resource.c revision 60fe8c139c6f2febefe595781812ddf0864a6ab8
1/* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@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 58static 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 111static char * 112sprintrlim(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) 126static void 127print_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 tprints("{...}"); 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 147int 148sys_getrlimit(struct tcb *tcp) 149{ 150 struct rlimit rlim; 151 152 if (entering(tcp)) { 153 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 154 tprints(", "); 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 tprints("{...}"); 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 173int 174sys_setrlimit(struct tcb *tcp) 175{ 176 struct rlimit rlim; 177 178 if (entering(tcp)) { 179 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 180 tprints(", "); 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 tprints("{...}"); 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 199static char * 200sprintrlim64(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 213int 214sys_getrlimit64(struct tcb *tcp) 215{ 216 struct rlimit64 rlim; 217 218 if (entering(tcp)) { 219 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 220 tprints(", "); 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 tprints("{...}"); 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 235int 236sys_setrlimit64(struct tcb *tcp) 237{ 238 struct rlimit64 rlim; 239 240 if (entering(tcp)) { 241 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 242 tprints(", "); 243 if (!verbose(tcp)) 244 tprintf("%#lx", tcp->u_arg[1]); 245 else if (umove(tcp, tcp->u_arg[1], &rlim) < 0) 246 tprints("{...}"); 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 258static 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 268void 269printrusage32(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 tprints("NULL"); 296 else if (syserror(tcp) || !verbose(tcp)) 297 tprintf("%#lx", addr); 298 else if (umove(tcp, addr, &ru) < 0) 299 tprints("{...}"); 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 325void 326printrusage(struct tcb *tcp, long addr) 327{ 328 struct rusage ru; 329 330 if (!addr) 331 tprints("NULL"); 332 else if (syserror(tcp) || !verbose(tcp)) 333 tprintf("%#lx", addr); 334 else if (umove(tcp, addr, &ru) < 0) 335 tprints("{...}"); 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 360int 361sys_getrusage(struct tcb *tcp) 362{ 363 if (entering(tcp)) { 364 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 365 tprints(", "); 366 } 367 else 368 printrusage(tcp, tcp->u_arg[1]); 369 return 0; 370} 371 372#ifdef ALPHA 373int 374sys_osf_getrusage(struct tcb *tcp) 375{ 376 if (entering(tcp)) { 377 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 378 tprints(", "); 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 390int 391sys_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 tprints("{...}"); 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 417static const struct xlat priorities[] = { 418 { PRIO_PROCESS, "PRIO_PROCESS" }, 419 { PRIO_PGRP, "PRIO_PGRP" }, 420 { PRIO_USER, "PRIO_USER" }, 421 { 0, NULL }, 422}; 423 424int 425sys_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 434int 435sys_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 444int 445sys_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 454int 455sys_times(struct tcb *tcp) 456{ 457 struct tms tbuf; 458 459 if (exiting(tcp)) { 460 if (tcp->u_arg[0] == 0) 461 tprints("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 tprints("{...}"); 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