1 0 stevel /* 2 356 muffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 0 stevel * Use is subject to license terms. 4 0 stevel */ 5 0 stevel 6 0 stevel /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7 0 stevel /* All Rights Reserved */ 8 0 stevel 9 0 stevel /* 10 0 stevel * Copyright (c) 1980 Regents of the University of California. 11 0 stevel * All rights reserved. The Berkeley Software License Agreement 12 0 stevel * specifies the terms and conditions for redistribution. 13 0 stevel */ 14 0 stevel 15 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 16 0 stevel 17 0 stevel #include "sh.h" 18 0 stevel #include "sh.tconst.h" 19 0 stevel 20 0 stevel void ruadd(struct rusage *ru, struct rusage *ru2); 21 0 stevel void prusage(struct rusage *r0, struct rusage *r1, struct timeval *e, 22 0 stevel struct timeval *b); 23 0 stevel void pdeltat(struct timeval *t1, struct timeval *t0); 24 0 stevel void tvadd(struct timeval *tsum, struct timeval *t0); 25 0 stevel void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0); 26 0 stevel 27 0 stevel /* 28 0 stevel * C Shell - routines handling process timing and niceing 29 0 stevel */ 30 0 stevel 31 0 stevel void 32 356 muffin settimes(void) 33 0 stevel { 34 0 stevel struct rusage ruch; 35 0 stevel 36 0 stevel #ifdef TRACE 37 0 stevel tprintf("TRACE- settimes()\n"); 38 0 stevel #endif 39 0 stevel (void) gettimeofday(&time0, (struct timezone *)0); 40 0 stevel (void) getrusage(RUSAGE_SELF, &ru0); 41 0 stevel (void) getrusage(RUSAGE_CHILDREN, &ruch); 42 0 stevel ruadd(&ru0, &ruch); 43 0 stevel } 44 0 stevel 45 0 stevel /* 46 0 stevel * dotime is only called if it is truly a builtin function and not a 47 0 stevel * prefix to another command 48 0 stevel */ 49 0 stevel void 50 356 muffin dotime(void) 51 0 stevel { 52 0 stevel struct timeval timedol; 53 0 stevel struct rusage ru1, ruch; 54 0 stevel 55 0 stevel #ifdef TRACE 56 0 stevel tprintf("TRACE- dotime()\n"); 57 0 stevel #endif 58 0 stevel (void) getrusage(RUSAGE_SELF, &ru1); 59 0 stevel (void) getrusage(RUSAGE_CHILDREN, &ruch); 60 0 stevel ruadd(&ru1, &ruch); 61 0 stevel (void) gettimeofday(&timedol, (struct timezone *)0); 62 0 stevel prusage(&ru0, &ru1, &timedol, &time0); 63 0 stevel } 64 0 stevel 65 0 stevel /* 66 0 stevel * donice is only called when it's on the line by itself or with a +- value 67 0 stevel */ 68 0 stevel void 69 0 stevel donice(tchar **v) 70 0 stevel { 71 0 stevel tchar *cp; 72 0 stevel int nval; 73 0 stevel 74 0 stevel #ifdef TRACE 75 0 stevel tprintf("TRACE- donice()\n"); 76 0 stevel #endif 77 0 stevel v++; 78 0 stevel cp = *v++; 79 0 stevel if (cp == 0) { 80 0 stevel nval = 4; 81 0 stevel } else if (*v == 0 && (cp[0] == '+' || cp[0] == '-')) { 82 0 stevel nval = getn(cp); 83 0 stevel } 84 0 stevel (void) setpriority(PRIO_PROCESS, 0, nval); 85 0 stevel } 86 0 stevel 87 0 stevel void 88 0 stevel ruadd(struct rusage *ru, struct rusage *ru2) 89 0 stevel { 90 0 stevel long *lp, *lp2; 91 0 stevel int cnt; 92 0 stevel /* 93 0 stevel * The SunOS 4.x <sys/rusage.h> has ru_first and ru_last #defines 94 0 stevel * as below. 95 0 stevel * The SVR4/POSIX <sys/resource.h> does not have these defined for 96 0 stevel * struct rusage 97 0 stevel * The #defines below are here so that the original csh logic 98 0 stevel * for ruadd remains clear now that there is no longer a private copy 99 0 stevel * of the old <sys/resource.h> 100 0 stevel */ 101 0 stevel #define ru_first ru_ixrss 102 0 stevel #define ru_last ru_nivcsw 103 0 stevel 104 0 stevel #ifdef TRACE 105 0 stevel tprintf("TRACE- ruadd()\n"); 106 0 stevel #endif 107 0 stevel tvadd(&ru->ru_utime, &ru2->ru_utime); 108 0 stevel tvadd(&ru->ru_stime, &ru2->ru_stime); 109 0 stevel if (ru2->ru_maxrss > ru->ru_maxrss) { 110 0 stevel ru->ru_maxrss = ru2->ru_maxrss; 111 0 stevel } 112 0 stevel cnt = &ru->ru_last - &ru->ru_first + 1; 113 0 stevel lp = &ru->ru_first; 114 0 stevel lp2 = &ru2->ru_first; 115 0 stevel do { 116 0 stevel *lp++ += *lp2++; 117 0 stevel } while (--cnt > 0); 118 0 stevel } 119 0 stevel 120 0 stevel void 121 0 stevel prusage(struct rusage *r0, struct rusage *r1, struct timeval *e, 122 0 stevel struct timeval *b) 123 0 stevel { 124 0 stevel #define pgtok(p) ((p * pgsize) / 1024) 125 0 stevel static int pgsize; 126 0 stevel 127 0 stevel time_t t = 128 0 stevel (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 + 129 0 stevel (r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 + 130 0 stevel (r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 + 131 0 stevel (r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000; 132 0 stevel tchar *cp; 133 0 stevel int i; 134 0 stevel struct varent *vp = adrof(S_time); 135 0 stevel int ms = 136 0 stevel (e->tv_sec - b->tv_sec) * 100 + (e->tv_usec - b->tv_usec) / 10000; 137 0 stevel 138 0 stevel #ifdef TRACE 139 0 stevel tprintf("TRACE- prusage()\n"); 140 0 stevel #endif 141 0 stevel if (pgsize == 0) { 142 0 stevel pgsize = getpagesize(); 143 0 stevel } 144 0 stevel 145 0 stevel cp = S_USAGEFORMAT; /* "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww" */ 146 0 stevel if (vp && vp->vec[0] && vp->vec[1]) { 147 0 stevel cp = vp->vec[1]; 148 0 stevel } 149 0 stevel for (; *cp; cp++) { 150 0 stevel if (*cp != '%') { 151 0 stevel Putchar(*cp); 152 0 stevel } else if (cp[1]) { 153 0 stevel switch (*++cp) { 154 0 stevel 155 0 stevel case 'U': 156 0 stevel pdeltat(&r1->ru_utime, &r0->ru_utime); 157 0 stevel break; 158 0 stevel 159 0 stevel case 'S': 160 0 stevel pdeltat(&r1->ru_stime, &r0->ru_stime); 161 0 stevel break; 162 0 stevel 163 0 stevel case 'E': 164 0 stevel psecs_int(ms / 100); 165 0 stevel break; 166 0 stevel 167 0 stevel case 'P': 168 0 stevel printf("%d%%", (int)(t * 100 / 169 0 stevel ((ms ? ms : 1)))); 170 0 stevel break; 171 0 stevel 172 0 stevel case 'W': 173 0 stevel i = r1->ru_nswap - r0->ru_nswap; 174 0 stevel printf("%d", i); 175 0 stevel break; 176 0 stevel 177 0 stevel case 'X': 178 0 stevel printf("%d", t == 0 ? 0 : 179 0 stevel pgtok((r1->ru_ixrss - r0->ru_ixrss) / t)); 180 0 stevel break; 181 0 stevel 182 0 stevel case 'D': 183 0 stevel printf("%d", t == 0 ? 0 : 184 0 stevel pgtok((r1->ru_idrss + r1->ru_isrss- 185 0 stevel (r0->ru_idrss + r0->ru_isrss)) / t)); 186 0 stevel break; 187 0 stevel 188 0 stevel case 'K': 189 0 stevel printf("%d", t == 0 ? 0 : 190 0 stevel pgtok(((r1->ru_ixrss + r1->ru_isrss + 191 0 stevel r1->ru_idrss) - (r0->ru_ixrss + 192 0 stevel r0->ru_idrss + r0->ru_isrss)) / t)); 193 0 stevel break; 194 0 stevel 195 0 stevel case 'M': 196 0 stevel printf("%d", r1->ru_maxrss / 2); 197 0 stevel break; 198 0 stevel 199 0 stevel case 'F': 200 0 stevel printf("%d", r1->ru_majflt - r0->ru_majflt); 201 0 stevel break; 202 0 stevel 203 0 stevel case 'R': 204 0 stevel printf("%d", r1->ru_minflt - r0->ru_minflt); 205 0 stevel break; 206 0 stevel 207 0 stevel case 'I': 208 0 stevel printf("%d", r1->ru_inblock - r0->ru_inblock); 209 0 stevel break; 210 0 stevel 211 0 stevel case 'O': 212 0 stevel printf("%d", r1->ru_oublock - r0->ru_oublock); 213 0 stevel break; 214 0 stevel } 215 0 stevel } 216 0 stevel } 217 0 stevel Putchar('\n'); 218 0 stevel #undef pgtok 219 0 stevel } 220 0 stevel 221 0 stevel void 222 0 stevel pdeltat(struct timeval *t1, struct timeval *t0) 223 0 stevel { 224 0 stevel struct timeval td; 225 0 stevel 226 0 stevel #ifdef TRACE 227 0 stevel tprintf("TRACE- pdeltat()\n"); 228 0 stevel #endif 229 0 stevel tvsub(&td, t1, t0); 230 0 stevel /* change printf formats */ 231 0 stevel printf("%d.%01d", td.tv_sec, td.tv_usec / 100000); 232 0 stevel } 233 0 stevel 234 0 stevel void 235 0 stevel tvadd(struct timeval *tsum, struct timeval *t0) 236 0 stevel { 237 0 stevel 238 0 stevel #ifdef TRACE 239 0 stevel tprintf("TRACE- tvadd()\n"); 240 0 stevel #endif 241 0 stevel tsum->tv_sec += t0->tv_sec; 242 0 stevel tsum->tv_usec += t0->tv_usec; 243 0 stevel if (tsum->tv_usec > 1000000) { 244 0 stevel tsum->tv_sec++; 245 0 stevel tsum->tv_usec -= 1000000; 246 0 stevel } 247 0 stevel } 248 0 stevel 249 0 stevel void 250 0 stevel tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0) 251 0 stevel { 252 0 stevel 253 0 stevel #ifdef TRACE 254 0 stevel tprintf("TRACE- tvsub()\n"); 255 0 stevel #endif 256 0 stevel tdiff->tv_sec = t1->tv_sec - t0->tv_sec; 257 0 stevel tdiff->tv_usec = t1->tv_usec - t0->tv_usec; 258 0 stevel if (tdiff->tv_usec < 0) { 259 0 stevel tdiff->tv_sec--; 260 0 stevel tdiff->tv_usec += 1000000; 261 0 stevel } 262 0 stevel } 263