proc.c - ubase - suckless linux base utils
 (HTM) git clone git://git.suckless.org/ubase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       proc.c (2391B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <sys/stat.h>
            3 
            4 #include <errno.h>
            5 #include <fcntl.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 "../util.h"
           14 
           15 int
           16 parsecmdline(pid_t pid, char *buf, size_t siz)
           17 {
           18         int fd;
           19         char path[PATH_MAX];
           20         ssize_t n, i;
           21 
           22         snprintf(path, sizeof(path), "/proc/%ld/cmdline", (long)pid);
           23         fd = open(path, O_RDONLY);
           24         if (fd < 0)
           25                 return -1;
           26         n = read(fd, buf, siz > 0 ? siz - 1 : 0);
           27         if (n < 0) {
           28                 weprintf("read %s:", path);
           29                 close(fd);
           30                 return -1;
           31         }
           32         if (!n) {
           33                 close(fd);
           34                 return -1;
           35         }
           36         buf[n] = '\0';
           37         for (i = 0; i < n; i++)
           38                 if (buf[i] == '\0')
           39                         buf[i] = ' ';
           40         close(fd);
           41         return 0;
           42 }
           43 
           44 int
           45 parsestat(pid_t pid, struct procstat *ps)
           46 {
           47         char path[PATH_MAX];
           48         FILE *fp;
           49         size_t len;
           50 
           51         snprintf(path, sizeof(path), "/proc/%d/stat", pid);
           52         if (!(fp = fopen(path, "r")))
           53                 return -1;
           54         fscanf(fp, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu",
           55                &ps->pid, ps->comm,
           56                &ps->state, &ps->ppid, &ps->pgrp,
           57                &ps->sid, &ps->tty_nr, &ps->tpgid, &ps->flags,
           58                &ps->minflt, &ps->cminflt, &ps->majflt, &ps->cmajflt,
           59                &ps->utime, &ps->stime);
           60         fscanf(fp, "%ld %ld %ld %ld %ld %ld %llu %lu %ld %ld",
           61                &ps->cutime, &ps->cstime, &ps->priority, &ps->nice,
           62                &ps->num_threads, &ps->itrealvalue, &ps->starttime,
           63                &ps->vsize, &ps->rss, &ps->rsslim);
           64         /* Filter out '(' and ')' from comm */
           65         if ((len = strlen(ps->comm)) > 0)
           66                 len--;
           67         ps->comm[len] = '\0';
           68         memmove(ps->comm, ps->comm + 1, len);
           69         fclose(fp);
           70         return 0;
           71 }
           72 
           73 int
           74 parsestatus(pid_t pid, struct procstatus *pstatus)
           75 {
           76         char path[PATH_MAX];
           77         char buf[BUFSIZ], *off;
           78         int fd;
           79         ssize_t n;
           80 
           81         snprintf(path, sizeof(path), "/proc/%d/status", pid);
           82         fd = open(path, O_RDONLY);
           83         if (fd < 0)
           84                 return -1;
           85         n = read(fd, buf, sizeof(buf) - 1);
           86         if (n < 0)
           87                 eprintf("%s: read error:", path);
           88         if (!n) {
           89                 close(fd);
           90                 return -1;
           91         }
           92         buf[n] = '\0';
           93         close(fd);
           94         off = strstr(buf, "Uid:");
           95         if (!off)
           96                 return -1;
           97         sscanf(off, "Uid: %u %u", &pstatus->uid, &pstatus->euid);
           98         off = strstr(buf, "Gid:");
           99         if (!off)
          100                 return -1;
          101         sscanf(off, "Gid: %u %u", &pstatus->gid, &pstatus->egid);
          102         return 0;
          103 }
          104 
          105 int
          106 pidfile(const char *file)
          107 {
          108         char *end;
          109 
          110         errno = 0;
          111         strtol(file, &end, 10);
          112         if (*end != '\0')
          113                 return 0;
          114         if (errno != 0)
          115                 return 0;
          116         return 1;
          117 }