plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

proc.c (3813B)


      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 
     10 static void install(int);
     11 
     12 void
     13 sproc(int xpid)
     14 {
     15 	Lsym *s;
     16 	int i;
     17 	Regs *regs;
     18 
     19 	if(symmap == 0)
     20 		error("no map");
     21 
     22 	if(pid == xpid)
     23 		return;
     24 
     25 	if(corhdr){
     26 		regs = coreregs(corhdr, xpid);
     27 		if(regs == nil)
     28 			error("no such pid in core dump");
     29 		free(correg);
     30 		correg = regs;
     31 	}else{
     32 		/* XXX should only change register set here if cormap already mapped */
     33 		if(xpid <= 0)
     34 			error("bad pid");
     35 		unmapproc(cormap);
     36 		unmapfile(corhdr, cormap);
     37 		free(correg);
     38 		correg = nil;
     39 		pid = -1;
     40 		corpid = -1;
     41 
     42 		if(mapproc(xpid, cormap, &correg) < 0)
     43 			error("setproc %d: %r", xpid);
     44 
     45 		/* XXX check text file here? */
     46 
     47 		for(i=0; i<cormap->nseg; i++){
     48 			if(cormap->seg[i].file == nil){
     49 				if(strcmp(cormap->seg[i].name, "data") == 0)
     50 					cormap->seg[i].name = "*data";
     51 				if(strcmp(cormap->seg[i].name, "text") == 0)
     52 					cormap->seg[i].name = "*text";
     53 			}
     54 		}
     55 	}
     56 	pid = xpid;
     57 	corpid = pid;
     58 	s = look("pid");
     59 	s->v->store.u.ival = pid;
     60 
     61 	install(pid);
     62 }
     63 
     64 int
     65 nproc(char **argv)
     66 {
     67 	int pid, i;
     68 
     69 	pid = fork();
     70 	switch(pid) {
     71 	case -1:
     72 		error("new: fork %r");
     73 	case 0:
     74 		rfork(RFNAMEG|RFNOTEG);
     75 		if(ctlproc(getpid(), "hang") < 0)
     76 			fatal("new: hang %d: %r", getpid());
     77 
     78 		close(0);
     79 		close(1);
     80 		close(2);
     81 		for(i = 3; i < NFD; i++)
     82 			close(i);
     83 
     84 		open("/dev/tty", OREAD);
     85 		open("/dev/tty", OWRITE);
     86 		open("/dev/tty", OWRITE);
     87 		execv(argv[0], argv);
     88 		fatal("new: exec %s: %r", argv[0]);
     89 	default:
     90 		install(pid);
     91 		msg(pid, "attached");
     92 		msg(pid, "waitstop");
     93 		notes(pid);
     94 		sproc(pid);
     95 		dostop(pid);
     96 		break;
     97 	}
     98 
     99 	return pid;
    100 }
    101 
    102 void
    103 notes(int pid)
    104 {
    105 	Lsym *s;
    106 	Value *v;
    107 	int i, n;
    108 	char **notes;
    109 	List *l, **tail;
    110 
    111 	s = look("notes");
    112 	if(s == 0)
    113 		return;
    114 
    115 	v = s->v;
    116 	n = procnotes(pid, &notes);
    117 	if(n < 0)
    118 		error("procnotes pid=%d: %r", pid);
    119 
    120 	v->set = 1;
    121 	v->type = TLIST;
    122 	v->store.u.l = 0;
    123 	tail = &v->store.u.l;
    124 	for(i=0; i<n; i++) {
    125 		l = al(TSTRING);
    126 		l->store.u.string = strnode(notes[i]);
    127 		l->store.fmt = 's';
    128 		*tail = l;
    129 		tail = &l->next;
    130 	}
    131 	free(notes);
    132 }
    133 
    134 void
    135 dostop(int pid)
    136 {
    137 	Lsym *s;
    138 	Node *np, *p;
    139 
    140 	s = look("stopped");
    141 	if(s && s->proc) {
    142 		np = an(ONAME, ZN, ZN);
    143 		np->sym = s;
    144 		np->store.fmt = 'D';
    145 		np->type = TINT;
    146 		p = con(pid);
    147 		p->store.fmt = 'D';
    148 		np = an(OCALL, np, p);
    149 		execute(np);
    150 	}
    151 }
    152 
    153 static void
    154 install(int pid)
    155 {
    156 	Lsym *s;
    157 	List *l;
    158 	int i, new, p;
    159 
    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 
    171 	ptab[new].pid = pid;
    172 
    173 	s = look("proclist");
    174 	l = al(TINT);
    175 	l->store.fmt = 'D';
    176 	l->store.u.ival = pid;
    177 	l->next = s->v->store.u.l;
    178 	s->v->store.u.l = l;
    179 	s->v->set = 1;
    180 }
    181 
    182 /*
    183 static int
    184 installed(int pid)
    185 {
    186 	int i;
    187 
    188 	for(i=0; i<Maxproc; i++)
    189 		if(ptab[i].pid == pid)
    190 			return 1;
    191 	return 0;
    192 }
    193 */
    194 
    195 void
    196 deinstall(int pid)
    197 {
    198 	int i;
    199 	Lsym *s;
    200 	List *f, **d;
    201 
    202 	for(i = 0; i < Maxproc; i++) {
    203 		if(ptab[i].pid == pid) {
    204 			detachproc(pid);
    205 			/* close(ptab[i].ctl); */
    206 			ptab[i].pid = 0;
    207 			s = look("proclist");
    208 			d = &s->v->store.u.l;
    209 			for(f = *d; f; f = f->next) {
    210 				if(f->store.u.ival == pid) {
    211 					*d = f->next;
    212 					break;
    213 				}
    214 			}
    215 			s = look("pid");
    216 			if(s->v->store.u.ival == pid)
    217 				s->v->store.u.ival = 0;
    218 			return;
    219 		}
    220 	}
    221 }
    222 
    223 void
    224 msg(int pid, char *msg)
    225 {
    226 	int i;
    227 	char err[ERRMAX];
    228 
    229 	for(i = 0; i < Maxproc; i++) {
    230 		if(ptab[i].pid == pid) {
    231 			if(ctlproc(pid, msg) < 0){
    232 				errstr(err, sizeof err);
    233 				if(strcmp(err, "process exited") == 0)
    234 					deinstall(pid);
    235 				error("msg: pid=%d %s: %s", pid, msg, err);
    236 			}
    237 			return;
    238 		}
    239 	}
    240 	error("msg: pid=%d: not found for %s", pid, msg);
    241 }
    242 
    243 char *
    244 getstatus(int pid)
    245 {
    246 	return "unknown";
    247 }