121943Sdist /* 221943Sdist * Copyright (c) 1980 Regents of the University of California. 322536Sedward * All rights reserved. The Berkeley Software License Agreement 421943Sdist * specifies the terms and conditions for redistribution. 521943Sdist */ 621943Sdist 714476Ssam #ifndef lint 8*25851Slepreau static char *sccsid = "@(#)time.c 5.3 (Berkeley) 01/12/86"; 922536Sedward #endif 101306Sbill 111306Sbill #include "sh.h" 121306Sbill 131306Sbill /* 141306Sbill * C Shell - routines handling process timing and niceing 151306Sbill */ 161306Sbill 171306Sbill settimes() 181306Sbill { 1910036Ssam struct rusage ruch; 201306Sbill 2117508Sedward (void) gettimeofday(&time0, (struct timezone *)0); 2217508Sedward (void) getrusage(RUSAGE_SELF, &ru0); 2317508Sedward (void) getrusage(RUSAGE_CHILDREN, &ruch); 2410036Ssam ruadd(&ru0, &ruch); 251306Sbill } 261306Sbill 271306Sbill /* 281306Sbill * dotime is only called if it is truly a builtin function and not a 291306Sbill * prefix to another command 301306Sbill */ 311306Sbill dotime() 321306Sbill { 3310705Ssam struct timeval timedol; 3410036Ssam struct rusage ru1, ruch; 351306Sbill 3617508Sedward (void) getrusage(RUSAGE_SELF, &ru1); 3717508Sedward (void) getrusage(RUSAGE_CHILDREN, &ruch); 3810036Ssam ruadd(&ru1, &ruch); 3917508Sedward (void) gettimeofday(&timedol, (struct timezone *)0); 4010705Ssam prusage(&ru0, &ru1, &timedol, &time0); 411306Sbill } 421306Sbill 431306Sbill /* 441306Sbill * donice is only called when it on the line by itself or with a +- value 451306Sbill */ 461306Sbill donice(v) 471306Sbill register char **v; 481306Sbill { 491306Sbill register char *cp; 50*25851Slepreau int nval; 511306Sbill 521306Sbill v++, cp = *v++; 5317251Ssam if (cp == 0) 54*25851Slepreau nval = 4; 5517251Ssam else if (*v == 0 && any(cp[0], "+-")) 56*25851Slepreau nval = getn(cp); 57*25851Slepreau (void) setpriority(PRIO_PROCESS, 0, 58*25851Slepreau getpriority(PRIO_PROCESS, 0) + nval); 591306Sbill } 601306Sbill 6110036Ssam ruadd(ru, ru2) 6210036Ssam register struct rusage *ru, *ru2; 631306Sbill { 6410036Ssam register long *lp, *lp2; 6510036Ssam register int cnt; 661306Sbill 6710036Ssam tvadd(&ru->ru_utime, &ru2->ru_utime); 6810036Ssam tvadd(&ru->ru_stime, &ru2->ru_stime); 6910036Ssam if (ru2->ru_maxrss > ru->ru_maxrss) 7010036Ssam ru->ru_maxrss = ru2->ru_maxrss; 7110036Ssam cnt = &ru->ru_last - &ru->ru_first + 1; 7210036Ssam lp = &ru->ru_first; lp2 = &ru2->ru_first; 7310036Ssam do 7410036Ssam *lp++ += *lp2++; 7510036Ssam while (--cnt > 0); 761306Sbill } 771306Sbill 7810705Ssam prusage(r0, r1, e, b) 7910036Ssam register struct rusage *r0, *r1; 8010705Ssam struct timeval *e, *b; 811306Sbill { 821306Sbill register time_t t = 8310036Ssam (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ 8410036Ssam (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ 8510036Ssam (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ 8610036Ssam (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; 871306Sbill register char *cp; 881306Sbill register int i; 891306Sbill register struct varent *vp = adrof("time"); 9010705Ssam int ms = 9110705Ssam (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000; 921306Sbill 931306Sbill cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 941306Sbill if (vp && vp->vec[0] && vp->vec[1]) 951306Sbill cp = vp->vec[1]; 961306Sbill for (; *cp; cp++) 971306Sbill if (*cp != '%') 981306Sbill putchar(*cp); 991306Sbill else if (cp[1]) switch(*++cp) { 1001306Sbill 1011306Sbill case 'U': 10210036Ssam pdeltat(&r1->ru_utime, &r0->ru_utime); 1031306Sbill break; 1041306Sbill 1051306Sbill case 'S': 10610036Ssam pdeltat(&r1->ru_stime, &r0->ru_stime); 1071306Sbill break; 1081306Sbill 1091306Sbill case 'E': 11017508Sedward psecs((long)(ms / 100)); 1111306Sbill break; 1121306Sbill 1131306Sbill case 'P': 11410705Ssam printf("%d%%", (int) (t*100 / ((ms ? ms : 1)))); 1151306Sbill break; 1161306Sbill 1171306Sbill case 'W': 11810036Ssam i = r1->ru_nswap - r0->ru_nswap; 1191306Sbill printf("%d", i); 1201306Sbill break; 1211306Sbill 1221306Sbill case 'X': 12310036Ssam printf("%d", t == 0 ? 0 : (r1->ru_ixrss-r0->ru_ixrss)/t); 1241306Sbill break; 1251306Sbill 1261306Sbill case 'D': 12710036Ssam printf("%d", t == 0 ? 0 : 12810036Ssam (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); 1291306Sbill break; 1301306Sbill 1311306Sbill case 'K': 13210036Ssam printf("%d", t == 0 ? 0 : 13310036Ssam ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - 13410036Ssam (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); 1351306Sbill break; 1361306Sbill 1371306Sbill case 'M': 13810036Ssam printf("%d", r1->ru_maxrss/2); 1391306Sbill break; 1401306Sbill 1411306Sbill case 'F': 14210036Ssam printf("%d", r1->ru_majflt-r0->ru_majflt); 1431306Sbill break; 1441306Sbill 1451306Sbill case 'R': 14610036Ssam printf("%d", r1->ru_minflt-r0->ru_minflt); 1471306Sbill break; 1481306Sbill 1491306Sbill case 'I': 15010036Ssam printf("%d", r1->ru_inblock-r0->ru_inblock); 1511306Sbill break; 1521306Sbill 1531306Sbill case 'O': 15410036Ssam printf("%d", r1->ru_oublock-r0->ru_oublock); 1551306Sbill break; 1561306Sbill } 1571306Sbill putchar('\n'); 1581306Sbill } 15910036Ssam 16010036Ssam pdeltat(t1, t0) 16110036Ssam struct timeval *t1, *t0; 16210036Ssam { 16310036Ssam struct timeval td; 16410036Ssam 16510036Ssam tvsub(&td, t1, t0); 16610036Ssam printf("%d.%01d", td.tv_sec, td.tv_usec/100000); 16710036Ssam } 16810036Ssam 16910036Ssam tvadd(tsum, t0) 17010036Ssam struct timeval *tsum, *t0; 17110036Ssam { 17210036Ssam 17310036Ssam tsum->tv_sec += t0->tv_sec; 17410036Ssam tsum->tv_usec += t0->tv_usec; 17510036Ssam if (tsum->tv_usec > 1000000) 17610036Ssam tsum->tv_sec++, tsum->tv_usec -= 1000000; 17710036Ssam } 17810036Ssam 17910036Ssam tvsub(tdiff, t1, t0) 18010036Ssam struct timeval *tdiff, *t1, *t0; 18110036Ssam { 18210036Ssam 18310036Ssam tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 18410036Ssam tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 18510036Ssam if (tdiff->tv_usec < 0) 18610036Ssam tdiff->tv_sec--, tdiff->tv_usec += 1000000; 18710036Ssam } 188