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