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 "../proc.h"
 13#include "../util.h"
 14
 15int
 16parsecmdline(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
 44int
 45parsestat(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
 73int
 74parsestatus(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
105int
106pidfile(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}