proc.c 4.2 KB

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