Hey guys,
Has anyone had an experience with porting linux daemon code to macos? I'm getting "no path for address" error in system log when the second thread start running its function loop. The daemon does not crash and even terminates properly when I kill it, but the code in the thread does not go any further. Could you advise something?
OS = Sierra 10.12.6
gcc/g++ --version = Apple LLVM version 9.0.0 (clang-900.0.39.2)
Here's the code I'm trying to make alive
Has anyone had an experience with porting linux daemon code to macos? I'm getting "no path for address" error in system log when the second thread start running its function loop. The daemon does not crash and even terminates properly when I kill it, but the code in the thread does not go any further. Could you advise something?
OS = Sierra 10.12.6
gcc/g++ --version = Apple LLVM version 9.0.0 (clang-900.0.39.2)
Here's the code I'm trying to make alive
Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <pthread.h>
static bool g_active = false;
void* daemon_main(void* /* ptr */) {
unsigned int counter = 0;
while (g_active) {
/* !!! THE PROBLEM IS HERE !!!
*
* All function calls in this loop do not work,
* but it still can quit from it, when g_active == false.
* If I remove the loop from here, the thread will be terminated normally */
syslog(LOG_INFO, "Counter = %d", counter++);
sleep(2);
}
return nullptr;
}
void signal_handler(int signal) {
syslog(LOG_NOTICE, "SIGTERM signal has been received. Start quitting...");
// quit from the daemon main loop
g_active = false;
}
int main(int argc, char** argv) {
// our process_id and session_id
pid_t pid, sid;
// fork off the parent process
pid = fork();
if (pid < 0) {
printf("Could not fork the PID\n");
exit(EXIT_FAILURE);
}
// if we got a good pid, then we can exit the parent process
if (pid > 0) {
exit(EXIT_SUCCESS);
}
// change the file mode mask
umask(0);
// open any logs here
openlog("foo", LOG_NOWAIT | LOG_PID, LOG_USER);
syslog(LOG_NOTICE, "Logger started");
// create a new sid for the child process
sid = setsid();
if (sid < 0) {
syslog(LOG_ERR, "Could not generate session ID for child process");
closelog();
exit(EXIT_FAILURE);
}
// change the current working directory
if ((chdir("/")) < 0) {
syslog(LOG_ERR, "Could not change working directory to /");
closelog();
exit(EXIT_FAILURE);
}
// catch and handle signals
if (signal(SIGTERM, signal_handler) == SIG_ERR) {
syslog(LOG_ERR, "Could not register SIGTERM catcher");
closelog();
exit(EXIT_FAILURE);
}
// close out the standard file descriptors
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// daemon-specific initialization goes here
pthread_t secondThread;
g_active = true;
int ires = pthread_create(&secondThread, NULL, daemon_main, NULL);
if (ires != 0) {
syslog(LOG_ERR, "Could not create a second thread. Error <%d>", ires);
closelog();
exit(EXIT_FAILURE);
}
syslog(LOG_NOTICE, "Initialization completed");
pthread_join(secondThread, NULL);
// close system log for the child process
syslog(LOG_NOTICE, "Successfully stopped");
closelog();
// terminate the child process when the daemon completes
exit(EXIT_SUCCESS);
}
Last edited: