From 04f99c49513427cf8b61a3b5551b4e36a78ccd45 Mon Sep 17 00:00:00 2001 From: Andrew Wood Date: Thu, 19 Mar 2026 22:57:41 +0000 Subject: [PATCH] Use a special type for opts->argv[] so that the whole array, and array entries, can both be NULL, and the array entries pointers to constant strings; and ensure that argv[] always has a NULL pointer on the end - all so argv can be passed to execvp() (#67). --- src/include/options.h | 4 +++- src/main/options.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/include/options.h b/src/include/options.h index bf07871..ecf0b23 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -46,6 +46,8 @@ typedef enum { PV_SIDE_BOTH /* monitor both sides */ } pvside_t; +typedef /*@null@*/ const char * argv_string; + /* * Structure describing run-time options. * @@ -66,7 +68,7 @@ struct opts_s { /*@keep@*/ /*@null@*/ char *extra_display; /* extra display specifier, if any */ /*@keep@*/ /*@null@*/ pid_t *watchfd_pid; /* array of processes to watch fds of */ /*@keep@*/ /*@null@*/ int *watchfd_fd; /* array of fds to watch in each one (0=all) */ - /*@keep@*/ /*@null@*/ const char **argv; /* array of non-option arguments */ + /*@keep@*/ /*@null@*/ argv_string *argv; /* array of non-option arguments */ size_t lastwritten; /* show N bytes last written */ off_t rate_limit; /* rate limit, in bytes per second */ size_t buffer_size; /* buffer size, in bytes (0=default) */ diff --git a/src/main/options.c b/src/main/options.c index c6e691c..879f3e3 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -92,12 +92,13 @@ void opts_free( /*@only@ */ opts_t opts) /* * Add a filename to the list of non-option arguments, returning false on - * error. The filename is not copied - the pointer is stored. + * error. The filename is not copied - the pointer is stored. The list is + * guaranteed to have a NULL after the last item. */ bool opts_add_file(opts_t opts, const char *filename) { /*@-branchstate@ */ - if ((opts->argc >= opts->argv_length) || (NULL == opts->argv)) { + if (((1+opts->argc) >= opts->argv_length) || (NULL == opts->argv)) { opts->argv_length = opts->argc + 10; /*@-keeptrans@ */ opts->argv = realloc(opts->argv, opts->argv_length * sizeof(char *)); @@ -121,6 +122,7 @@ bool opts_add_file(opts_t opts, const char *filename) */ opts->argv[opts->argc++] = filename; + opts->argv[opts->argc] = NULL; return true; }