#include #include #include #include #include #include #include #include extern const char *__progname; static const char *string; static regex_t pattern; static const char *ps_arg; static int nargs; static int len; static int our_pid; static int ps_pid; static int pid_loc; static int cmd_loc; static int kflag = 0; static int pflag = 0; static int sflag = 0; static int vflag = 0; static int xflag = 0; static int rflag = 0; static int qflag = 0; static int any; static int errs = 0; static int repeat = 0; static int repeat_delay = 60; static int (*exittest)(void); #ifdef __linux__ /* Linux doesn't seem to have sys_signame, leaving us without a way to map signal names to signals. :( */ static void set_kflag(const char *s) { fprintf(stderr,"%s: %s: -k not available on Linux\n",__progname,s); exit(1); } #else static void set_kflag(const char *s) { char *ep; int n; if (*s == '-') s ++; if (! *s) return; n = strtol(s,&ep,10); if (! *ep) { kflag = n; return; } for (n=1;n= linehave) line = realloc(line,(linehave=linelen+64)+1); line[linelen++] = c; } } pipe(p); if ((ps_pid=fork()) == 0) { dup2(p[1],fileno(stdout)); close(p[0]); close(p[1]); execl("/bin/ps","ps",ps_arg,(char *)0); exit(0); } close(p[1]); our_pid = getpid(); f = fdopen(p[0],"r"); initline(); if (! getline()) { if (! sflag) fprintf(stderr,"Cannot read ps header\n"); exit(2); } for (pid_loc=0;line[pid_loc];pid_loc++) { if (strncmp(line+pid_loc,"PID",3) == 0) { break; } } if (line[pid_loc] == '\0') { if (! sflag) fprintf(stderr,"Cannot find `PID' in \"%s\"\n",line); exit(2); } pid_loc += 2; switch (pid_loc) { case 2: olpad = " "; break; case 3: olpad = " "; break; default: olpad = ""; break; } for (cmd_loc=0;line[cmd_loc];cmd_loc++) { if (strncmp(line+cmd_loc,"COMMAND",7) == 0) { break; } } if (line[cmd_loc] == '\0') { if (! sflag) fprintf(stderr,"Cannot find `COMMAND' in \"%s\"\n",line); exit(2); } if (vflag || !(qflag||sflag||pflag||kflag)) printf("%s%s\n",olpad,line); while (getline()) { char *cp; int wantit; cp = line + pid_loc; while ((cp > line) && (*cp != ' ')) cp --; sscanf(cp,"%d",&pid); if ((pid == our_pid) || (pid == ps_pid)) continue; wantit = 0; if (rflag) { re_err = regexec(&pattern,line+cmd_loc,0,0,0); switch (re_err) { case 0: wantit = 1; break; case REG_NOMATCH: break; default: fprintf(stderr,"%s: %s: %s\n",__progname,string,regex_error(re_err,&pattern)); exit(1); break; } } else if (xflag) { wantit = (linelen == cmd_loc+len) && !bcmp(line+cmd_loc,string,len); } else { for (cp=line+cmd_loc;*cp;cp++) { if (! strncmp(cp,string,len)) { wantit = 1; break; } } } if (wantit) { if (vflag || !(sflag||pflag||kflag)) printf("%s%s\n",olpad,line); if (pflag) printf("%d\n",pid); if (kflag && (kill(pid,kflag) < 0)) { fprintf(stderr,"%s: kill(%d,%d): %s\n",__progname,pid,kflag,strerror(errno)); errs ++; } any = 1; } } fclose(f); } static void reap(void) { while (wait3(0,WNOHANG,0) > 0) ; } int main(int, char **); int main(int ac, char **av) { if (0) { usage:; fprintf(stderr,"Usage: %s [-k signal] [-p] [-s] [-v] [-x] [-r] [-q] [ps-arg] string\n",__progname); exit(2); } nargs = 0; string = "ax"; for (ac--,av++;ac;ac--,av++) { if (!strcmp(*av,"-k") && av[1]) { set_kflag(av[1]); ac --; av ++; continue; } if (!strcmp(*av,"-p")) { pflag = 1; continue; } if (!strcmp(*av,"-s")) { sflag = 1; continue; } if (!strcmp(*av,"-v")) { vflag = 1; continue; } if (!strcmp(*av,"-x")) { xflag = 1; continue; } if (!strcmp(*av,"-r")) { rflag = 1; continue; } if (!strcmp(*av,"-q")) { qflag = 1; continue; } if (!strcmp(*av,"-u")) { repeat = 1; sflag = 1; exittest = &exittest_until; continue; } if (!strcmp(*av,"-w")) { repeat = 1; sflag = 1; exittest = &exittest_while; continue; } if (!strcmp(*av,"-i") && av[1]) { repeat_delay = atoi(av[1]); if (repeat_delay < 1) { fprintf(stderr,"%s: -i value must be >= 1\n",__progname); repeat_delay = 60; } ac --; av ++; continue; } if (nargs >= 2) goto usage; nargs ++; ps_arg = string; string = *av; } if (nargs < 1) goto usage; len = strlen(string); if (rflag) { int re_err; re_err = regcomp(&pattern,string,REG_EXTENDED|REG_NOSUB); if (re_err) { fprintf(stderr,"%s: %s: %s\n",__progname,string,regex_error(re_err,&pattern)); exit(1); } } while (1) { any = 0; do_it(); if (!repeat || (*exittest)()) break; reap(); sleep(repeat_delay); } exit(errs||!any); }