|
|
1.1 ! root 1: /* ! 2: * stuff concerned with the table ! 3: * of processes we've spawned ! 4: * almost everything in this file should go away; ! 5: * it's needed only to keep /etc/utmp up to date ! 6: */ ! 7: ! 8: #include "mgr.h" ! 9: #include <sys/types.h> ! 10: #include <utmp.h> ! 11: #include <libc.h> ! 12: #include <signal.h> ! 13: #include <wait.h> ! 14: ! 15: typedef struct { ! 16: int pid; ! 17: char *tty; ! 18: char *service; ! 19: } Proc; ! 20: ! 21: #define MAXPROC 1024 ! 22: Proc proc[MAXPROC]; ! 23: Proc *maxproc; ! 24: static int debug=1; ! 25: ! 26: /* ! 27: * make ourselves into a new process ! 28: * returns 0 if we're the parent, or we can't ! 29: * returns 1 in the child ! 30: */ ! 31: newproc(rp) ! 32: Request *rp; ! 33: { ! 34: int pid; ! 35: register Proc *p; ! 36: char *ttyname(), *tty; ! 37: ! 38: /* ! 39: * clean up any utmp entries for incalling tty ! 40: */ ! 41: checkkids(); ! 42: tty = ttyname(rp->i->cfd>=0 ? rp->i->cfd : rp->i->rfd); ! 43: if(tty) ! 44: for (p = proc; p < &proc[MAXPROC]; p++) ! 45: if(p->pid && strcmp(tty, p->tty)==0) ! 46: deadproc(p->pid, 0); ! 47: ! 48: /* ! 49: * create a new process ! 50: */ ! 51: switch(pid=fork()){ ! 52: case -1: ! 53: logevent("can't fork; gave up\n"); ! 54: _ipcabort(0, "", rp->i); ! 55: return(0); ! 56: case 0: ! 57: closesvcs(); ! 58: return (1); ! 59: default: ! 60: break; ! 61: } ! 62: ! 63: _ipcabort(0, "", rp->i); ! 64: if (tty==NULL){ ! 65: if(debug) ! 66: logevent("newproc(%d, non-tty)\n", pid); ! 67: return(0); ! 68: } ! 69: ! 70: /* ! 71: * remember proc so we can take it out of utmp when ! 72: * it dies. ! 73: */ ! 74: for (p = proc; p < &proc[MAXPROC]; p++) ! 75: if(p->pid == 0) { ! 76: if(debug) ! 77: logevent("newproc(%d, %s)\n", pid, tty); ! 78: if ((p->tty = strdup(tty)) != NULL){ ! 79: p->pid = pid; ! 80: p->service = strdup(rp->s->name); ! 81: } ! 82: return (0); ! 83: } ! 84: ! 85: /* too bad */ ! 86: logevent("no internal proc; didn't bother\n"); ! 87: return (0); ! 88: } ! 89: ! 90: /* ! 91: * clean up after any dead children ! 92: */ ! 93: checkkids() ! 94: { ! 95: int pid; ! 96: int status; ! 97: ! 98: for(;;){ ! 99: pid = wait3(&status, WNOHANG, 0); ! 100: if(pid<=0) ! 101: break; ! 102: deadproc(pid, status); ! 103: } ! 104: } ! 105: ! 106: deadproc(pid, status) ! 107: int pid; ! 108: int status; ! 109: { ! 110: register Proc *p; ! 111: int e, t; ! 112: ! 113: if(debug) ! 114: logevent("deadproc(%d, %x)\n", pid, status); ! 115: ! 116: if(pid <= 0) ! 117: logevent("pid == %d: something is wrong\n", pid); ! 118: ! 119: /* ! 120: * see if we have a local record of this process ! 121: */ ! 122: for (p = proc; p < &proc[MAXPROC]; p++) ! 123: if (p->pid == pid) ! 124: break; ! 125: if(p==&proc[MAXPROC]) { ! 126: logevent("non-tty proc %d died\n", pid); ! 127: return; ! 128: } ! 129: ! 130: /* ! 131: * remove any knowledge of this process ! 132: */ ! 133: rmutmp(p->tty); ! 134: p->pid = 0; ! 135: free(p->tty); ! 136: p->tty = 0; ! 137: ! 138: e = (status>>8)&0177; ! 139: t = status&0377; ! 140: if(p->service) { ! 141: if(status){ ! 142: if(t&0200) ! 143: logevent("%s exit(%d) signal(%d) core dumped\n", ! 144: p->service, e, t&~0200); ! 145: else ! 146: logevent("%s exit(%d) signal(%d)\n", p->service, e, t); ! 147: } ! 148: free(p->service); ! 149: } ! 150: } ! 151: ! 152: /* ! 153: * this should really be somewhere else ... ! 154: */ ! 155: ! 156: rmutmp(tty) ! 157: char *tty; ! 158: { ! 159: static struct utmp ut, vt; ! 160: int fd; ! 161: long time(); ! 162: ! 163: if(debug) ! 164: logevent("rmutmp(%s)\n", tty); ! 165: if (strncmp(tty, "/dev/", 5) == 0) ! 166: tty += 5; ! 167: strncpy(vt.ut_line, tty, sizeof(vt.ut_line)); ! 168: vt.ut_time = time((long *)0); ! 169: if ((fd = open("/etc/utmp", 2)) >= 0) { ! 170: while (read(fd, (char *)&ut, sizeof(ut)) == sizeof(ut)) ! 171: if (strncmp(tty, ut.ut_line, sizeof(ut.ut_line)) == 0) { ! 172: lseek(fd, (long)-sizeof(ut), 1); ! 173: write(fd, (char *)&vt, sizeof(vt)); ! 174: break; ! 175: } ! 176: close(fd); ! 177: } ! 178: if ((fd = open("/usr/adm/wtmp", 1)) >= 0) { ! 179: lseek(fd, 0L, 2); ! 180: write(fd, (char *)&vt, sizeof(vt)); ! 181: close(fd); ! 182: } ! 183: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.