ps.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2013 Kevin Lange
  5. *
  6. * ps
  7. *
  8. * print a list of running processes
  9. */
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <stdint.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <syscall.h>
  17. #include <unistd.h>
  18. #include <dirent.h>
  19. #include <pwd.h>
  20. #include <toaru/list.h>
  21. #define LINE_LEN 4096
  22. static int show_all = 0;
  23. void print_username(int uid) {
  24. struct passwd * p = getpwuid(uid);
  25. if (p) {
  26. printf("%-8s", p->pw_name);
  27. } else {
  28. printf("%-8d", uid);
  29. }
  30. endpwent();
  31. }
  32. void print_entry(struct dirent * dent) {
  33. char tmp[256], buf[4096];
  34. FILE * f;
  35. int read = 1;
  36. char line[LINE_LEN];
  37. int pid, uid, tgid;
  38. char name[100];
  39. sprintf(tmp, "/proc/%s/status", dent->d_name);
  40. f = fopen(tmp, "r");
  41. if (!f) {
  42. return;
  43. }
  44. line[0] = 0;
  45. while (fgets(line, LINE_LEN, f) != NULL) {
  46. char * n = strstr(line,"\n");
  47. if (n) { *n = '\0'; }
  48. char * tab = strstr(line,"\t");
  49. if (tab) {
  50. *tab = '\0';
  51. tab++;
  52. }
  53. if (strstr(line, "Pid:") == line) {
  54. pid = atoi(tab);
  55. } else if (strstr(line, "Uid:") == line) {
  56. uid = atoi(tab);
  57. } else if (strstr(line, "Tgid:") == line) {
  58. tgid = atoi(tab);
  59. } else if (strstr(line, "Name:") == line) {
  60. strcpy(name, tab);
  61. }
  62. }
  63. fclose(f);
  64. if ((tgid != pid) && !show_all) {
  65. /* Skip threads */
  66. return;
  67. }
  68. print_username(uid);
  69. if (show_all) {
  70. printf("%5d.%-5d", tgid, pid);
  71. } else {
  72. printf(" %5d", pid);
  73. }
  74. printf(" ");
  75. sprintf(tmp, "/proc/%s/cmdline", dent->d_name);
  76. f = fopen(tmp, "r");
  77. memset(buf, 0x00, 4096);
  78. read = fread(buf, 1, 4096, f);
  79. fclose(f);
  80. buf[read] = '\0';
  81. for (int i = 0; i < read; ++i) {
  82. if (buf[i] == '\036') {
  83. buf[i] = ' ';
  84. }
  85. }
  86. if (tgid != pid) {
  87. printf("{%s}\n", buf);
  88. } else {
  89. printf("%s\n", buf);
  90. }
  91. }
  92. void show_usage(int argc, char * argv[]) {
  93. printf(
  94. "ps - list running processes\n"
  95. "\n"
  96. "usage: %s [-A] [format]\n"
  97. "\n"
  98. " -A \033[3mignored\033[0m\n"
  99. " -? \033[3mshow this help text\033[0m\n"
  100. "\n", argv[0]);
  101. }
  102. int main (int argc, char * argv[]) {
  103. /* Parse arguments */
  104. if (argc > 1) {
  105. for (int i = 1; i < argc; ++i) {
  106. if (argv[i][0] == '-') {
  107. char *c = &argv[i][1];
  108. while (*c) {
  109. switch (*c) {
  110. case 'A':
  111. show_all = 1;
  112. break;
  113. case '?':
  114. show_usage(argc, argv);
  115. return 0;
  116. }
  117. c++;
  118. }
  119. }
  120. }
  121. }
  122. /* Open the directory */
  123. DIR * dirp = opendir("/proc");
  124. /* Read the entries in the directory */
  125. list_t * ents_list = list_create();
  126. struct dirent * ent = readdir(dirp);
  127. while (ent != NULL) {
  128. if (ent->d_name[0] >= '0' && ent->d_name[0] <= '9') {
  129. struct dirent * entcpy = malloc(sizeof(struct dirent));
  130. memcpy(entcpy, ent, sizeof(struct dirent));
  131. list_insert(ents_list, (void *)entcpy);
  132. }
  133. ent = readdir(dirp);
  134. }
  135. closedir(dirp);
  136. foreach(entry, ents_list) {
  137. print_entry(entry->value);
  138. }
  139. return 0;
  140. }
  141. /*
  142. * vim: tabstop=4
  143. * vim: shiftwidth=4
  144. * vim: noexpandtab
  145. */