| Message ID | 20250305114509.78197-1-pierre.lebleu@pile-engineering.com |
|---|---|
| State | Rejected |
| Headers | show |
| Series | moongoose: Add support for writing PID file on startup | expand |
Hi Pierre, On 3/5/25 12:45, Pierre Lebleu wrote: > Signed-off-by: Pierre Lebleu <pierre.lebleu@pile-engineering.com> > --- > mongoose/mongoose_interface.c | 37 +++++++++++++++++++++++++++++++---- > 1 file changed, 33 insertions(+), 4 deletions(-) > Apart of the patch itself, this does not make a lot of sense for me. Why do we need the external pid ? SWUpdate is a multithread and multiprocess application, and it handles itself the owned processes. First question could be why the Webserver and the other processes (downloader, suricatta, etc..). So which is the use case ? And what is supposed to do ? It seems also to me a bad design to try to manage the processes outside SWUpdate. It won't know then and its behavior could become unpredictable. Best regards, Stefano Babic > diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c > index bc514598..11518eef 100644 > --- a/mongoose/mongoose_interface.c > +++ b/mongoose/mongoose_interface.c > @@ -39,10 +39,12 @@ > #define MG_TLS 0 > #endif > > +#define MG_PIDFILE "/run/swupdate-mongoose.pid" > #define MG_PORT "8080" > #define MG_ROOT "." > > struct mongoose_options { > + char *pidfile; > char *root; > bool listing; > char *port; > @@ -776,6 +778,11 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat > if (strlen(tmp)) { > opts->port = strdup(tmp); > } > + > + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "pidfile", tmp); > + if (strlen(tmp)) { > + opts->pidfile = strdup(tmp); > + } > #if MG_TLS > GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "ssl_certificate", tmp); > if (strlen(tmp)) { > @@ -807,6 +814,7 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat > static struct option long_options[] = { > {"listing", no_argument, NULL, 'l'}, > {"port", required_argument, NULL, 'p'}, > + {"pidfile", required_argument, NULL, 'P'}, > #if MG_TLS > {"ssl", no_argument, NULL, 's'}, > {"ssl-cert", required_argument, NULL, 'C'}, > @@ -825,7 +833,8 @@ void mongoose_print_help(void) > stdout, > "\tmongoose arguments:\n" > "\t -l, --listing : enable directory listing\n" > - "\t -p, --port <port> : server port number (default: %s)\n" > + "\t -p, --port <port> : server port number (default: %s)\n" > + "\t -P, --pidfile <file> : specify a pid file (default: %s)\n" > #if MG_TLS > "\t -s, --ssl : enable ssl support\n" > "\t -C, --ssl-cert <cert> : ssl certificate to present to clients\n" > @@ -835,7 +844,7 @@ void mongoose_print_help(void) > "\t -t, --timeout : timeout to check if connection is lost (default: check disabled)\n" > "\t --auth-domain : set authentication domain if any (default: none)\n" > "\t --global-auth-file : set authentication file if any (default: none)\n", > - MG_PORT, MG_ROOT); > + MG_PORT, MG_PIDFILE, MG_ROOT); > } > > int start_mongoose(const char *cfgfname, int argc, char *argv[]) > @@ -845,6 +854,7 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) > struct mg_connection *nc; > char *url = NULL; > int choice; > + pid_t pid; > > #if MG_TLS > ssl = false; > @@ -875,7 +885,7 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) > } > > optind = 1; > - while ((choice = getopt_long(argc, argv, "lp:sC:K:r:a:t:", > + while ((choice = getopt_long(argc, argv, "lp:P:sC:K:r:a:t:", > long_options, NULL)) != -1) { > switch (choice) { > case '0': > @@ -893,6 +903,10 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) > free(opts.port); > opts.port = strdup(optarg); > break; > + case 'P': > + free(opts.pidfile); > + opts.pidfile = strdup(optarg); > + break; > case 't': > watchdog_conn = strtoul(optarg, NULL, 10); > break; > @@ -963,8 +977,23 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) > > mg_wakeup_init(&mgr); > > + pid = getpid(); > INFO("Mongoose web server v%s with PID %d listening on %s and serving %s", > - MG_VERSION, getpid(), url, s_http_server_opts.root_dir); > + MG_VERSION, pid, url, s_http_server_opts.root_dir); > + > + if (opts.pidfile) { > + FILE *fd = fopen(opts.pidfile, "w"); > + > + if (fd) { > + INFO("Writing PID into %s\n", opts.pidfile); > + fprintf(fd, "%d\n", pid); > + fclose(fd); > + } else { > + WARN("Error opening file %s: %s (errno: %d)", opts.pidfile, strerror(errno), errno); > + } > + > + free(opts.pidfile); > + } > > while (s_signo == 0) > mg_mgr_poll(&mgr, 100);
Hi Stefano, Thanks for the quick response. I need the PID file to use with the watchdog on my embedded system. The watchdog verifies whether swupdate is running by checking the PID. For your reference, the configuration file sets the "pidfile" option, which is detailed here: https://sourceforge.net/p/watchdog/code/ci/master/tree/watchdog.conf Just to clarify, the goal is not to manage swupdate but merely to confirm that the daemon is running properly. Best regards, Pierre On Wed, Mar 5, 2025 at 12:56 PM Stefano Babic <stefano.babic@swupdate.org> wrote: > Hi Pierre, > > On 3/5/25 12:45, Pierre Lebleu wrote: > > Signed-off-by: Pierre Lebleu <pierre.lebleu@pile-engineering.com> > > --- > > mongoose/mongoose_interface.c | 37 +++++++++++++++++++++++++++++++---- > > 1 file changed, 33 insertions(+), 4 deletions(-) > > > > Apart of the patch itself, this does not make a lot of sense for me. Why > do we need the external pid ? > > SWUpdate is a multithread and multiprocess application, and it handles > itself the owned processes. First question could be why the Webserver > and the other processes (downloader, suricatta, etc..). > > So which is the use case ? And what is supposed to do ? > > It seems also to me a bad design to try to manage the processes outside > SWUpdate. It won't know then and its behavior could become unpredictable. > > Best regards, > Stefano Babic > > > diff --git a/mongoose/mongoose_interface.c > b/mongoose/mongoose_interface.c > > index bc514598..11518eef 100644 > > --- a/mongoose/mongoose_interface.c > > +++ b/mongoose/mongoose_interface.c > > @@ -39,10 +39,12 @@ > > #define MG_TLS 0 > > #endif > > > > +#define MG_PIDFILE "/run/swupdate-mongoose.pid" > > #define MG_PORT "8080" > > #define MG_ROOT "." > > > > struct mongoose_options { > > + char *pidfile; > > char *root; > > bool listing; > > char *port; > > @@ -776,6 +778,11 @@ static int mongoose_settings(void *elem, void > __attribute__ ((__unused__)) *dat > > if (strlen(tmp)) { > > opts->port = strdup(tmp); > > } > > + > > + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "pidfile", tmp); > > + if (strlen(tmp)) { > > + opts->pidfile = strdup(tmp); > > + } > > #if MG_TLS > > GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "ssl_certificate", > tmp); > > if (strlen(tmp)) { > > @@ -807,6 +814,7 @@ static int mongoose_settings(void *elem, void > __attribute__ ((__unused__)) *dat > > static struct option long_options[] = { > > {"listing", no_argument, NULL, 'l'}, > > {"port", required_argument, NULL, 'p'}, > > + {"pidfile", required_argument, NULL, 'P'}, > > #if MG_TLS > > {"ssl", no_argument, NULL, 's'}, > > {"ssl-cert", required_argument, NULL, 'C'}, > > @@ -825,7 +833,8 @@ void mongoose_print_help(void) > > stdout, > > "\tmongoose arguments:\n" > > "\t -l, --listing : enable directory > listing\n" > > - "\t -p, --port <port> : server port number > (default: %s)\n" > > + "\t -p, --port <port> : server port number > (default: %s)\n" > > + "\t -P, --pidfile <file> : specify a pid file > (default: %s)\n" > > #if MG_TLS > > "\t -s, --ssl : enable ssl support\n" > > "\t -C, --ssl-cert <cert> : ssl certificate to > present to clients\n" > > @@ -835,7 +844,7 @@ void mongoose_print_help(void) > > "\t -t, --timeout : timeout to check if > connection is lost (default: check disabled)\n" > > "\t --auth-domain : set authentication > domain if any (default: none)\n" > > "\t --global-auth-file : set authentication > file if any (default: none)\n", > > - MG_PORT, MG_ROOT); > > + MG_PORT, MG_PIDFILE, MG_ROOT); > > } > > > > int start_mongoose(const char *cfgfname, int argc, char *argv[]) > > @@ -845,6 +854,7 @@ int start_mongoose(const char *cfgfname, int argc, > char *argv[]) > > struct mg_connection *nc; > > char *url = NULL; > > int choice; > > + pid_t pid; > > > > #if MG_TLS > > ssl = false; > > @@ -875,7 +885,7 @@ int start_mongoose(const char *cfgfname, int argc, > char *argv[]) > > } > > > > optind = 1; > > - while ((choice = getopt_long(argc, argv, "lp:sC:K:r:a:t:", > > + while ((choice = getopt_long(argc, argv, "lp:P:sC:K:r:a:t:", > > long_options, NULL)) != -1) { > > switch (choice) { > > case '0': > > @@ -893,6 +903,10 @@ int start_mongoose(const char *cfgfname, int argc, > char *argv[]) > > free(opts.port); > > opts.port = strdup(optarg); > > break; > > + case 'P': > > + free(opts.pidfile); > > + opts.pidfile = strdup(optarg); > > + break; > > case 't': > > watchdog_conn = strtoul(optarg, NULL, 10); > > break; > > @@ -963,8 +977,23 @@ int start_mongoose(const char *cfgfname, int argc, > char *argv[]) > > > > mg_wakeup_init(&mgr); > > > > + pid = getpid(); > > INFO("Mongoose web server v%s with PID %d listening on %s and > serving %s", > > - MG_VERSION, getpid(), url, s_http_server_opts.root_dir); > > + MG_VERSION, pid, url, s_http_server_opts.root_dir); > > + > > + if (opts.pidfile) { > > + FILE *fd = fopen(opts.pidfile, "w"); > > + > > + if (fd) { > > + INFO("Writing PID into %s\n", opts.pidfile); > > + fprintf(fd, "%d\n", pid); > > + fclose(fd); > > + } else { > > + WARN("Error opening file %s: %s (errno: %d)", > opts.pidfile, strerror(errno), errno); > > + } > > + > > + free(opts.pidfile); > > + } > > > > while (s_signo == 0) > > mg_mgr_poll(&mgr, 100); > >
Hi Pierre, On 3/5/25 13:11, Pierre Lebleu wrote: > Hi Stefano, > > Thanks for the quick response. > > I need the PID file to use with the watchdog on my embedded system. The > watchdog verifies whether swupdate is running by checking the PID. No. This is done by systemd. SWUpdate sends a notification to systemd when it is up and running, and systemd monitors it. SWUpdate itself implements signal handling to check if internal processes are living, and if not, it exits. In the SWUpdate's run unit you can decide the action that must be taken. If you want to do via watchdog daemon or monit, you are starting SWUpdate itself and you get the pid when you run exec. This is the only pid you need, not the internal ones. > For your reference, the configuration file sets the "pidfile" option, > which is detailed here: https://sourceforge.net/p/watchdog/code/ci/ > master/tree/watchdog.conf <https://sourceforge.net/p/watchdog/code/ci/ > master/tree/watchdog.conf> > > Just to clarify, the goal is not to manage swupdate but merely to > confirm that the daemon is running properly. See above. Best regards, Stefano Babic > > Best regards, > > Pierre > > On Wed, Mar 5, 2025 at 12:56 PM Stefano Babic > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org>> wrote: > > Hi Pierre, > > On 3/5/25 12:45, Pierre Lebleu wrote: > > Signed-off-by: Pierre Lebleu <pierre.lebleu@pile-engineering.com > <mailto:pierre.lebleu@pile-engineering.com>> > > --- > > mongoose/mongoose_interface.c | 37 ++++++++++++++++++++++++++++ > +++---- > > 1 file changed, 33 insertions(+), 4 deletions(-) > > > > Apart of the patch itself, this does not make a lot of sense for me. Why > do we need the external pid ? > > SWUpdate is a multithread and multiprocess application, and it handles > itself the owned processes. First question could be why the Webserver > and the other processes (downloader, suricatta, etc..). > > So which is the use case ? And what is supposed to do ? > > It seems also to me a bad design to try to manage the processes outside > SWUpdate. It won't know then and its behavior could become > unpredictable. > > Best regards, > Stefano Babic > > > diff --git a/mongoose/mongoose_interface.c b/mongoose/ > mongoose_interface.c > > index bc514598..11518eef 100644 > > --- a/mongoose/mongoose_interface.c > > +++ b/mongoose/mongoose_interface.c > > @@ -39,10 +39,12 @@ > > #define MG_TLS 0 > > #endif > > > > +#define MG_PIDFILE "/run/swupdate-mongoose.pid" > > #define MG_PORT "8080" > > #define MG_ROOT "." > > > > struct mongoose_options { > > + char *pidfile; > > char *root; > > bool listing; > > char *port; > > @@ -776,6 +778,11 @@ static int mongoose_settings(void *elem, > void __attribute__ ((__unused__)) *dat > > if (strlen(tmp)) { > > opts->port = strdup(tmp); > > } > > + > > + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "pidfile", tmp); > > + if (strlen(tmp)) { > > + opts->pidfile = strdup(tmp); > > + } > > #if MG_TLS > > GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, > "ssl_certificate", tmp); > > if (strlen(tmp)) { > > @@ -807,6 +814,7 @@ static int mongoose_settings(void *elem, > void __attribute__ ((__unused__)) *dat > > static struct option long_options[] = { > > {"listing", no_argument, NULL, 'l'}, > > {"port", required_argument, NULL, 'p'}, > > + {"pidfile", required_argument, NULL, 'P'}, > > #if MG_TLS > > {"ssl", no_argument, NULL, 's'}, > > {"ssl-cert", required_argument, NULL, 'C'}, > > @@ -825,7 +833,8 @@ void mongoose_print_help(void) > > stdout, > > "\tmongoose arguments:\n" > > "\t -l, --listing : enable > directory listing\n" > > - "\t -p, --port <port> : server port > number (default: %s)\n" > > + "\t -p, --port <port> : server port > number (default: %s)\n" > > + "\t -P, --pidfile <file> : specify a pid > file (default: %s)\n" > > #if MG_TLS > > "\t -s, --ssl : enable ssl > support\n" > > "\t -C, --ssl-cert <cert> : ssl > certificate to present to clients\n" > > @@ -835,7 +844,7 @@ void mongoose_print_help(void) > > "\t -t, --timeout : timeout to > check if connection is lost (default: check disabled)\n" > > "\t --auth-domain : set > authentication domain if any (default: none)\n" > > "\t --global-auth-file : set > authentication file if any (default: none)\n", > > - MG_PORT, MG_ROOT); > > + MG_PORT, MG_PIDFILE, MG_ROOT); > > } > > > > int start_mongoose(const char *cfgfname, int argc, char *argv[]) > > @@ -845,6 +854,7 @@ int start_mongoose(const char *cfgfname, int > argc, char *argv[]) > > struct mg_connection *nc; > > char *url = NULL; > > int choice; > > + pid_t pid; > > > > #if MG_TLS > > ssl = false; > > @@ -875,7 +885,7 @@ int start_mongoose(const char *cfgfname, int > argc, char *argv[]) > > } > > > > optind = 1; > > - while ((choice = getopt_long(argc, argv, "lp:sC:K:r:a:t:", > > + while ((choice = getopt_long(argc, argv, "lp:P:sC:K:r:a:t:", > > long_options, NULL)) != -1) { > > switch (choice) { > > case '0': > > @@ -893,6 +903,10 @@ int start_mongoose(const char *cfgfname, int > argc, char *argv[]) > > free(opts.port); > > opts.port = strdup(optarg); > > break; > > + case 'P': > > + free(opts.pidfile); > > + opts.pidfile = strdup(optarg); > > + break; > > case 't': > > watchdog_conn = strtoul(optarg, NULL, 10); > > break; > > @@ -963,8 +977,23 @@ int start_mongoose(const char *cfgfname, int > argc, char *argv[]) > > > > mg_wakeup_init(&mgr); > > > > + pid = getpid(); > > INFO("Mongoose web server v%s with PID %d listening on %s > and serving %s", > > - MG_VERSION, getpid(), url, > s_http_server_opts.root_dir); > > + MG_VERSION, pid, url, s_http_server_opts.root_dir); > > + > > + if (opts.pidfile) { > > + FILE *fd = fopen(opts.pidfile, "w"); > > + > > + if (fd) { > > + INFO("Writing PID into %s\n", opts.pidfile); > > + fprintf(fd, "%d\n", pid); > > + fclose(fd); > > + } else { > > + WARN("Error opening file %s: %s (errno: > %d)", opts.pidfile, strerror(errno), errno); > > + } > > + > > + free(opts.pidfile); > > + } > > > > while (s_signo == 0) > > mg_mgr_poll(&mgr, 100); > > -- > You received this message because you are subscribed to the Google > Groups "swupdate" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to swupdate+unsubscribe@googlegroups.com > <mailto:swupdate+unsubscribe@googlegroups.com>. > To view this discussion visit https://groups.google.com/d/msgid/ > swupdate/ > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw%40mail.gmail.com > <https://groups.google.com/d/msgid/swupdate/ > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw%40mail.gmail.com? > utm_medium=email&utm_source=footer>.
Hi Stefano, Thanks for the explanation, it's crystal clear ! So, would you advise me to modify swupdate.sh from meta-swupde to something like: --- a/recipes-support/swupdate/swupdate/swupdate.sh +++ b/recipes-support/swupdate/swupdate/swupdate.sh @@ -16,6 +16,9 @@ for f in `(test -d @LIBDIR@/swupdate/conf.d/ && ls -1 @LIBDIR@/swupdate/conf.d/; fi done +# Write the PID file +echo $$ > /run/swupdate.pid + # handle variable escaping in a simmple way. Use exec to forward open filedescriptors from systemd open. if [ "$SWUPDATE_WEBSERVER_ARGS" != "" -a "$SWUPDATE_SURICATTA_ARGS" != "" ]; then exec /usr/bin/swupdate $SWUPDATE_ARGS -w "$SWUPDATE_WEBSERVER_ARGS" -u "$SWUPDATE_SURICATTA_ARGS" Best regards, On Wed, Mar 5, 2025 at 1:17 PM Stefano Babic <stefano.babic@swupdate.org> wrote: > Hi Pierre, > > On 3/5/25 13:11, Pierre Lebleu wrote: > > Hi Stefano, > > > > Thanks for the quick response. > > > > I need the PID file to use with the watchdog on my embedded system. The > > watchdog verifies whether swupdate is running by checking the PID. > > No. > > This is done by systemd. SWUpdate sends a notification to systemd when > it is up and running, and systemd monitors it. SWUpdate itself > implements signal handling to check if internal processes are living, > and if not, it exits. In the SWUpdate's run unit you can decide the > action that must be taken. > > If you want to do via watchdog daemon or monit, you are starting > SWUpdate itself and you get the pid when you run exec. This is the only > pid you need, not the internal ones. > > > For your reference, the configuration file sets the "pidfile" option, > > which is detailed here: https://sourceforge.net/p/watchdog/code/ci/ > > master/tree/watchdog.conf <https://sourceforge.net/p/watchdog/code/ci/ > > master/tree/watchdog.conf> > > > > Just to clarify, the goal is not to manage swupdate but merely to > > confirm that the daemon is running properly. > > See above. > > Best regards, > Stefano Babic > > > > > Best regards, > > > > Pierre > > > > On Wed, Mar 5, 2025 at 12:56 PM Stefano Babic > > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org>> wrote: > > > > Hi Pierre, > > > > On 3/5/25 12:45, Pierre Lebleu wrote: > > > Signed-off-by: Pierre Lebleu <pierre.lebleu@pile-engineering.com > > <mailto:pierre.lebleu@pile-engineering.com>> > > > --- > > > mongoose/mongoose_interface.c | 37 ++++++++++++++++++++++++++++ > > +++---- > > > 1 file changed, 33 insertions(+), 4 deletions(-) > > > > > > > Apart of the patch itself, this does not make a lot of sense for me. > Why > > do we need the external pid ? > > > > SWUpdate is a multithread and multiprocess application, and it > handles > > itself the owned processes. First question could be why the Webserver > > and the other processes (downloader, suricatta, etc..). > > > > So which is the use case ? And what is supposed to do ? > > > > It seems also to me a bad design to try to manage the processes > outside > > SWUpdate. It won't know then and its behavior could become > > unpredictable. > > > > Best regards, > > Stefano Babic > > > > > diff --git a/mongoose/mongoose_interface.c b/mongoose/ > > mongoose_interface.c > > > index bc514598..11518eef 100644 > > > --- a/mongoose/mongoose_interface.c > > > +++ b/mongoose/mongoose_interface.c > > > @@ -39,10 +39,12 @@ > > > #define MG_TLS 0 > > > #endif > > > > > > +#define MG_PIDFILE "/run/swupdate-mongoose.pid" > > > #define MG_PORT "8080" > > > #define MG_ROOT "." > > > > > > struct mongoose_options { > > > + char *pidfile; > > > char *root; > > > bool listing; > > > char *port; > > > @@ -776,6 +778,11 @@ static int mongoose_settings(void *elem, > > void __attribute__ ((__unused__)) *dat > > > if (strlen(tmp)) { > > > opts->port = strdup(tmp); > > > } > > > + > > > + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "pidfile", tmp); > > > + if (strlen(tmp)) { > > > + opts->pidfile = strdup(tmp); > > > + } > > > #if MG_TLS > > > GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, > > "ssl_certificate", tmp); > > > if (strlen(tmp)) { > > > @@ -807,6 +814,7 @@ static int mongoose_settings(void *elem, > > void __attribute__ ((__unused__)) *dat > > > static struct option long_options[] = { > > > {"listing", no_argument, NULL, 'l'}, > > > {"port", required_argument, NULL, 'p'}, > > > + {"pidfile", required_argument, NULL, 'P'}, > > > #if MG_TLS > > > {"ssl", no_argument, NULL, 's'}, > > > {"ssl-cert", required_argument, NULL, 'C'}, > > > @@ -825,7 +833,8 @@ void mongoose_print_help(void) > > > stdout, > > > "\tmongoose arguments:\n" > > > "\t -l, --listing : enable > > directory listing\n" > > > - "\t -p, --port <port> : server port > > number (default: %s)\n" > > > + "\t -p, --port <port> : server port > > number (default: %s)\n" > > > + "\t -P, --pidfile <file> : specify a pid > > file (default: %s)\n" > > > #if MG_TLS > > > "\t -s, --ssl : enable ssl > > support\n" > > > "\t -C, --ssl-cert <cert> : ssl > > certificate to present to clients\n" > > > @@ -835,7 +844,7 @@ void mongoose_print_help(void) > > > "\t -t, --timeout : timeout to > > check if connection is lost (default: check disabled)\n" > > > "\t --auth-domain : set > > authentication domain if any (default: none)\n" > > > "\t --global-auth-file : set > > authentication file if any (default: none)\n", > > > - MG_PORT, MG_ROOT); > > > + MG_PORT, MG_PIDFILE, MG_ROOT); > > > } > > > > > > int start_mongoose(const char *cfgfname, int argc, char *argv[]) > > > @@ -845,6 +854,7 @@ int start_mongoose(const char *cfgfname, int > > argc, char *argv[]) > > > struct mg_connection *nc; > > > char *url = NULL; > > > int choice; > > > + pid_t pid; > > > > > > #if MG_TLS > > > ssl = false; > > > @@ -875,7 +885,7 @@ int start_mongoose(const char *cfgfname, int > > argc, char *argv[]) > > > } > > > > > > optind = 1; > > > - while ((choice = getopt_long(argc, argv, "lp:sC:K:r:a:t:", > > > + while ((choice = getopt_long(argc, argv, "lp:P:sC:K:r:a:t:", > > > long_options, NULL)) != -1) { > > > switch (choice) { > > > case '0': > > > @@ -893,6 +903,10 @@ int start_mongoose(const char *cfgfname, int > > argc, char *argv[]) > > > free(opts.port); > > > opts.port = strdup(optarg); > > > break; > > > + case 'P': > > > + free(opts.pidfile); > > > + opts.pidfile = strdup(optarg); > > > + break; > > > case 't': > > > watchdog_conn = strtoul(optarg, NULL, 10); > > > break; > > > @@ -963,8 +977,23 @@ int start_mongoose(const char *cfgfname, int > > argc, char *argv[]) > > > > > > mg_wakeup_init(&mgr); > > > > > > + pid = getpid(); > > > INFO("Mongoose web server v%s with PID %d listening on %s > > and serving %s", > > > - MG_VERSION, getpid(), url, > > s_http_server_opts.root_dir); > > > + MG_VERSION, pid, url, s_http_server_opts.root_dir); > > > + > > > + if (opts.pidfile) { > > > + FILE *fd = fopen(opts.pidfile, "w"); > > > + > > > + if (fd) { > > > + INFO("Writing PID into %s\n", opts.pidfile); > > > + fprintf(fd, "%d\n", pid); > > > + fclose(fd); > > > + } else { > > > + WARN("Error opening file %s: %s (errno: > > %d)", opts.pidfile, strerror(errno), errno); > > > + } > > > + > > > + free(opts.pidfile); > > > + } > > > > > > while (s_signo == 0) > > > mg_mgr_poll(&mgr, 100); > > > > -- > > You received this message because you are subscribed to the Google > > Groups "swupdate" group. > > To unsubscribe from this group and stop receiving emails from it, send > > an email to swupdate+unsubscribe@googlegroups.com > > <mailto:swupdate+unsubscribe@googlegroups.com>. > > To view this discussion visit https://groups.google.com/d/msgid/ > > swupdate/ > > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw%40mail.gmail.com > > <https://groups.google.com/d/msgid/swupdate/ > > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw%40mail.gmail.com? > > utm_medium=email&utm_source=footer>. > >
On 3/5/25 13:30, Pierre Lebleu wrote: > Hi Stefano, > > Thanks for the explanation, it's crystal clear ! > > So, would you advise me to modify swupdate.sh from meta-swupde to > something like: > > --- a/recipes-support/swupdate/swupdate/swupdate.sh > +++ b/recipes-support/swupdate/swupdate/swupdate.sh > @@ -16,6 +16,9 @@ for f in `(test -d @LIBDIR@/swupdate/conf.d/ && ls -1 > @LIBDIR@/swupdate/conf.d/; > fi > done > > +# Write the PID file > +echo $$ > /run/swupdate.pid That is the pid. > + > # handle variable escaping in a simmple way. Use exec to forward open > filedescriptors from systemd open. > if [ "$SWUPDATE_WEBSERVER_ARGS" != "" -a "$SWUPDATE_SURICATTA_ARGS" ! > = "" ]; then > exec /usr/bin/swupdate $SWUPDATE_ARGS -w "$SWUPDATE_WEBSERVER_ARGS" > -u "$SWUPDATE_SURICATTA_ARGS" > > Best regards, > > On Wed, Mar 5, 2025 at 1:17 PM Stefano Babic <stefano.babic@swupdate.org > <mailto:stefano.babic@swupdate.org>> wrote: > > Hi Pierre, > > On 3/5/25 13:11, Pierre Lebleu wrote: > > Hi Stefano, > > > > Thanks for the quick response. > > > > I need the PID file to use with the watchdog on my embedded > system. The > > watchdog verifies whether swupdate is running by checking the PID. > > No. > > This is done by systemd. SWUpdate sends a notification to systemd when > it is up and running, and systemd monitors it. SWUpdate itself > implements signal handling to check if internal processes are living, > and if not, it exits. In the SWUpdate's run unit you can decide the > action that must be taken. > > If you want to do via watchdog daemon or monit, you are starting > SWUpdate itself and you get the pid when you run exec. This is the only > pid you need, not the internal ones. > > > For your reference, the configuration file sets the "pidfile" option, > > which is detailed here: https://sourceforge.net/p/watchdog/code/ > ci/ <https://sourceforge.net/p/watchdog/code/ci/> > > master/tree/watchdog.conf <https://sourceforge.net/p/watchdog/ > code/ci/ <https://sourceforge.net/p/watchdog/code/ci/> > > master/tree/watchdog.conf> > > > > Just to clarify, the goal is not to manage swupdate but merely to > > confirm that the daemon is running properly. > > See above. > > Best regards, > Stefano Babic > > > > > Best regards, > > > > Pierre > > > > On Wed, Mar 5, 2025 at 12:56 PM Stefano Babic > > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org> > <mailto:stefano.babic@swupdate.org > <mailto:stefano.babic@swupdate.org>>> wrote: > > > > Hi Pierre, > > > > On 3/5/25 12:45, Pierre Lebleu wrote: > > > Signed-off-by: Pierre Lebleu <pierre.lebleu@pile- > engineering.com <mailto:pierre.lebleu@pile-engineering.com> > > <mailto:pierre.lebleu@pile-engineering.com > <mailto:pierre.lebleu@pile-engineering.com>>> > > > --- > > > mongoose/mongoose_interface.c | 37 +++++++++++++++++++++ > +++++++ > > +++---- > > > 1 file changed, 33 insertions(+), 4 deletions(-) > > > > > > > Apart of the patch itself, this does not make a lot of sense > for me. Why > > do we need the external pid ? > > > > SWUpdate is a multithread and multiprocess application, and > it handles > > itself the owned processes. First question could be why the > Webserver > > and the other processes (downloader, suricatta, etc..). > > > > So which is the use case ? And what is supposed to do ? > > > > It seems also to me a bad design to try to manage the > processes outside > > SWUpdate. It won't know then and its behavior could become > > unpredictable. > > > > Best regards, > > Stefano Babic > > > > > diff --git a/mongoose/mongoose_interface.c b/mongoose/ > > mongoose_interface.c > > > index bc514598..11518eef 100644 > > > --- a/mongoose/mongoose_interface.c > > > +++ b/mongoose/mongoose_interface.c > > > @@ -39,10 +39,12 @@ > > > #define MG_TLS 0 > > > #endif > > > > > > +#define MG_PIDFILE "/run/swupdate-mongoose.pid" > > > #define MG_PORT "8080" > > > #define MG_ROOT "." > > > > > > struct mongoose_options { > > > + char *pidfile; > > > char *root; > > > bool listing; > > > char *port; > > > @@ -776,6 +778,11 @@ static int mongoose_settings(void *elem, > > void __attribute__ ((__unused__)) *dat > > > if (strlen(tmp)) { > > > opts->port = strdup(tmp); > > > } > > > + > > > + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, > "pidfile", tmp); > > > + if (strlen(tmp)) { > > > + opts->pidfile = strdup(tmp); > > > + } > > > #if MG_TLS > > > GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, > > "ssl_certificate", tmp); > > > if (strlen(tmp)) { > > > @@ -807,6 +814,7 @@ static int mongoose_settings(void *elem, > > void __attribute__ ((__unused__)) *dat > > > static struct option long_options[] = { > > > {"listing", no_argument, NULL, 'l'}, > > > {"port", required_argument, NULL, 'p'}, > > > + {"pidfile", required_argument, NULL, 'P'}, > > > #if MG_TLS > > > {"ssl", no_argument, NULL, 's'}, > > > {"ssl-cert", required_argument, NULL, 'C'}, > > > @@ -825,7 +833,8 @@ void mongoose_print_help(void) > > > stdout, > > > "\tmongoose arguments:\n" > > > "\t -l, --listing : enable > > directory listing\n" > > > - "\t -p, --port <port> : server > port > > number (default: %s)\n" > > > + "\t -p, --port <port> : server > port > > number (default: %s)\n" > > > + "\t -P, --pidfile <file> : > specify a pid > > file (default: %s)\n" > > > #if MG_TLS > > > "\t -s, --ssl : enable ssl > > support\n" > > > "\t -C, --ssl-cert <cert> : ssl > > certificate to present to clients\n" > > > @@ -835,7 +844,7 @@ void mongoose_print_help(void) > > > "\t -t, --timeout : timeout to > > check if connection is lost (default: check disabled)\n" > > > "\t --auth-domain : set > > authentication domain if any (default: none)\n" > > > "\t --global-auth-file : set > > authentication file if any (default: none)\n", > > > - MG_PORT, MG_ROOT); > > > + MG_PORT, MG_PIDFILE, MG_ROOT); > > > } > > > > > > int start_mongoose(const char *cfgfname, int argc, char > *argv[]) > > > @@ -845,6 +854,7 @@ int start_mongoose(const char > *cfgfname, int > > argc, char *argv[]) > > > struct mg_connection *nc; > > > char *url = NULL; > > > int choice; > > > + pid_t pid; > > > > > > #if MG_TLS > > > ssl = false; > > > @@ -875,7 +885,7 @@ int start_mongoose(const char > *cfgfname, int > > argc, char *argv[]) > > > } > > > > > > optind = 1; > > > - while ((choice = getopt_long(argc, argv, > "lp:sC:K:r:a:t:", > > > + while ((choice = getopt_long(argc, argv, > "lp:P:sC:K:r:a:t:", > > > long_options, NULL)) != > -1) { > > > switch (choice) { > > > case '0': > > > @@ -893,6 +903,10 @@ int start_mongoose(const char > *cfgfname, int > > argc, char *argv[]) > > > free(opts.port); > > > opts.port = strdup(optarg); > > > break; > > > + case 'P': > > > + free(opts.pidfile); > > > + opts.pidfile = strdup(optarg); > > > + break; > > > case 't': > > > watchdog_conn = strtoul(optarg, > NULL, 10); > > > break; > > > @@ -963,8 +977,23 @@ int start_mongoose(const char > *cfgfname, int > > argc, char *argv[]) > > > > > > mg_wakeup_init(&mgr); > > > > > > + pid = getpid(); > > > INFO("Mongoose web server v%s with PID %d listening > on %s > > and serving %s", > > > - MG_VERSION, getpid(), url, > > s_http_server_opts.root_dir); > > > + MG_VERSION, pid, url, > s_http_server_opts.root_dir); > > > + > > > + if (opts.pidfile) { > > > + FILE *fd = fopen(opts.pidfile, "w"); > > > + > > > + if (fd) { > > > + INFO("Writing PID into %s\n", > opts.pidfile); > > > + fprintf(fd, "%d\n", pid); > > > + fclose(fd); > > > + } else { > > > + WARN("Error opening file %s: %s (errno: > > %d)", opts.pidfile, strerror(errno), errno); > > > + } > > > + > > > + free(opts.pidfile); > > > + } > > > > > > while (s_signo == 0) > > > mg_mgr_poll(&mgr, 100); > > > > -- > > You received this message because you are subscribed to the Google > > Groups "swupdate" group. > > To unsubscribe from this group and stop receiving emails from it, > send > > an email to swupdate+unsubscribe@googlegroups.com > <mailto:swupdate%2Bunsubscribe@googlegroups.com> > > <mailto:swupdate+unsubscribe@googlegroups.com > <mailto:swupdate%2Bunsubscribe@googlegroups.com>>. > > To view this discussion visit https://groups.google.com/d/msgid/ > <https://groups.google.com/d/msgid/> > > swupdate/ > > > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw%40mail.gmail.com <http://40mail.gmail.com> > > <https://groups.google.com/d/msgid/swupdate/ <https:// > groups.google.com/d/msgid/swupdate/> > > > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw%40mail.gmail.com <http://40mail.gmail.com>? > > utm_medium=email&utm_source=footer>. >
Hi Stefano, Thanks for your explanation! Based on our discussion, the patch can therefore be dropped. Best regards, Pierre On Wed, Mar 5, 2025 at 1:32 PM Stefano Babic <stefano.babic@swupdate.org> wrote: > On 3/5/25 13:30, Pierre Lebleu wrote: > > Hi Stefano, > > > > Thanks for the explanation, it's crystal clear ! > > > > So, would you advise me to modify swupdate.sh from meta-swupde to > > something like: > > > > --- a/recipes-support/swupdate/swupdate/swupdate.sh > > +++ b/recipes-support/swupdate/swupdate/swupdate.sh > > @@ -16,6 +16,9 @@ for f in `(test -d @LIBDIR@/swupdate/conf.d/ && ls -1 > > @LIBDIR@/swupdate/conf.d/; > > fi > > done > > > > +# Write the PID file > > +echo $$ > /run/swupdate.pid > > That is the pid. > > > + > > # handle variable escaping in a simmple way. Use exec to forward open > > filedescriptors from systemd open. > > if [ "$SWUPDATE_WEBSERVER_ARGS" != "" -a "$SWUPDATE_SURICATTA_ARGS" ! > > = "" ]; then > > exec /usr/bin/swupdate $SWUPDATE_ARGS -w "$SWUPDATE_WEBSERVER_ARGS" > > -u "$SWUPDATE_SURICATTA_ARGS" > > > > Best regards, > > > > On Wed, Mar 5, 2025 at 1:17 PM Stefano Babic <stefano.babic@swupdate.org > > <mailto:stefano.babic@swupdate.org>> wrote: > > > > Hi Pierre, > > > > On 3/5/25 13:11, Pierre Lebleu wrote: > > > Hi Stefano, > > > > > > Thanks for the quick response. > > > > > > I need the PID file to use with the watchdog on my embedded > > system. The > > > watchdog verifies whether swupdate is running by checking the PID. > > > > No. > > > > This is done by systemd. SWUpdate sends a notification to systemd > when > > it is up and running, and systemd monitors it. SWUpdate itself > > implements signal handling to check if internal processes are living, > > and if not, it exits. In the SWUpdate's run unit you can decide the > > action that must be taken. > > > > If you want to do via watchdog daemon or monit, you are starting > > SWUpdate itself and you get the pid when you run exec. This is the > only > > pid you need, not the internal ones. > > > > > For your reference, the configuration file sets the "pidfile" > option, > > > which is detailed here: https://sourceforge.net/p/watchdog/code/ > > ci/ <https://sourceforge.net/p/watchdog/code/ci/> > > > master/tree/watchdog.conf <https://sourceforge.net/p/watchdog/ > > code/ci/ <https://sourceforge.net/p/watchdog/code/ci/> > > > master/tree/watchdog.conf> > > > > > > Just to clarify, the goal is not to manage swupdate but merely to > > > confirm that the daemon is running properly. > > > > See above. > > > > Best regards, > > Stefano Babic > > > > > > > > Best regards, > > > > > > Pierre > > > > > > On Wed, Mar 5, 2025 at 12:56 PM Stefano Babic > > > <stefano.babic@swupdate.org <mailto:stefano.babic@swupdate.org> > > <mailto:stefano.babic@swupdate.org > > <mailto:stefano.babic@swupdate.org>>> wrote: > > > > > > Hi Pierre, > > > > > > On 3/5/25 12:45, Pierre Lebleu wrote: > > > > Signed-off-by: Pierre Lebleu <pierre.lebleu@pile- > > engineering.com <mailto:pierre.lebleu@pile-engineering.com> > > > <mailto:pierre.lebleu@pile-engineering.com > > <mailto:pierre.lebleu@pile-engineering.com>>> > > > > --- > > > > mongoose/mongoose_interface.c | 37 +++++++++++++++++++++ > > +++++++ > > > +++---- > > > > 1 file changed, 33 insertions(+), 4 deletions(-) > > > > > > > > > > Apart of the patch itself, this does not make a lot of sense > > for me. Why > > > do we need the external pid ? > > > > > > SWUpdate is a multithread and multiprocess application, and > > it handles > > > itself the owned processes. First question could be why the > > Webserver > > > and the other processes (downloader, suricatta, etc..). > > > > > > So which is the use case ? And what is supposed to do ? > > > > > > It seems also to me a bad design to try to manage the > > processes outside > > > SWUpdate. It won't know then and its behavior could become > > > unpredictable. > > > > > > Best regards, > > > Stefano Babic > > > > > > > diff --git a/mongoose/mongoose_interface.c b/mongoose/ > > > mongoose_interface.c > > > > index bc514598..11518eef 100644 > > > > --- a/mongoose/mongoose_interface.c > > > > +++ b/mongoose/mongoose_interface.c > > > > @@ -39,10 +39,12 @@ > > > > #define MG_TLS 0 > > > > #endif > > > > > > > > +#define MG_PIDFILE "/run/swupdate-mongoose.pid" > > > > #define MG_PORT "8080" > > > > #define MG_ROOT "." > > > > > > > > struct mongoose_options { > > > > + char *pidfile; > > > > char *root; > > > > bool listing; > > > > char *port; > > > > @@ -776,6 +778,11 @@ static int mongoose_settings(void > *elem, > > > void __attribute__ ((__unused__)) *dat > > > > if (strlen(tmp)) { > > > > opts->port = strdup(tmp); > > > > } > > > > + > > > > + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, > > "pidfile", tmp); > > > > + if (strlen(tmp)) { > > > > + opts->pidfile = strdup(tmp); > > > > + } > > > > #if MG_TLS > > > > GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, > > > "ssl_certificate", tmp); > > > > if (strlen(tmp)) { > > > > @@ -807,6 +814,7 @@ static int mongoose_settings(void > *elem, > > > void __attribute__ ((__unused__)) *dat > > > > static struct option long_options[] = { > > > > {"listing", no_argument, NULL, 'l'}, > > > > {"port", required_argument, NULL, 'p'}, > > > > + {"pidfile", required_argument, NULL, 'P'}, > > > > #if MG_TLS > > > > {"ssl", no_argument, NULL, 's'}, > > > > {"ssl-cert", required_argument, NULL, 'C'}, > > > > @@ -825,7 +833,8 @@ void mongoose_print_help(void) > > > > stdout, > > > > "\tmongoose arguments:\n" > > > > "\t -l, --listing : enable > > > directory listing\n" > > > > - "\t -p, --port <port> : server > > port > > > number (default: %s)\n" > > > > + "\t -p, --port <port> : server > > port > > > number (default: %s)\n" > > > > + "\t -P, --pidfile <file> : > > specify a pid > > > file (default: %s)\n" > > > > #if MG_TLS > > > > "\t -s, --ssl : enable > ssl > > > support\n" > > > > "\t -C, --ssl-cert <cert> : ssl > > > certificate to present to clients\n" > > > > @@ -835,7 +844,7 @@ void mongoose_print_help(void) > > > > "\t -t, --timeout : > timeout to > > > check if connection is lost (default: check disabled)\n" > > > > "\t --auth-domain : set > > > authentication domain if any (default: none)\n" > > > > "\t --global-auth-file : set > > > authentication file if any (default: none)\n", > > > > - MG_PORT, MG_ROOT); > > > > + MG_PORT, MG_PIDFILE, MG_ROOT); > > > > } > > > > > > > > int start_mongoose(const char *cfgfname, int argc, char > > *argv[]) > > > > @@ -845,6 +854,7 @@ int start_mongoose(const char > > *cfgfname, int > > > argc, char *argv[]) > > > > struct mg_connection *nc; > > > > char *url = NULL; > > > > int choice; > > > > + pid_t pid; > > > > > > > > #if MG_TLS > > > > ssl = false; > > > > @@ -875,7 +885,7 @@ int start_mongoose(const char > > *cfgfname, int > > > argc, char *argv[]) > > > > } > > > > > > > > optind = 1; > > > > - while ((choice = getopt_long(argc, argv, > > "lp:sC:K:r:a:t:", > > > > + while ((choice = getopt_long(argc, argv, > > "lp:P:sC:K:r:a:t:", > > > > long_options, NULL)) != > > -1) { > > > > switch (choice) { > > > > case '0': > > > > @@ -893,6 +903,10 @@ int start_mongoose(const char > > *cfgfname, int > > > argc, char *argv[]) > > > > free(opts.port); > > > > opts.port = strdup(optarg); > > > > break; > > > > + case 'P': > > > > + free(opts.pidfile); > > > > + opts.pidfile = strdup(optarg); > > > > + break; > > > > case 't': > > > > watchdog_conn = strtoul(optarg, > > NULL, 10); > > > > break; > > > > @@ -963,8 +977,23 @@ int start_mongoose(const char > > *cfgfname, int > > > argc, char *argv[]) > > > > > > > > mg_wakeup_init(&mgr); > > > > > > > > + pid = getpid(); > > > > INFO("Mongoose web server v%s with PID %d listening > > on %s > > > and serving %s", > > > > - MG_VERSION, getpid(), url, > > > s_http_server_opts.root_dir); > > > > + MG_VERSION, pid, url, > > s_http_server_opts.root_dir); > > > > + > > > > + if (opts.pidfile) { > > > > + FILE *fd = fopen(opts.pidfile, "w"); > > > > + > > > > + if (fd) { > > > > + INFO("Writing PID into %s\n", > > opts.pidfile); > > > > + fprintf(fd, "%d\n", pid); > > > > + fclose(fd); > > > > + } else { > > > > + WARN("Error opening file %s: %s > (errno: > > > %d)", opts.pidfile, strerror(errno), errno); > > > > + } > > > > + > > > > + free(opts.pidfile); > > > > + } > > > > > > > > while (s_signo == 0) > > > > mg_mgr_poll(&mgr, 100); > > > > > > -- > > > You received this message because you are subscribed to the Google > > > Groups "swupdate" group. > > > To unsubscribe from this group and stop receiving emails from it, > > send > > > an email to swupdate+unsubscribe@googlegroups.com > > <mailto:swupdate%2Bunsubscribe@googlegroups.com> > > > <mailto:swupdate+unsubscribe@googlegroups.com > > <mailto:swupdate%2Bunsubscribe@googlegroups.com>>. > > > To view this discussion visit https://groups.google.com/d/msgid/ > > <https://groups.google.com/d/msgid/> > > > swupdate/ > > > > > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw% > 40mail.gmail.com <http://40mail.gmail.com> > > > <https://groups.google.com/d/msgid/swupdate/ <https:// > > groups.google.com/d/msgid/swupdate/> > > > > > CADBTOeqyryw3WDrmD3vGsoTt12GbWfNXKtdNRWDi3C%3DW-6fjxw% > 40mail.gmail.com <http://40mail.gmail.com>? > > > utm_medium=email&utm_source=footer>. > > > >
diff --git a/mongoose/mongoose_interface.c b/mongoose/mongoose_interface.c index bc514598..11518eef 100644 --- a/mongoose/mongoose_interface.c +++ b/mongoose/mongoose_interface.c @@ -39,10 +39,12 @@ #define MG_TLS 0 #endif +#define MG_PIDFILE "/run/swupdate-mongoose.pid" #define MG_PORT "8080" #define MG_ROOT "." struct mongoose_options { + char *pidfile; char *root; bool listing; char *port; @@ -776,6 +778,11 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat if (strlen(tmp)) { opts->port = strdup(tmp); } + + GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "pidfile", tmp); + if (strlen(tmp)) { + opts->pidfile = strdup(tmp); + } #if MG_TLS GET_FIELD_STRING_RESET(LIBCFG_PARSER, elem, "ssl_certificate", tmp); if (strlen(tmp)) { @@ -807,6 +814,7 @@ static int mongoose_settings(void *elem, void __attribute__ ((__unused__)) *dat static struct option long_options[] = { {"listing", no_argument, NULL, 'l'}, {"port", required_argument, NULL, 'p'}, + {"pidfile", required_argument, NULL, 'P'}, #if MG_TLS {"ssl", no_argument, NULL, 's'}, {"ssl-cert", required_argument, NULL, 'C'}, @@ -825,7 +833,8 @@ void mongoose_print_help(void) stdout, "\tmongoose arguments:\n" "\t -l, --listing : enable directory listing\n" - "\t -p, --port <port> : server port number (default: %s)\n" + "\t -p, --port <port> : server port number (default: %s)\n" + "\t -P, --pidfile <file> : specify a pid file (default: %s)\n" #if MG_TLS "\t -s, --ssl : enable ssl support\n" "\t -C, --ssl-cert <cert> : ssl certificate to present to clients\n" @@ -835,7 +844,7 @@ void mongoose_print_help(void) "\t -t, --timeout : timeout to check if connection is lost (default: check disabled)\n" "\t --auth-domain : set authentication domain if any (default: none)\n" "\t --global-auth-file : set authentication file if any (default: none)\n", - MG_PORT, MG_ROOT); + MG_PORT, MG_PIDFILE, MG_ROOT); } int start_mongoose(const char *cfgfname, int argc, char *argv[]) @@ -845,6 +854,7 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) struct mg_connection *nc; char *url = NULL; int choice; + pid_t pid; #if MG_TLS ssl = false; @@ -875,7 +885,7 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) } optind = 1; - while ((choice = getopt_long(argc, argv, "lp:sC:K:r:a:t:", + while ((choice = getopt_long(argc, argv, "lp:P:sC:K:r:a:t:", long_options, NULL)) != -1) { switch (choice) { case '0': @@ -893,6 +903,10 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) free(opts.port); opts.port = strdup(optarg); break; + case 'P': + free(opts.pidfile); + opts.pidfile = strdup(optarg); + break; case 't': watchdog_conn = strtoul(optarg, NULL, 10); break; @@ -963,8 +977,23 @@ int start_mongoose(const char *cfgfname, int argc, char *argv[]) mg_wakeup_init(&mgr); + pid = getpid(); INFO("Mongoose web server v%s with PID %d listening on %s and serving %s", - MG_VERSION, getpid(), url, s_http_server_opts.root_dir); + MG_VERSION, pid, url, s_http_server_opts.root_dir); + + if (opts.pidfile) { + FILE *fd = fopen(opts.pidfile, "w"); + + if (fd) { + INFO("Writing PID into %s\n", opts.pidfile); + fprintf(fd, "%d\n", pid); + fclose(fd); + } else { + WARN("Error opening file %s: %s (errno: %d)", opts.pidfile, strerror(errno), errno); + } + + free(opts.pidfile); + } while (s_signo == 0) mg_mgr_poll(&mgr, 100);
Signed-off-by: Pierre Lebleu <pierre.lebleu@pile-engineering.com> --- mongoose/mongoose_interface.c | 37 +++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)