diff mbox series

moongoose: Add support for writing PID file on startup

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

Commit Message

Pierre Lebleu March 5, 2025, 11:45 a.m. UTC
Signed-off-by: Pierre Lebleu <pierre.lebleu@pile-engineering.com>
---
 mongoose/mongoose_interface.c | 37 +++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

Comments

Stefano Babic March 5, 2025, 11:56 a.m. UTC | #1
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);
Pierre Lebleu March 5, 2025, 12:11 p.m. UTC | #2
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);
>
>
Stefano Babic March 5, 2025, 12:17 p.m. UTC | #3
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>.
Pierre Lebleu March 5, 2025, 12:30 p.m. UTC | #4
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>.
>
>
Stefano Babic March 5, 2025, 12:32 p.m. UTC | #5
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>.
>
Pierre Lebleu March 5, 2025, 12:47 p.m. UTC | #6
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 mbox series

Patch

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);