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