Add --watchfd option values to an array in the main state, as well as to the currently used variables (#12).

This commit is contained in:
Andrew Wood
2025-09-17 23:12:13 +01:00
parent 12cc996d32
commit dbce5b355e
5 changed files with 75 additions and 10 deletions
+2 -2
View File
@@ -56,8 +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 */
unsigned int watchfd_count; /* number of watchfd items */
unsigned int watchfd_length; /* allocated array size */
bool do_nothing; /* exit-without-doing-anything flag */
bool progress; /* progress bar flag */
bool timer; /* timer flag */
+10 -8
View File
@@ -131,13 +131,6 @@ typedef uint16_t pvdisplay_bytecount_t;
typedef uint16_t pvdisplay_width_t;
#define PVDISPLAY_WIDTH_MAX (65535) /* UINT16_MAX */
/* Process and (optional) file descriptor to watch with "--watchfd". */
struct pvwatchspec_s {
pid_t pid; /* process to watch fds of */
int fd; /* fd to watch, or 0 for all */
};
typedef struct pvwatchspec_s *pvwatchspec_t;
/* String pointer, that is the only pointer to this resource, that can be null. */
typedef /*@only@*/ /*@null@*/ char * nullable_string_t;
@@ -167,6 +160,15 @@ struct pvstate_s {
unsigned int file_count; /* number of input files */
} files;
/*********************************
* Items to watch with --watchfd *
*********************************/
struct pvwatchspec_s {
/*@only@*/ /*@null@*/ pid_t *pid; /* array of processes to watch fds of */
/*@only@*/ /*@null@*/ int *fd; /* array of fds to watch in each one (0=all) */
unsigned int count; /* number of items in these arrays */
} watchfd;
/*******************
* Program control *
*******************/
@@ -183,7 +185,7 @@ struct pvstate_s {
off_t rate_limit; /* rate limit, in bytes per second */
size_t target_buffer_size; /* buffer size (0=default) */
off_t size; /* total size of data */
/* TODO: replace watch_pid, watch_fd with an array of structs (#12) */
/* TODO: replace watch_pid, watch_fd with arrays (#12) */
pid_t watch_pid; /* process to watch fds of */
unsigned int skip_errors; /* skip read errors counter */
int watch_fd; /* fd to watch */
+1
View File
@@ -240,6 +240,7 @@ extern void pv_state_average_rate_window_set(pvstate_t, unsigned int);
extern void pv_state_set_terminal_supports_utf8(pvstate_t, bool);
extern void pv_state_inputfiles(pvstate_t, unsigned int, const char **);
extern void pv_state_watchfds(pvstate_t, unsigned int, const pid_t *, const int *);
/*
* Work out whether we are in the foreground.
+7
View File
@@ -387,6 +387,13 @@ int main(int argc, char **argv)
pv_state_inputfiles(state, opts->argc, (const char **) (opts->argv));
}
/*
* Put the list of watchfd items into the PV internal state.
*/
if ((opts->watchfd_count > 0) && (NULL != opts->watchfd_pid) && (NULL != opts->watchfd_fd)) {
pv_state_watchfds(state, opts->watchfd_count, opts->watchfd_pid, opts->watchfd_fd);
}
/*
* If stderr is not a terminal and we're neither forcing output nor
* outputting numerically, we will have nothing to display at all.
+55
View File
@@ -323,6 +323,15 @@ void pv_state_free(pvstate_t state)
state->files.filename = NULL;
}
if (NULL != state->watchfd.pid) {
free(state->watchfd.pid);
state->watchfd.pid = NULL;
}
if (NULL != state->watchfd.fd) {
free(state->watchfd.fd);
state->watchfd.fd = NULL;
}
free(state);
return;
@@ -703,3 +712,49 @@ void pv_state_inputfiles(pvstate_t state, unsigned int input_file_count, const c
}
state->files.file_count = input_file_count;
}
/*
* Set the arrays of watchfd process IDs and file descriptors.
*/
void pv_state_watchfds(pvstate_t state, unsigned int watchfd_count, const pid_t * pids, const int *fds)
{
unsigned int item_idx;
/*@only@ */ pid_t *new_pid_array = NULL;
/*@only@ */ int *new_fd_array = NULL;
/* Free the old arrays, if there were any. */
if (NULL != state->watchfd.pid) {
free(state->watchfd.pid);
state->watchfd.pid = NULL;
}
if (NULL != state->watchfd.fd) {
free(state->watchfd.fd);
state->watchfd.fd = NULL;
}
state->watchfd.count = 0;
/* Allocate empty new arrays of the right size. */
new_pid_array = calloc((size_t) (watchfd_count + 1), sizeof(pid_t));
if (NULL == new_pid_array) {
/*@-mustfreefresh@ *//* see similar _() issue above */
pv_error("%s: %s", _("process list allocation failed"), strerror(errno));
/*@+mustfreefresh@ */
return;
}
state->watchfd.pid = new_pid_array;
new_fd_array = calloc((size_t) (watchfd_count + 1), sizeof(int));
if (NULL == new_fd_array) {
/*@-mustfreefresh@ *//* see similar _() issue above */
pv_error("%s: %s", _("file descriptor list allocation failed"), strerror(errno));
/*@+mustfreefresh@ */
return;
}
state->watchfd.fd = new_fd_array;
/* Populate the new arrays with the values supplied. */
for (item_idx = 0; item_idx < watchfd_count; item_idx++) {
state->watchfd.pid[item_idx] = pids[item_idx];
state->watchfd.fd[item_idx] = fds[item_idx];
}
state->watchfd.count = watchfd_count;
}