1: /* @(#)sh.wait.c 2.1 SCCS id keyword */ 2: /* Copyright (c) 1980 Regents of the University of California */ 3: #include "sh.h" 4: #ifdef VMUNIX 5: #include <sys/vtimes.h> 6: struct vtimes zvms; 7: #endif 8: 9: /* 10: * C Shell 11: */ 12: 13: static struct tbuffer { 14: #ifdef V6 15: int put, pst; 16: #else 17: time_t put, pst; 18: #endif 19: time_t cut, cst; 20: } times0; 21: time_t time0; 22: 23: long 24: secs(bef, aft) 25: struct tbuffer *bef, *aft; 26: { 27: 28: return ((aft->cut - bef->cut + aft->cst - bef->cst)); 29: } 30: 31: settimes() 32: { 33: 34: time(&time0); 35: times(×0); 36: } 37: 38: dotime(v, kp) 39: register char **v; 40: struct command *kp; 41: { 42: struct tbuffer timeszer, timesdol, *tzp; 43: time_t timezer, timedol; 44: #ifdef VMUNIX 45: struct vtimes vm0, vm1, vmme; 46: #endif 47: 48: if (v[1] != 0) { 49: time(&timezer), times(×zer); 50: #ifdef VMUNIX 51: vtimes(0, &vm0); 52: #endif 53: lshift(v, 1); 54: if (func(kp) == 0) { 55: timflg = 1; 56: return (0); 57: } 58: tzp = ×zer; 59: #ifdef VMUNIX 60: vmme = zvms; 61: #endif 62: } else { 63: timezer = time0, tzp = ×0; 64: #ifdef VMUNIX 65: vm0 = zvms; 66: vtimes(&vmme, 0); 67: #endif 68: } 69: time(&timedol); 70: times(×dol); 71: #ifdef VMUNIX 72: vtimes(0, &vm1); 73: vmsadd(&vm1, &vmme); 74: #else 75: ptimes(timedol - timezer, tzp, ×dol); 76: #endif 77: #ifdef VMUNIX 78: pvtimes(&vm0, &vm1, timedol - timezer); 79: #endif 80: return (1); 81: } 82: 83: #ifdef VMUNIX 84: vmsadd(vp, wp) 85: register struct vtimes *vp, *wp; 86: { 87: 88: vp->vm_utime += wp->vm_utime; 89: vp->vm_stime += wp->vm_stime; 90: vp->vm_nswap += wp->vm_nswap; 91: vp->vm_idsrss += wp->vm_idsrss; 92: vp->vm_ixrss += wp->vm_ixrss; 93: if (vp->vm_maxrss < wp->vm_maxrss) 94: vp->vm_maxrss = wp->vm_maxrss; 95: vp->vm_majflt += wp->vm_majflt; 96: vp->vm_minflt += wp->vm_minflt; 97: vp->vm_inblk += wp->vm_inblk; 98: vp->vm_oublk += wp->vm_oublk; 99: } 100: #endif 101: 102: donice(v) 103: register char **v; 104: { 105: register char *cp; 106: 107: v++, cp = *v++; 108: if (cp == 0) { 109: /* 110: nice(20); 111: nice(-10); 112: */ 113: nice(4); 114: return (1); 115: } 116: if (*v == 0 && any(cp[0], "+-")) { 117: /* 118: nice(20); 119: nice(-10); 120: */ 121: nice(getn(cp)); 122: return (1); 123: } 124: return (0); 125: } 126: 127: struct tbuffer bef, aft; 128: #ifdef VMUNIX 129: struct vtimes vms; 130: #endif 131: time_t btim, atim; 132: 133: pwait(i) 134: register int i; 135: { 136: register int p, e; 137: char *name; 138: int s; 139: 140: if (i == 0) 141: return; 142: time(&btim); 143: do { 144: times(&bef); 145: #ifndef VMUNIX 146: p = wait(&s); 147: #else 148: p = vwait(&s, &vms); 149: #endif 150: if (p == -1) 151: return; 152: times(&aft); 153: if (p == getn(value("child"))) 154: unsetv("child"); 155: time(&atim); 156: e = s & TRIM; 157: if (e > 0 && (e > 15 || mesg[e])) { 158: if (p != i) 159: printf("%d: ", p); 160: if (name = cname(p)) 161: printf("%s: ", name); 162: if (e <= 15) 163: printf(mesg[e]); 164: else 165: printf("Sig %d", e); 166: if (s & 0200) 167: printf(" -- Core dumped"); 168: printf("\n"); 169: } 170: if (e != 0 && i == p) { 171: cdone(p); 172: if (e == SIGINT && setintr && (!gointr || !eq(gointr, "-"))) 173: pintr(); 174: error(0); 175: } 176: if (i == p) { 177: set("status", putn(e ? e | QUOTE : (s >> 8) & 0377)); 178: if (exiterr && !eq(value("status"), "0")) { 179: if (e == 0) { 180: if (name = cname(p)) 181: printf("%s: ", name); 182: printf("Exit status %s\n", value("status")); 183: } 184: exitstat(); 185: } 186: cdone(p); 187: break; 188: } 189: cdone(p); 190: } while (i != p); 191: if (timflg || (!child && adrof("time") && secs(&bef, &aft) / 60 >= getn(value("time")))) { 192: timflg = 0; 193: #ifndef VMUNIX 194: ptimes(atim - btim, &bef, &aft); 195: #else 196: pvtimes(&zvms, &vms, atim- btim); 197: #endif 198: } 199: } 200: 201: #ifndef VMUNIX 202: ptimes(sec, bef, aft) 203: time_t sec; 204: register struct tbuffer *bef, *aft; 205: { 206: 207: p60ths(aft->cut - bef->cut); 208: printf("u "); 209: p60ths(aft->cst - bef->cst); 210: printf("s "); 211: psecs(sec); 212: printf(" %d%%", (int) ((100 * secs(bef, aft)) / (60 * (sec ? sec : 1)))); 213: #ifndef VMUNIX 214: putchar('\n'); 215: #endif 216: } 217: #endif 218: 219: #ifdef VMUNIX 220: pvtimes(v0, v1, sec) 221: register struct vtimes *v0, *v1; 222: time_t sec; 223: { 224: register time_t t = 225: (v1->vm_utime-v0->vm_utime)+(v1->vm_stime-v0->vm_stime); 226: register char *cp; 227: register int i; 228: register struct varent *vp = adrof("time"); 229: 230: cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 231: if (vp && vp->vec[0] && vp->vec[1]) 232: cp = vp->vec[1]; 233: for (; *cp; cp++) 234: if (*cp != '%') 235: putchar(*cp); 236: else if (cp[1]) switch(*++cp) { 237: 238: case 'U': 239: p60ths(v1->vm_utime - v0->vm_utime); 240: break; 241: 242: case 'S': 243: p60ths(v1->vm_stime - v0->vm_stime); 244: break; 245: 246: case 'E': 247: psecs(sec); 248: break; 249: 250: case 'P': 251: printf("%d%%", (int) ((100 * t) / (60 * (sec ? sec : 1)))); 252: break; 253: 254: case 'W': 255: i = v1->vm_nswap - v0->vm_nswap; 256: printf("%d", i); 257: break; 258: 259: case 'X': 260: printf("%d", t == 0 ? 0 : (v1->vm_ixrss-v0->vm_ixrss)/(2*t)); 261: break; 262: 263: case 'D': 264: printf("%d", t == 0 ? 0 : (v1->vm_idsrss-v0->vm_idsrss)/(2*t)); 265: break; 266: 267: case 'K': 268: printf("%d", t == 0 ? 0 : ((v1->vm_ixrss+v1->vm_idsrss) - 269: (v0->vm_ixrss+v0->vm_idsrss))/(2*t)); 270: break; 271: 272: case 'M': 273: printf("%d", v1->vm_maxrss/2); 274: break; 275: 276: case 'F': 277: printf("%d", v1->vm_majflt-v0->vm_majflt); 278: break; 279: 280: case 'R': 281: printf("%d", v1->vm_minflt-v0->vm_minflt); 282: break; 283: 284: case 'I': 285: printf("%d", v1->vm_inblk-v0->vm_inblk); 286: break; 287: 288: case 'O': 289: printf("%d", v1->vm_oublk-v0->vm_oublk); 290: break; 291: 292: } 293: putchar('\n'); 294: } 295: #endif 296: 297: endwait() 298: { 299: 300: signal(SIGINT, SIG_IGN); 301: cleft(); 302: bferr("Interrupted"); 303: } 304: 305: await() 306: { 307: if (setintr) 308: signal(SIGINT, endwait); 309: pwait(-1); 310: if (setintr) 311: signal(SIGINT, SIG_IGN); 312: } 313: 314: struct achild { 315: int pid; 316: char *cname; 317: struct achild *cnext; 318: } children; 319: 320: char * 321: cname(pid) 322: int pid; 323: { 324: register struct achild *cp; 325: 326: for (cp = children.cnext; cp; cp = cp->cnext) 327: if (cp->pid == pid) 328: return (cp->cname); 329: return (NOSTR); 330: } 331: 332: cadd(pid, cname) 333: int pid; 334: char *cname; 335: { 336: register struct achild *cp = (struct achild *) calloc(1, sizeof (struct achild)); 337: 338: cp->pid = pid; 339: cp->cname = savestr(cname); 340: cp->cnext = children.cnext; 341: children.cnext = cp; 342: } 343: 344: cdone(pid) 345: int pid; 346: { 347: register struct achild *cpp, *cp; 348: 349: cpp = &children; 350: for (cp = cpp->cnext; cp; cp = cp->cnext) { 351: if (cp->pid == pid) { 352: xfree(cp->cname); 353: cpp->cnext = cp->cnext; 354: xfree(cp); 355: return; 356: } 357: cpp = cp; 358: } 359: } 360: 361: cleft() 362: { 363: 364: register struct achild *cp; 365: 366: for (cp = children.cnext; cp; cp = cp->cnext) 367: printf("%6d %s\n", cp->pid, cp->cname); 368: }