proc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <ctype.h>
  5. #include <mach.h>
  6. #define Extern extern
  7. #include "acid.h"
  8. #include "y.tab.h"
  9. static void install(int);
  10. void
  11. nocore(void)
  12. {
  13. int i;
  14. if(cormap == 0)
  15. return;
  16. for (i = 0; i < cormap->nsegs; i++)
  17. if (cormap->seg[i].inuse && cormap->seg[i].fd >= 0)
  18. close(cormap->seg[i].fd);
  19. free(cormap);
  20. cormap = 0;
  21. }
  22. void
  23. sproc(int pid)
  24. {
  25. Lsym *s;
  26. char buf[64];
  27. ulong proctab;
  28. int fd, i, fcor;
  29. if(symmap == 0)
  30. error("no map");
  31. sprint(buf, "/proc/%d/mem", pid);
  32. fcor = open(buf, ORDWR);
  33. if(fcor < 0)
  34. error("setproc: open %s: %r", buf);
  35. checkqid(symmap->seg[0].fd, pid);
  36. if(kernel) {
  37. proctab = 0;
  38. sprint(buf, "/proc/%d/proc", pid);
  39. fd = open(buf, OREAD);
  40. if(fd >= 0) {
  41. i = read(fd, buf, sizeof(buf));
  42. if(i >= 0) {
  43. buf[i] = '\0';
  44. proctab = strtoul(buf, 0, 0);
  45. }
  46. close(fd);
  47. }
  48. s = look("proc");
  49. if(s != 0)
  50. s->v->ival = proctab;
  51. }
  52. s = look("pid");
  53. s->v->ival = pid;
  54. nocore();
  55. cormap = attachproc(pid, kernel, fcor, &fhdr);
  56. if (cormap == 0)
  57. error("setproc: can't make coremap: %r");
  58. i = findseg(cormap, "text");
  59. if (i > 0)
  60. cormap->seg[i].name = "*text";
  61. i = findseg(cormap, "data");
  62. if (i > 0)
  63. cormap->seg[i].name = "*data";
  64. install(pid);
  65. }
  66. int
  67. nproc(char **argv)
  68. {
  69. char buf[128];
  70. int pid, i, fd;
  71. pid = fork();
  72. switch(pid) {
  73. case -1:
  74. error("new: fork %r");
  75. case 0:
  76. rfork(RFNAMEG|RFNOTEG);
  77. sprint(buf, "/proc/%d/ctl", getpid());
  78. fd = open(buf, ORDWR);
  79. if(fd < 0)
  80. fatal("new: open %s: %r", buf);
  81. write(fd, "hang", 4);
  82. close(fd);
  83. close(0);
  84. close(1);
  85. close(2);
  86. for(i = 3; i < NFD; i++)
  87. close(i);
  88. open("/dev/cons", OREAD);
  89. open("/dev/cons", OWRITE);
  90. open("/dev/cons", OWRITE);
  91. exec(argv[0], argv);
  92. fatal("new: exec %s: %r");
  93. default:
  94. install(pid);
  95. msg(pid, "waitstop");
  96. notes(pid);
  97. sproc(pid);
  98. dostop(pid);
  99. break;
  100. }
  101. return pid;
  102. }
  103. void
  104. notes(int pid)
  105. {
  106. Lsym *s;
  107. Value *v;
  108. int i, fd;
  109. char buf[128];
  110. List *l, **tail;
  111. s = look("notes");
  112. if(s == 0)
  113. return;
  114. v = s->v;
  115. sprint(buf, "/proc/%d/note", pid);
  116. fd = open(buf, OREAD);
  117. if(fd < 0)
  118. error("pid=%d: open note: %r", pid);
  119. v->set = 1;
  120. v->type = TLIST;
  121. v->l = 0;
  122. tail = &v->l;
  123. for(;;) {
  124. i = read(fd, buf, sizeof(buf));
  125. if(i <= 0)
  126. break;
  127. buf[i] = '\0';
  128. l = al(TSTRING);
  129. l->string = strnode(buf);
  130. l->fmt = 's';
  131. *tail = l;
  132. tail = &l->next;
  133. }
  134. close(fd);
  135. }
  136. void
  137. dostop(int pid)
  138. {
  139. Lsym *s;
  140. Node *np, *p;
  141. s = look("stopped");
  142. if(s && s->proc) {
  143. np = an(ONAME, ZN, ZN);
  144. np->sym = s;
  145. np->fmt = 'D';
  146. np->type = TINT;
  147. p = con(pid);
  148. p->fmt = 'D';
  149. np = an(OCALL, np, p);
  150. execute(np);
  151. }
  152. }
  153. static void
  154. install(int pid)
  155. {
  156. Lsym *s;
  157. List *l;
  158. char buf[128];
  159. int i, fd, new, p;
  160. new = -1;
  161. for(i = 0; i < Maxproc; i++) {
  162. p = ptab[i].pid;
  163. if(p == pid)
  164. return;
  165. if(p == 0 && new == -1)
  166. new = i;
  167. }
  168. if(new == -1)
  169. error("no free process slots");
  170. sprint(buf, "/proc/%d/ctl", pid);
  171. fd = open(buf, OWRITE);
  172. if(fd < 0)
  173. error("pid=%d: open ctl: %r", pid);
  174. ptab[new].pid = pid;
  175. ptab[new].ctl = fd;
  176. s = look("proclist");
  177. l = al(TINT);
  178. l->fmt = 'D';
  179. l->ival = pid;
  180. l->next = s->v->l;
  181. s->v->l = l;
  182. s->v->set = 1;
  183. }
  184. void
  185. deinstall(int pid)
  186. {
  187. int i;
  188. Lsym *s;
  189. List *f, **d;
  190. for(i = 0; i < Maxproc; i++) {
  191. if(ptab[i].pid == pid) {
  192. close(ptab[i].ctl);
  193. ptab[i].pid = 0;
  194. s = look("proclist");
  195. d = &s->v->l;
  196. for(f = *d; f; f = f->next) {
  197. if(f->ival == pid) {
  198. *d = f->next;
  199. break;
  200. }
  201. }
  202. s = look("pid");
  203. if(s->v->ival == pid)
  204. s->v->ival = 0;
  205. return;
  206. }
  207. }
  208. }
  209. void
  210. msg(int pid, char *msg)
  211. {
  212. int i;
  213. int l;
  214. char err[ERRMAX];
  215. for(i = 0; i < Maxproc; i++) {
  216. if(ptab[i].pid == pid) {
  217. l = strlen(msg);
  218. if(write(ptab[i].ctl, msg, l) != l) {
  219. errstr(err, sizeof err);
  220. if(strcmp(err, "process exited") == 0)
  221. deinstall(pid);
  222. error("msg: pid=%d %s: %s", pid, msg, err);
  223. }
  224. return;
  225. }
  226. }
  227. error("msg: pid=%d: not found for %s", pid, msg);
  228. }
  229. char *
  230. getstatus(int pid)
  231. {
  232. int fd, n;
  233. char *argv[16], buf[64];
  234. static char status[128];
  235. sprint(buf, "/proc/%d/status", pid);
  236. fd = open(buf, OREAD);
  237. if(fd < 0)
  238. error("open %s: %r", buf);
  239. n = read(fd, status, sizeof(status)-1);
  240. close(fd);
  241. if(n <= 0)
  242. error("read %s: %r", buf);
  243. status[n] = '\0';
  244. if(tokenize(status, argv, nelem(argv)-1) < 3)
  245. error("tokenize %s: %r", buf);
  246. return argv[2];
  247. }
  248. Waitmsg*
  249. waitfor(int pid)
  250. {
  251. Waitmsg *w;
  252. for(;;) {
  253. if((w = wait()) == nil)
  254. error("wait %r");
  255. if(w->pid == pid)
  256. return w;
  257. free(w);
  258. }
  259. return nil; /* ken */
  260. }