1 /* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk (at) cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko (at) hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs (at) world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert (at) cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $Id$ 31 */ 32 33 #include "defs.h" 34 35 #include <sys/resource.h> 36 #ifdef LINUX 37 #include <sys/times.h> 38 #include <linux/kernel.h> 39 #endif /* LINUX */ 40 #if defined(SVR4) || defined(FREEBSD) 41 #include <sys/times.h> 42 #include <sys/time.h> 43 #endif 44 45 #if HAVE_LONG_LONG_RLIM_T 46 /* 47 * Hacks for systems that have a long long rlim_t 48 */ 49 50 #define rlimit64 rlimit /* Ugly hack */ 51 #define rlim64_t rlim_t /* Ugly hack */ 52 #define RLIM64_INFINITY RLIM_INFINITY /* You guessed it */ 53 54 #define sys_getrlimit64 sys_getrlimit 55 #define sys_setrlimit64 sys_setrlimit 56 #endif 57 58 static const struct xlat resources[] = { 59 #ifdef RLIMIT_AS 60 { RLIMIT_AS, "RLIMIT_AS" }, 61 #endif 62 #ifdef RLIMIT_CORE 63 { RLIMIT_CORE, "RLIMIT_CORE" }, 64 #endif 65 #ifdef RLIMIT_CPU 66 { RLIMIT_CPU, "RLIMIT_CPU" }, 67 #endif 68 #ifdef RLIMIT_DATA 69 { RLIMIT_DATA, "RLIMIT_DATA" }, 70 #endif 71 #ifdef RLIMIT_FSIZE 72 { RLIMIT_FSIZE, "RLIMIT_FSIZE" }, 73 #endif 74 #ifdef RLIMIT_LOCKS 75 { RLIMIT_LOCKS, "RLIMIT_LOCKS" }, 76 #endif 77 #ifdef RLIMIT_MEMLOCK 78 { RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK" }, 79 #endif 80 #ifdef RLIMIT_MSGQUEUE 81 { RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE" }, 82 #endif 83 #ifdef RLIMIT_NICE 84 { RLIMIT_NICE, "RLIMIT_NICE" }, 85 #endif 86 #ifdef RLIMIT_NOFILE 87 { RLIMIT_NOFILE, "RLIMIT_NOFILE" }, 88 #endif 89 #ifdef RLIMIT_NPROC 90 { RLIMIT_NPROC, "RLIMIT_NPROC" }, 91 #endif 92 #ifdef RLIMIT_RSS 93 { RLIMIT_RSS, "RLIMIT_RSS" }, 94 #endif 95 #ifdef RLIMIT_RTPRIO 96 { RLIMIT_RTPRIO, "RLIMIT_RTPRIO" }, 97 #endif 98 #ifdef RLIMIT_SIGPENDING 99 { RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING" }, 100 #endif 101 #ifdef RLIMIT_STACK 102 { RLIMIT_STACK, "RLIMIT_STACK" }, 103 #endif 104 #ifdef RLIMIT_VMEM 105 { RLIMIT_VMEM, "RLIMIT_VMEM" }, 106 #endif 107 { 0, NULL }, 108 }; 109 110 #if !HAVE_LONG_LONG_RLIM_T 111 static char * 112 sprintrlim(long lim) 113 { 114 static char buf[32]; 115 116 if (lim == RLIM_INFINITY) 117 sprintf(buf, "RLIM_INFINITY"); 118 else if (lim > 1024 && lim%1024 == 0) 119 sprintf(buf, "%ld*1024", lim/1024); 120 else 121 sprintf(buf, "%ld", lim); 122 return buf; 123 } 124 125 # if defined LINUX && (defined POWERPC64 || defined X86_64) 126 static void 127 print_rlimit32(struct tcb *tcp) 128 { 129 struct rlimit32 { 130 unsigned int rlim_cur; 131 unsigned int rlim_max; 132 } rlim; 133 134 if (umove(tcp, tcp->u_arg[1], &rlim) < 0) 135 tprintf("{...}"); 136 else { 137 tprintf("{rlim_cur=%s,", 138 sprintrlim(rlim.rlim_cur == -1 ? RLIM_INFINITY 139 : rlim.rlim_cur)); 140 tprintf(" rlim_max=%s}", 141 sprintrlim(rlim.rlim_max == -1 ? RLIM_INFINITY 142 : rlim.rlim_max)); 143 } 144 } 145 # endif 146 147 int 148 sys_getrlimit(struct tcb *tcp) 149 { 150 struct rlimit rlim; 151 152 if (entering(tcp)) { 153 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 154 tprintf(", "); 155 } 156 else { 157 if (syserror(tcp) || !verbose(tcp)) 158 tprintf("%#lx", tcp->u_arg[1]); 159 # if defined LINUX && (defined POWERPC64 || defined X86_64) 160 else if (current_personality == 1) 161 print_rlimit32(tcp); 162 # endif 163 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0) 164 tprintf("{...}"); 165 else { 166 tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur)); 167 tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max)); 168 } 169 } 170 return 0; 171 } 172 173 int 174 sys_setrlimit(struct tcb *tcp) 175 { 176 struct rlimit rlim; 177 178 if (entering(tcp)) { 179 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 180 tprintf(", "); 181 if (!verbose(tcp)) 182 tprintf("%#lx", tcp->u_arg[1]); 183 # if defined LINUX && (defined POWERPC64 || defined X86_64) 184 else if (current_personality == 1) 185 print_rlimit32(tcp); 186 # endif 187 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0) 188 tprintf("{...}"); 189 else { 190 tprintf("{rlim_cur=%s,", sprintrlim(rlim.rlim_cur)); 191 tprintf(" rlim_max=%s}", sprintrlim(rlim.rlim_max)); 192 } 193 } 194 return 0; 195 } 196 #endif /* !HAVE_LONG_LONG_RLIM_T */ 197 198 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_RLIM_T 199 static char * 200 sprintrlim64(rlim64_t lim) 201 { 202 static char buf[64]; 203 204 if (lim == RLIM64_INFINITY) 205 sprintf(buf, "RLIM64_INFINITY"); 206 else if (lim > 1024 && lim%1024 == 0) 207 sprintf(buf, "%lld*1024", (long long) lim/1024); 208 else 209 sprintf(buf, "%lld", (long long) lim); 210 return buf; 211 } 212 213 int 214 sys_getrlimit64(struct tcb *tcp) 215 { 216 struct rlimit64 rlim; 217 218 if (entering(tcp)) { 219 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 220 tprintf(", "); 221 } 222 else { 223 if (syserror(tcp) || !verbose(tcp)) 224 tprintf("%#lx", tcp->u_arg[1]); 225 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0) 226 tprintf("{...}"); 227 else { 228 tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur)); 229 tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max)); 230 } 231 } 232 return 0; 233 } 234 235 int 236 sys_setrlimit64(struct tcb *tcp) 237 { 238 struct rlimit64 rlim; 239 240 if (entering(tcp)) { 241 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 242 tprintf(", "); 243 if (!verbose(tcp)) 244 tprintf("%#lx", tcp->u_arg[1]); 245 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0) 246 tprintf("{...}"); 247 else { 248 tprintf("{rlim_cur=%s,", sprintrlim64(rlim.rlim_cur)); 249 tprintf(" rlim_max=%s}", sprintrlim64(rlim.rlim_max)); 250 } 251 } 252 return 0; 253 } 254 #endif /* _LFS64_LARGEFILES || HAVE_LONG_LONG_RLIM_T */ 255 256 #ifndef SVR4 257 258 static const struct xlat usagewho[] = { 259 { RUSAGE_SELF, "RUSAGE_SELF" }, 260 { RUSAGE_CHILDREN, "RUSAGE_CHILDREN" }, 261 #ifdef RUSAGE_BOTH 262 { RUSAGE_BOTH, "RUSAGE_BOTH" }, 263 #endif 264 { 0, NULL }, 265 }; 266 267 #ifdef ALPHA 268 void 269 printrusage32(struct tcb *tcp, long addr) 270 { 271 struct timeval32 { 272 unsigned tv_sec; 273 unsigned tv_usec; 274 }; 275 struct rusage32 { 276 struct timeval32 ru_utime; /* user time used */ 277 struct timeval32 ru_stime; /* system time used */ 278 long ru_maxrss; /* maximum resident set size */ 279 long ru_ixrss; /* integral shared memory size */ 280 long ru_idrss; /* integral unshared data size */ 281 long ru_isrss; /* integral unshared stack size */ 282 long ru_minflt; /* page reclaims */ 283 long ru_majflt; /* page faults */ 284 long ru_nswap; /* swaps */ 285 long ru_inblock; /* block input operations */ 286 long ru_oublock; /* block output operations */ 287 long ru_msgsnd; /* messages sent */ 288 long ru_msgrcv; /* messages received */ 289 long ru_nsignals; /* signals received */ 290 long ru_nvcsw; /* voluntary context switches */ 291 long ru_nivcsw; /* involuntary " */ 292 } ru; 293 294 if (!addr) 295 tprintf("NULL"); 296 else if (syserror(tcp) || !verbose(tcp)) 297 tprintf("%#lx", addr); 298 else if (umove(tcp, addr, &ru) < 0) 299 tprintf("{...}"); 300 else if (!abbrev(tcp)) { 301 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ", 302 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 303 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 304 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ", 305 ru.ru_maxrss, ru.ru_ixrss); 306 tprintf("ru_idrss=%lu, ru_isrss=%lu, ", 307 ru.ru_idrss, ru.ru_isrss); 308 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ", 309 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); 310 tprintf("ru_inblock=%lu, ru_oublock=%lu, ", 311 ru.ru_inblock, ru.ru_oublock); 312 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ", 313 ru.ru_msgsnd, ru.ru_msgrcv); 314 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}", 315 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 316 } 317 else { 318 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}", 319 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 320 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 321 } 322 } 323 #endif 324 325 void 326 printrusage(struct tcb *tcp, long addr) 327 { 328 struct rusage ru; 329 330 if (!addr) 331 tprintf("NULL"); 332 else if (syserror(tcp) || !verbose(tcp)) 333 tprintf("%#lx", addr); 334 else if (umove(tcp, addr, &ru) < 0) 335 tprintf("{...}"); 336 else if (!abbrev(tcp)) { 337 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ", 338 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 339 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 340 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ", 341 ru.ru_maxrss, ru.ru_ixrss); 342 tprintf("ru_idrss=%lu, ru_isrss=%lu, ", 343 ru.ru_idrss, ru.ru_isrss); 344 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ", 345 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); 346 tprintf("ru_inblock=%lu, ru_oublock=%lu, ", 347 ru.ru_inblock, ru.ru_oublock); 348 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ", 349 ru.ru_msgsnd, ru.ru_msgrcv); 350 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}", 351 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 352 } 353 else { 354 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}", 355 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 356 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 357 } 358 } 359 360 int 361 sys_getrusage(struct tcb *tcp) 362 { 363 if (entering(tcp)) { 364 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 365 tprintf(", "); 366 } 367 else 368 printrusage(tcp, tcp->u_arg[1]); 369 return 0; 370 } 371 372 #ifdef ALPHA 373 int 374 sys_osf_getrusage(struct tcb *tcp) 375 { 376 if (entering(tcp)) { 377 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 378 tprintf(", "); 379 } 380 else 381 printrusage32(tcp, tcp->u_arg[1]); 382 return 0; 383 } 384 #endif /* ALPHA */ 385 386 #endif /* !SVR4 */ 387 388 #ifdef LINUX 389 390 int 391 sys_sysinfo(struct tcb *tcp) 392 { 393 struct sysinfo si; 394 395 if (exiting(tcp)) { 396 if (syserror(tcp) || !verbose(tcp)) 397 tprintf("%#lx", tcp->u_arg[0]); 398 else if (umove(tcp, tcp->u_arg[0], &si) < 0) 399 tprintf("{...}"); 400 else { 401 tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ", 402 si.uptime, si.loads[0], si.loads[1], 403 si.loads[2]); 404 tprintf("totalram=%lu, freeram=%lu, ", 405 si.totalram, si.freeram); 406 tprintf("sharedram=%lu, bufferram=%lu} ", 407 si.sharedram, si.bufferram); 408 tprintf("totalswap=%lu, freeswap=%lu, procs=%hu}", 409 si.totalswap, si.freeswap, si.procs); 410 } 411 } 412 return 0; 413 } 414 415 #endif /* LINUX */ 416 417 static const struct xlat priorities[] = { 418 { PRIO_PROCESS, "PRIO_PROCESS" }, 419 { PRIO_PGRP, "PRIO_PGRP" }, 420 { PRIO_USER, "PRIO_USER" }, 421 { 0, NULL }, 422 }; 423 424 int 425 sys_getpriority(struct tcb *tcp) 426 { 427 if (entering(tcp)) { 428 printxval(priorities, tcp->u_arg[0], "PRIO_???"); 429 tprintf(", %lu", tcp->u_arg[1]); 430 } 431 return 0; 432 } 433 434 int 435 sys_setpriority(struct tcb *tcp) 436 { 437 if (entering(tcp)) { 438 printxval(priorities, tcp->u_arg[0], "PRIO_???"); 439 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]); 440 } 441 return 0; 442 } 443 444 int 445 sys_nice(struct tcb *tcp) 446 { 447 if (entering(tcp)) 448 tprintf("%ld", tcp->u_arg[0]); 449 return 0; 450 } 451 452 #ifndef SUNOS4 453 454 int 455 sys_times(struct tcb *tcp) 456 { 457 struct tms tbuf; 458 459 if (exiting(tcp)) { 460 if (tcp->u_arg[0] == 0) 461 tprintf("NULL"); 462 else if (syserror(tcp)) 463 tprintf("%#lx", tcp->u_arg[0]); 464 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0) 465 tprintf("{...}"); 466 else { 467 tprintf("{tms_utime=%lu, tms_stime=%lu, ", 468 tbuf.tms_utime, tbuf.tms_stime); 469 tprintf("tms_cutime=%lu, tms_cstime=%lu}", 470 tbuf.tms_cutime, tbuf.tms_cstime); 471 } 472 } 473 return 0; 474 } 475 476 #endif /* !SUNOS4 */ 477