pidof.c - ubase - suckless linux base utils
 (HTM) git clone git://git.suckless.org/ubase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       pidof.c (2017B)
       ---
            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         for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) {
           59                 pe = emalloc(sizeof(*pe));
           60                 if (strcmp(p, "%PPID") == 0)
           61                         pe->pid = getppid();
           62                 else
           63                         pe->pid = estrtol(p, 10);
           64                 SLIST_INSERT_HEAD(&omitpid_head, pe, entry);
           65         }
           66 
           67         if (!(dp = opendir("/proc")))
           68                 eprintf("opendir /proc:");
           69 
           70         while ((entry = readdir(dp))) {
           71                 if (!pidfile(entry->d_name))
           72                         continue;
           73                 pid = estrtol(entry->d_name, 10);
           74                 if (oflag) {
           75                         SLIST_FOREACH(pe, &omitpid_head, entry)
           76                                 if (pe->pid == pid)
           77                                         break;
           78                         if (pe)
           79                                 continue;
           80                 }
           81                 if (parsestat(pid, &ps) < 0)
           82                         continue;
           83                 if (parsecmdline(ps.pid, cmdline,
           84                                  sizeof(cmdline)) < 0) {
           85                         cmd = ps.comm;
           86                         cmdbase = cmd;
           87                 } else {
           88                         if ((p = strchr(cmdline, ' ')))
           89                                 *p = '\0';
           90                         cmd = cmdline;
           91                         cmdbase = basename(cmdline);
           92                 }
           93                 /* Workaround for login shells */
           94                 if (cmd[0] == '-')
           95                         cmd++;
           96                 for (i = 0; i < argc; i++) {
           97                         if (strcmp(cmd, argv[i]) == 0 ||
           98                             strcmp(cmdbase, argv[i]) == 0) {
           99                                 putword(entry->d_name);
          100                                 found++;
          101                                 if (sflag)
          102                                         goto out;
          103                         }
          104                 }
          105         }
          106 
          107 out:
          108         if (found)
          109                 putchar('\n');
          110 
          111         closedir(dp);
          112 
          113         return 0;
          114 }