# HG changeset patch # User Michiel Broek # Date 1398361770 -7200 # Node ID 102c44bb8c9d07ff49a1e4dfe502e45c02de4343 # Parent f78f313b1d3483eb415c0bab07b51e50139b0f21 Deamon code added diff -r f78f313b1d34 -r 102c44bb8c9d lib/mbselib.h --- a/lib/mbselib.h Thu Apr 24 15:12:48 2014 +0200 +++ b/lib/mbselib.h Thu Apr 24 19:49:30 2014 +0200 @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include diff -r f78f313b1d34 -r 102c44bb8c9d thermometers/main.c --- a/thermometers/main.c Thu Apr 24 15:12:48 2014 +0200 +++ b/thermometers/main.c Thu Apr 24 19:49:30 2014 +0200 @@ -37,6 +37,7 @@ static bool connected = true; static bool disconnect_sent = false; static bool shutdown = false; +static pid_t pgrp, mypid; extern bool debug; extern sys_config Config; @@ -48,8 +49,9 @@ void help(void) { + fprintf(stdout, "mbsePi-apps thermometers v%s starting\n\n", VERSION); fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n"); - fprintf(stdout, " -d --debug Debug on\n"); + fprintf(stdout, " -d --debug Debug and run in foreground\n"); fprintf(stdout, " -h --help Display this help\n"); } @@ -118,7 +120,8 @@ int main(int argc, char *argv[]) { - int rc, c, i; + int rc, c, i; + pid_t frk; while (1) { int option_index = 0; @@ -142,6 +145,8 @@ openlog("thermometers", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); syslog(LOG_NOTICE, "mbsePi-apps thermometers v%s starting", VERSION); + if (debug) + fprintf(stdout, "mbsePi-apps thermometers v%s starting\n", VERSION); if (rdconfig()) { fprintf(stderr, "Error reading configuration\n"); @@ -159,7 +164,64 @@ signal(i, (void (*))die); } - rc = server(); + + if (debug) { + /* + * For debugging run in foreground. + */ + rc = server(); + } else { + /* + * Server initialization is complete. Now we can fork the + * daemon and return to the user. We need to do a setpgrp + * so that the daemon will no longer be assosiated with the + * users control terminal. This is done before the fork, so + * that the child will not be a process group leader. Otherwise, + * if the child were to open a terminal, it would become + * associated with that terminal as its control terminal. + */ + if ((pgrp = setpgid(0, 0)) == -1) { + syslog(LOG_NOTICE, "setpgpid failed"); + } + + frk = fork(); + switch (frk) { + case -1: + syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno)); + syslog(LOG_NOTICE, "Finished, rc=1"); + exit(1); + case 0: /* + * Run the daemon + */ + fclose(stdin); + if (open("/dev/null", O_RDONLY) != 0) { + syslog(LOG_NOTICE, "Reopen of stdin to /dev/null failed"); + _exit(2); + } + fclose(stdout); + if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { + syslog(LOG_NOTICE, "Reopen of stdout to /dev/null failed"); + _exit(2); + } + fclose(stderr); + if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { + syslog(LOG_NOTICE, "Reopen of stderr to /dev/null failed"); + _exit(2); + } + mypid = getpid(); + rc = server(); + break; + /* Not reached */ + default: + /* + * Here we detach this process and let the child + * run the deamon process. + */ + syslog(LOG_NOTICE, "Starting daemon with pid %d", frk); + exit(0); + } + } + syslog(LOG_NOTICE, "Finished, rc=%d", rc); return rc; } @@ -224,9 +286,7 @@ state = xstrcat(state, hostname); state = xstrcat(state, (char *)"/thermometers/state"); sprintf(buf, "0"); - - rc = mosquitto_will_set(mosq, state, strlen(buf), buf, qos, true); - if (rc) { + if ((rc = mosquitto_will_set(mosq, state, strlen(buf), buf, qos, true))) { if (rc == MOSQ_ERR_INVAL) { syslog(LOG_NOTICE, "mosquitto_will_set: input parameters invalid"); } else if (rc == MOSQ_ERR_NOMEM) { @@ -243,8 +303,7 @@ mosquitto_disconnect_callback_set(mosq, my_disconnect_callback); mosquitto_publish_callback_set(mosq, my_publish_callback); - rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive); - if (rc) { + if ((rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive))) { if (rc == MOSQ_ERR_ERRNO) { strerror_r(errno, err, 1024); syslog(LOG_NOTICE, "mosquitto_connect: error: %s", err); @@ -263,11 +322,13 @@ sprintf(buf, "1"); rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1); - fprintf(stdout, (char *)"Enter loop, connected %d\n", connected); + if (debug) + fprintf(stdout, (char *)"Enter loop, connected %d\n", connected); + do { if (status == STATUS_CONNACK_RECVD) { /* - * Here send our sensors values + * Here send our 1-wire sensors values */ for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { old1 = tmp1->next; @@ -341,7 +402,8 @@ tmp1->present = 1; } else { tmp1->present = 0; - printf("sensor %s is missing\n", tmp1->name); + if (debug) + printf("sensor %s is missing\n", tmp1->name); } free(device); @@ -361,7 +423,8 @@ status = STATUS_WAITING; } } else if (status == STATUS_WAITING) { - fprintf(stdout, (char *)"Waiting\n"); + if (debug) + fprintf(stdout, (char *)"Waiting\n"); if (last_mid_sent == last_mid && disconnect_sent == false) { mosquitto_disconnect(mosq); disconnect_sent = true; @@ -370,14 +433,15 @@ } rc = MOSQ_ERR_SUCCESS; - } while(rc == MOSQ_ERR_SUCCESS && connected); - fprintf(stdout, (char *)"Out of loop\n"); + } while (rc == MOSQ_ERR_SUCCESS && connected); + + if (debug) + fprintf(stdout, (char *)"Out of loop\n"); mosquitto_loop_stop(mosq, false); - mosquitto_destroy(mosq); mosquitto_lib_cleanup(); - return 0; + return rc; }