proc.c 2.3 KB

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