On 12/08/12 19:38, Todd C. Miller wrote:
> On Thu, 06 Dec 2012 10:55:50 +0100, Alexander Hall wrote:
>
>> If, between the internal grep'ing and the printout, a process has
>> disappeared, we currently get an empty line and pgrep will return
>> nonzero.
>
> Wouldn't it be better to just defer the printing of the delimiter
> under we get the args? Then you can just return success if errno
> is ESRCH or -1 for other errors.
>
> Perhaps something like this (untested).
I was thinking in these lines too, but with this, you might get the
result that pgrep returns 0 while not printing anything.
This diff follows your line, but allows *action to return match, error
or nomatch, handled appropriately by the main loop. Also make the same
changes to killact().
I have yet to make it fail my tests. Makes sense? OK?
/Alexander
Index: pkill.c
===================================================================
RCS file: /data/openbsd/cvs/src/usr.bin/pkill/pkill.c,v
retrieving revision 1.30
diff -u -p -r1.30 pkill.c
--- pkill.c 21 Aug 2012 10:32:38 -0000 1.30
+++ pkill.c 8 Dec 2012 22:41:11 -0000
@@ -419,10 +419,18 @@ main(int argc, char **argv)
if (selected[i] == inverse)
continue;
- if ((*action)(kp, j++) == -1)
+ switch ((*action)(kp, j++)) {
+ case STATUS_MATCH:
+ if (rv != STATUS_ERROR)
+ rv = STATUS_MATCH;
+ break;
+ case STATUS_NOMATCH:
+ j--;
+ break;
+ case STATUS_ERROR:
rv = STATUS_ERROR;
- else if (rv != STATUS_ERROR)
- rv = STATUS_MATCH;
+ break;
+ }
}
if (pgrep && j && !quiet)
putchar('\n');
@@ -453,38 +461,41 @@ killact(struct kinfo_proc *kp, int dummy
if (longfmt && !quiet)
printf("%d %s\n", (int)kp->p_pid, kp->p_comm);
- if (kill(kp->p_pid, signum) == -1 && errno != ESRCH) {
+ if (kill(kp->p_pid, signum) == -1) {
+ if (errno == ESRCH)
+ return (STATUS_NOMATCH);
warn("signalling pid %d", (int)kp->p_pid);
- return (-1);
+ return (STATUS_ERROR);
}
- return (0);
+ return (STATUS_MATCH);
}
int
grepact(struct kinfo_proc *kp, int printdelim)
{
char **argv;
+ const char *prefix = "";
if (quiet)
- return (0);
+ return (STATUS_MATCH);
if (printdelim)
- fputs(delim, stdout);
+ prefix = delim;
if (longfmt && matchargs) {
if ((argv = kvm_getargv(kd, kp, 0)) == NULL)
- return (-1);
+ return (errno == ESRCH ? STATUS_NOMATCH : STATUS_ERROR);
- printf("%d ", (int)kp->p_pid);
+ printf("%s%d ", prefix, (int)kp->p_pid);
for (; *argv != NULL; argv++) {
printf("%s", *argv);
if (argv[1] != NULL)
putchar(' ');
}
} else if (longfmt)
- printf("%d %s", (int)kp->p_pid, kp->p_comm);
+ printf("%s%d %s", prefix, (int)kp->p_pid, kp->p_comm);
else
- printf("%d", (int)kp->p_pid);
+ printf("%s%d", prefix, (int)kp->p_pid);
- return (0);
+ return (STATUS_MATCH);
}
void