From: Thomas Weißschuh Date: Thu, 2 Mar 2023 21:06:31 +0000 (+0000) Subject: waitpid: allow to only wait for a specific number of process exits X-Git-Tag: v2.39-rc1~16^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0e793a3d9083aa5d8bfe1ec27ce107f2df6780f;p=thirdparty%2Futil-linux.git waitpid: allow to only wait for a specific number of process exits Signed-off-by: Thomas Weißschuh --- diff --git a/bash-completion/waitpid b/bash-completion/waitpid index 67601bb8f7..60ea275afc 100644 --- a/bash-completion/waitpid +++ b/bash-completion/waitpid @@ -9,6 +9,9 @@ _waitpid_module() COMPREPLY=( $(compgen -W "seconds" -- $cur) ) return 0 ;; + '-c'|'--count') + return 0 + ;; '-h'|'--help'|'-V'|'--version') return 0 ;; @@ -18,6 +21,7 @@ _waitpid_module() OPTS="--verbose --timeout --exited + --count --help --version" COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) diff --git a/misc-utils/waitpid.1.adoc b/misc-utils/waitpid.1.adoc index ea9a7cf5c3..e0dae517ed 100644 --- a/misc-utils/waitpid.1.adoc +++ b/misc-utils/waitpid.1.adoc @@ -32,6 +32,9 @@ Maximum wait time. *-e*, *--exited*:: Don't error on already exited PIDs. +*-c*, *--count* _count_:: +Number of process exits to wait for. + include::man-common/help-version.adoc[] == EXIT STATUS diff --git a/misc-utils/waitpid.c b/misc-utils/waitpid.c index f7c5d4166e..871a36949e 100644 --- a/misc-utils/waitpid.c +++ b/misc-utils/waitpid.c @@ -46,6 +46,7 @@ static bool verbose = false; static struct timespec timeout; static bool allow_exited = false; +static size_t count; static pid_t *parse_pids(size_t n_strings, char * const *strings) { @@ -161,6 +162,7 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -v, --verbose be more verbose\n"), out); fputs(_(" -t, --timeout= wait at most timeout seconds\n"), out); fputs(_(" -e, --exited allow exited PIDs\n"), out); + fputs(_(" -c, --count= number of process exits to wait for\n"), out); fputs(USAGE_SEPARATOR, out); fprintf(out, USAGE_HELP_OPTIONS(25)); @@ -177,12 +179,13 @@ static int parse_options(int argc, char **argv) { "verbose", no_argument, NULL, 'v' }, { "timeout", required_argument, NULL, 't' }, { "exited", no_argument, NULL, 'e' }, + { "count", required_argument, NULL, 'c' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, { 0 } }; - while ((c = getopt_long (argc, argv, "vVht:e", longopts, NULL)) != -1) { + while ((c = getopt_long (argc, argv, "vVht:c:e", longopts, NULL)) != -1) { switch (c) { case 'v': verbose = true; @@ -194,6 +197,10 @@ static int parse_options(int argc, char **argv) case 'e': allow_exited = true; break; + case 'c': + count = str2num_or_err(optarg, 10, _("Invalid count"), + 1, INT64_MAX); + break; case 'V': print_version(EXIT_SUCCESS); case 'h': @@ -203,6 +210,10 @@ static int parse_options(int argc, char **argv) } } + if (allow_exited && count) + errx(EXIT_FAILURE, + _("-e/--exited and -c/--count are incompatible")); + return optind; } @@ -220,6 +231,10 @@ int main(int argc, char **argv) if (!n_pids) errx(EXIT_FAILURE, _("no PIDs specified")); + if (count && count > n_pids) + errx(EXIT_FAILURE, + _("can't want for %zu of %zu PIDs"), count, n_pids); + pid_t *pids = parse_pids(argc - pid_idx, argv + pid_idx); pidfds = open_pidfds(n_pids, pids); @@ -229,5 +244,7 @@ int main(int argc, char **argv) err_nosys(EXIT_FAILURE, _("could not create epoll")); active_pids = add_listeners(epoll, n_pids, pidfds, timeoutfd); + if (count) + active_pids = min(active_pids, count); wait_for_exits(epoll, active_pids, pids, pidfds); } diff --git a/tests/expected/misc/waitpid-count b/tests/expected/misc/waitpid-count new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/expected/misc/waitpid-count @@ -0,0 +1 @@ +1 diff --git a/tests/expected/misc/waitpid-count.err b/tests/expected/misc/waitpid-count.err new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/tests/expected/misc/waitpid-count.err @@ -0,0 +1 @@ +0 diff --git a/tests/ts/misc/waitpid b/tests/ts/misc/waitpid index 599bb47da3..ae5ab6f928 100755 --- a/tests/ts/misc/waitpid +++ b/tests/ts/misc/waitpid @@ -48,4 +48,12 @@ ts_init_subtest exited echo $? >> "$TS_ERRLOG" ts_finalize_subtest +ts_init_subtest count +(sleep 0.2; echo 1 >> "$TS_OUTPUT") & +BG1="$!" + +"$TS_CMD_WAITPID" -c 1 1 "$BG1" >> "$TS_OUTPUT" 2>> "$TS_ERRLOG" +echo $? >> "$TS_ERRLOG" +ts_finalize_subtest + ts_finalize