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*47421Sbostic static char *sccsid = "@(#)time.c 5.7 (Berkeley) 03/14/91"; 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; 5025851Slepreau int nval; 511306Sbill 521306Sbill v++, cp = *v++; 5317251Ssam if (cp == 0) 5425851Slepreau nval = 4; 55*47421Sbostic else if (*v == 0 && index("+-", cp[0])) 5625851Slepreau nval = getn(cp); 5728052Slepreau (void) setpriority(PRIO_PROCESS, 0, nval); 581306Sbill } 591306Sbill 6010036Ssam ruadd(ru, ru2) 6110036Ssam register struct rusage *ru, *ru2; 621306Sbill { 6310036Ssam register long *lp, *lp2; 6410036Ssam register int cnt; 651306Sbill 6610036Ssam tvadd(&ru->ru_utime, &ru2->ru_utime); 6710036Ssam tvadd(&ru->ru_stime, &ru2->ru_stime); 6810036Ssam if (ru2->ru_maxrss > ru->ru_maxrss) 6910036Ssam ru->ru_maxrss = ru2->ru_maxrss; 7010036Ssam cnt = &ru->ru_last - &ru->ru_first + 1; 7110036Ssam lp = &ru->ru_first; lp2 = &ru2->ru_first; 7210036Ssam do 7310036Ssam *lp++ += *lp2++; 7410036Ssam while (--cnt > 0); 751306Sbill } 761306Sbill 7710705Ssam prusage(r0, r1, e, b) 7810036Ssam register struct rusage *r0, *r1; 7910705Ssam struct timeval *e, *b; 801306Sbill { 811306Sbill register time_t t = 8210036Ssam (r1->ru_utime.tv_sec-r0->ru_utime.tv_sec)*100+ 8310036Ssam (r1->ru_utime.tv_usec-r0->ru_utime.tv_usec)/10000+ 8410036Ssam (r1->ru_stime.tv_sec-r0->ru_stime.tv_sec)*100+ 8510036Ssam (r1->ru_stime.tv_usec-r0->ru_stime.tv_usec)/10000; 861306Sbill register char *cp; 8731685Sbostic register long i; 881306Sbill register struct varent *vp = adrof("time"); 8931685Sbostic long ms = 9010705Ssam (e->tv_sec-b->tv_sec)*100 + (e->tv_usec-b->tv_usec)/10000; 911306Sbill 921306Sbill cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww"; 931306Sbill if (vp && vp->vec[0] && vp->vec[1]) 941306Sbill cp = vp->vec[1]; 951306Sbill for (; *cp; cp++) 961306Sbill if (*cp != '%') 9734340Sbostic cshputchar(*cp); 981306Sbill else if (cp[1]) switch(*++cp) { 991306Sbill 1001306Sbill case 'U': 10110036Ssam pdeltat(&r1->ru_utime, &r0->ru_utime); 1021306Sbill break; 1031306Sbill 1041306Sbill case 'S': 10510036Ssam pdeltat(&r1->ru_stime, &r0->ru_stime); 1061306Sbill break; 1071306Sbill 1081306Sbill case 'E': 10931685Sbostic psecs(ms / 100); 1101306Sbill break; 1111306Sbill 1121306Sbill case 'P': 11310705Ssam printf("%d%%", (int) (t*100 / ((ms ? ms : 1)))); 1141306Sbill break; 1151306Sbill 1161306Sbill case 'W': 11710036Ssam i = r1->ru_nswap - r0->ru_nswap; 11831685Sbostic printf("%ld", i); 1191306Sbill break; 1201306Sbill 1211306Sbill case 'X': 12231685Sbostic printf("%ld", t == 0 ? 0L : (r1->ru_ixrss-r0->ru_ixrss)/t); 1231306Sbill break; 1241306Sbill 1251306Sbill case 'D': 12631685Sbostic printf("%ld", t == 0 ? 0L : 12710036Ssam (r1->ru_idrss+r1->ru_isrss-(r0->ru_idrss+r0->ru_isrss))/t); 1281306Sbill break; 1291306Sbill 1301306Sbill case 'K': 13131685Sbostic printf("%ld", t == 0 ? 0L : 13210036Ssam ((r1->ru_ixrss+r1->ru_isrss+r1->ru_idrss) - 13310036Ssam (r0->ru_ixrss+r0->ru_idrss+r0->ru_isrss))/t); 1341306Sbill break; 1351306Sbill 1361306Sbill case 'M': 13731685Sbostic printf("%ld", r1->ru_maxrss/2); 1381306Sbill break; 1391306Sbill 1401306Sbill case 'F': 14131685Sbostic printf("%ld", r1->ru_majflt-r0->ru_majflt); 1421306Sbill break; 1431306Sbill 1441306Sbill case 'R': 14531685Sbostic printf("%ld", r1->ru_minflt-r0->ru_minflt); 1461306Sbill break; 1471306Sbill 1481306Sbill case 'I': 14931685Sbostic printf("%ld", r1->ru_inblock-r0->ru_inblock); 1501306Sbill break; 1511306Sbill 1521306Sbill case 'O': 15331685Sbostic printf("%ld", r1->ru_oublock-r0->ru_oublock); 1541306Sbill break; 1551306Sbill } 15634340Sbostic cshputchar('\n'); 1571306Sbill } 15810036Ssam 15910036Ssam pdeltat(t1, t0) 16010036Ssam struct timeval *t1, *t0; 16110036Ssam { 16210036Ssam struct timeval td; 16310036Ssam 16410036Ssam tvsub(&td, t1, t0); 16510036Ssam printf("%d.%01d", td.tv_sec, td.tv_usec/100000); 16610036Ssam } 16710036Ssam 16810036Ssam tvadd(tsum, t0) 16910036Ssam struct timeval *tsum, *t0; 17010036Ssam { 17110036Ssam 17210036Ssam tsum->tv_sec += t0->tv_sec; 17310036Ssam tsum->tv_usec += t0->tv_usec; 17410036Ssam if (tsum->tv_usec > 1000000) 17510036Ssam tsum->tv_sec++, tsum->tv_usec -= 1000000; 17610036Ssam } 17710036Ssam 17810036Ssam tvsub(tdiff, t1, t0) 17910036Ssam struct timeval *tdiff, *t1, *t0; 18010036Ssam { 18110036Ssam 18210036Ssam tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 18310036Ssam tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 18410036Ssam if (tdiff->tv_usec < 0) 18510036Ssam tdiff->tv_sec--, tdiff->tv_usec += 1000000; 18610036Ssam } 187