ubase

suckless linux base utils
git clone git://git.suckless.org/ubase
Log | Files | Refs | README | 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 }