URI:
       pidof.c - ubase - suckless linux base utils
  HTML git clone git://git.suckless.org/ubase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       pidof.c (2054B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <sys/types.h>
            3 
            4 #include <dirent.h>
            5 #include <libgen.h>
            6 #include <limits.h>
            7 #include <stdio.h>
            8 #include <stdlib.h>
            9 #include <string.h>
           10 #include <unistd.h>
           11 
           12 #include "proc.h"
           13 #include "queue.h"
           14 #include "util.h"
           15 
           16 struct pidentry {
           17         pid_t pid;
           18         SLIST_ENTRY(pidentry) entry;
           19 };
           20 
           21 static SLIST_HEAD(, pidentry) omitpid_head;
           22 
           23 static void
           24 usage(void)
           25 {
           26         eprintf("usage: %s [-o pid1,pid2,...pidN] [-s] [program...]\n", argv0);
           27 }
           28 
           29 int
           30 main(int argc, char *argv[])
           31 {
           32         DIR *dp;
           33         struct dirent *entry;
           34         pid_t pid;
           35         struct procstat ps;
           36         char cmdline[BUFSIZ], *cmd, *cmdbase = NULL, *p, *arg = NULL;
           37         int i, found = 0;
           38         int sflag = 0, oflag = 0;
           39         struct pidentry *pe;
           40 
           41         ARGBEGIN {
           42         case 's':
           43                 sflag = 1;
           44                 break;
           45         case 'o':
           46                 oflag = 1;
           47                 arg = EARGF(usage());
           48                 break;
           49         default:
           50                 usage();
           51         } ARGEND;
           52 
           53         if (!argc)
           54                 return 1;
           55 
           56         SLIST_INIT(&omitpid_head);
           57 
           58         if (oflag) {
           59                 for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) {
           60                         pe = emalloc(sizeof(*pe));
           61                         if (strcmp(p, "%PPID") == 0)
           62                                 pe->pid = getppid();
           63                         else
           64                                 pe->pid = estrtol(p, 10);
           65                         SLIST_INSERT_HEAD(&omitpid_head, pe, entry);
           66                 }
           67         }
           68 
           69         if (!(dp = opendir("/proc")))
           70                 eprintf("opendir /proc:");
           71 
           72         while ((entry = readdir(dp))) {
           73                 if (!pidfile(entry->d_name))
           74                         continue;
           75                 pid = estrtol(entry->d_name, 10);
           76                 if (oflag) {
           77                         SLIST_FOREACH(pe, &omitpid_head, entry)
           78                                 if (pe->pid == pid)
           79                                         break;
           80                         if (pe)
           81                                 continue;
           82                 }
           83                 if (parsestat(pid, &ps) < 0)
           84                         continue;
           85                 if (parsecmdline(ps.pid, cmdline,
           86                                  sizeof(cmdline)) < 0) {
           87                         cmd = ps.comm;
           88                         cmdbase = cmd;
           89                 } else {
           90                         if ((p = strchr(cmdline, ' ')))
           91                                 *p = '\0';
           92                         cmd = cmdline;
           93                         cmdbase = basename(cmdline);
           94                 }
           95                 /* Workaround for login shells */
           96                 if (cmd[0] == '-')
           97                         cmd++;
           98                 for (i = 0; i < argc; i++) {
           99                         if (strcmp(cmd, argv[i]) == 0 ||
          100                             strcmp(cmdbase, argv[i]) == 0) {
          101                                 putword(entry->d_name);
          102                                 found++;
          103                                 if (sflag)
          104                                         goto out;
          105                         }
          106                 }
          107         }
          108 
          109 out:
          110         if (found)
          111                 putchar('\n');
          112 
          113         closedir(dp);
          114 
          115         return found ? 0 : 1;
          116 }