#include "strutils.h"
#include "exitcodes.h"
#include "timeutils.h"
+#include "optutils.h"
#define EXIT_TIMEOUT_EXPIRED 3
#define TIMEOUT_SOCKET_IDX UINT64_MAX
-#define err_nosys(exitcode, ...) \
- err(errno == ENOSYS ? EXIT_NOTSUPP : exitcode, __VA_ARGS__)
-
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)
{
pidfds[i] = pidfd_open(pids[i], 0);
if (pidfds[i] == -1) {
if (allow_exited && errno == ESRCH) {
- warnx(_("PID %d has exited, skipping"), pids[i]);
+ if (verbose)
+ warnx(_("PID %d has exited, skipping"), pids[i]);
continue;
}
err_nosys(EXIT_FAILURE, _("could not open pid %u"), pids[i]);
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));
{ "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' },
- { NULL, 0, NULL, 0 },
+ { 0 }
+ };
+ static const ul_excl_t excl[] = { /* rows and cols in ASCII order */
+ { 'c', 'e' },
+ { 0 }
};
+ int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
+
+ while ((c = getopt_long (argc, argv, "vVht:c:e", longopts, NULL)) != -1) {
+
+ err_exclusive_options(c, longopts, excl, excl_st);
- while ((c = getopt_long (argc, argv, "vVht:e", longopts, NULL)) != -1) {
switch (c) {
case 'v':
verbose = true;
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':
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);
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);
}