aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2023-03-03 13:01:18 +0100
committerKarel Zak <kzak@redhat.com>2023-03-03 13:01:18 +0100
commit7dcb35dd176443238859de18cc73f0906287b91d (patch)
tree5676ca2df30f16c966900dd72b2cd5d0e745cab6
parent3b077eca0c01b386bd86a4639def65b14128d521 (diff)
parentf0e793a3d9083aa5d8bfe1ec27ce107f2df6780f (diff)
downloadutil-linux-7dcb35dd176443238859de18cc73f0906287b91d.tar.gz
Merge branch 'waitpid/count' of https://github.com/t-8ch/util-linux
* 'waitpid/count' of https://github.com/t-8ch/util-linux: waitpid: allow to only wait for a specific number of process exits
-rw-r--r--bash-completion/waitpid4
-rw-r--r--misc-utils/waitpid.1.adoc3
-rw-r--r--misc-utils/waitpid.c19
-rw-r--r--tests/expected/misc/waitpid-count1
-rw-r--r--tests/expected/misc/waitpid-count.err1
-rwxr-xr-xtests/ts/misc/waitpid8
6 files changed, 35 insertions, 1 deletions
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=<timeout> wait at most timeout seconds\n"), out);
fputs(_(" -e, --exited allow exited PIDs\n"), out);
+ fputs(_(" -c, --count=<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