diff --git a/src/include/options.h b/src/include/options.h index 9a2744b..1dd6a5a 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -39,6 +39,8 @@ struct opts_s { /*@keep@*/ /*@null@*/ char *pidfile; /* PID file, if any */ /*@keep@*/ /*@null@*/ char *store_and_forward_file; /* store and forward file, if any */ /*@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 */ size_t lastwritten; /* show N bytes last written */ off_t rate_limit; /* rate limit, in bytes per second */ @@ -54,6 +56,8 @@ struct opts_s { unsigned int height; /* screen height */ unsigned int argc; /* number of non-option arguments */ unsigned int argv_length; /* allocated array size */ + size_t watchfd_count; /* number of watchfd items */ + size_t watchfd_length; /* allocated array size */ bool do_nothing; /* exit-without-doing-anything flag */ bool progress; /* progress bar flag */ bool timer; /* timer flag */ diff --git a/src/main/options.c b/src/main/options.c index 8e4001b..960e846 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -63,6 +63,10 @@ void opts_free( /*@only@ */ opts_t opts) free(opts->store_and_forward_file); if (NULL != opts->extra_display) free(opts->extra_display); + if (NULL != opts->watchfd_pid) + free(opts->watchfd_pid); + if (NULL != opts->watchfd_fd) + free(opts->watchfd_fd); if (NULL != opts->argv) free(opts->argv); /*@+keeptrans@ */ @@ -104,6 +108,40 @@ bool opts_add_file(opts_t opts, const char *filename) return true; } +/* + * Add a process ID and file descriptor to the list of items to watch with + * --watchfd, returning false on error. + */ +static bool opts_add_watchfd(opts_t opts, pid_t pid, int fd) +{ + /*@-branchstate@ */ + if ((opts->watchfd_count >= opts->watchfd_length) || (NULL == opts->watchfd_pid)) { + opts->watchfd_length = opts->watchfd_count + 10; + /*@-keeptrans@ */ + opts->watchfd_pid = realloc(opts->watchfd_pid, opts->watchfd_length * sizeof(pid_t)); + opts->watchfd_fd = realloc(opts->watchfd_fd, opts->watchfd_length * sizeof(int)); + /*@+keeptrans@ */ + if ((NULL == opts->watchfd_pid) || (NULL == opts->watchfd_fd)) { + fprintf(stderr, "%s: %s\n", opts->program_name, strerror(errno)); + opts->watchfd_length = 0; + opts->watchfd_count = 0; + return false; + } + } + /*@+branchstate@ */ + + /* + * splint notes: we turned off "branchstate" and "keeptrans" above + * because of the same reason as in opts_add_file(). + */ + + opts->watchfd_pid[opts->watchfd_count] = pid; + opts->watchfd_fd[opts->watchfd_count] = fd; + opts->watchfd_count++; + + return true; +} + /* * Set opts->size from the size of the file whose name is size_file, @@ -469,6 +507,10 @@ opts_t opts_parse(unsigned int argc, char **argv) return NULL; /*@+mustfreefresh@ */ } + if (!opts_add_watchfd(opts, (pid_t) check_pid, check_fd)) { + opts_free(opts); + return NULL; + } break; default: break;