1 #include "lib.h" 2 #include "sys9.h" 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 7 8 int _finishing = 0; 9 int _sessleader = 0; 10 11 #define CPIDMAX 100 /* for keeping track of child pids */ 12 static int cpids[CPIDMAX+1]; 13 static int ncpid = 0; 14 static char exitstatus[ERRLEN]; 15 16 static void killcpids(int); 17 18 void 19 _exit(int status) 20 { 21 _finish(status, 0); 22 } 23 24 void 25 _finish(int status, char *term) 26 { 27 int i, nalive; 28 char *cp; 29 30 if(_finishing) 31 _EXITS(exitstatus); 32 _finishing = 1; 33 if(status){ 34 cp = _ultoa(exitstatus, status & 0xFF); 35 *cp = 0; 36 }else if(term){ 37 strncpy(exitstatus, term, ERRLEN); 38 } 39 if(_sessleader) { 40 for(i = 0, nalive=0; i < ncpid; i++) 41 if(cpids[i]) 42 nalive++; 43 if(nalive) 44 killcpids(nalive); 45 } 46 _EXITS(exitstatus); 47 } 48 49 /* 50 * register a child pid; will be hup'd on exit or termination 51 * if pid < 0, just clear the table (done on fork) 52 */ 53 54 void 55 _newcpid(int pid) 56 { 57 int i; 58 59 if(pid < 0){ 60 ncpid = 0; 61 }else{ 62 for(i = 0; i < ncpid; i++) 63 if(cpids[i] == 0) { 64 cpids[i] = pid; 65 return; 66 } 67 if(ncpid < CPIDMAX) 68 cpids[ncpid++] = pid; 69 } 70 } 71 72 void 73 _delcpid(int pid) 74 { 75 int i; 76 77 for(i = 0; i < ncpid; i++) 78 if(cpids[i] == pid) { 79 cpids[i] = 0; 80 if(i == ncpid-1) 81 ncpid--; 82 return; 83 } 84 } 85 86 /* 87 * What a pain this is. Children might not die because 88 * we're still here. So fork to get an independent 89 * child, and use it to kill everyone 90 */ 91 static void 92 killcpids(int nalive) 93 { 94 int i, p, fd, niters, wpid; 95 Waitmsg w; 96 char buf[100]; 97 char *cp; 98 99 for(i = 0; i<OPEN_MAX; i++) 100 _CLOSE(i); 101 cpids[ncpid++] = getpid(); /* kill ourselves, too */ 102 nalive++; 103 i = _RFORK(FORKPCS|FORKFDG|FORKNOW); 104 if(i > 0) 105 return; 106 107 for(niters=0; nalive > 0 && niters < 5; niters++){ 108 for(i = 0; i < ncpid; i++){ 109 if(!cpids[i]) 110 continue; 111 strcpy(buf, "/proc/"); 112 cp = _ultoa(buf+6, cpids[i]); 113 strcpy(cp, "/note"); 114 fd = _OPEN(buf, 1); 115 if(fd >= 0){ 116 if(_WRITE(fd, "hangup", 6) < 0){ 117 cpids[i] = 0; 118 nalive--; 119 } 120 _CLOSE(fd); 121 }else{ 122 cpids[i] = 0; 123 nalive--; 124 } 125 } 126 } 127 } 128 129 /* emulate: return p+sprintf(p, "%uld", v) */ 130 #define IDIGIT 15 131 char * 132 _ultoa(char *p, unsigned long v) 133 { 134 char s[IDIGIT]; 135 int n, i; 136 137 s[IDIGIT-1] = 0; 138 for(i = IDIGIT-2; i; i--){ 139 n = v % 10; 140 s[i] = n + '0'; 141 v = v / 10; 142 if(v == 0) 143 break; 144 } 145 strcpy(p, s+i); 146 return p + (IDIGIT-1-i); 147 } 148