(root)/
strace-6.5/
src/
resource.c
       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   * Copyright (c) 1999-2023 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: LGPL-2.1-or-later
      10   */
      11  
      12  #include "defs.h"
      13  #include <sys/resource.h>
      14  
      15  #include "xstring.h"
      16  
      17  #include "xlat/resources.h"
      18  
      19  static void
      20  print_rlim64_t(uint64_t lim) {
      21  	const char *str = NULL;
      22  
      23  	if (lim == UINT64_MAX)
      24  		str = "RLIM64_INFINITY";
      25  	else if (lim > 1024 && lim % 1024 == 0) {
      26  		static char buf[sizeof(lim) * 3 + sizeof("*1024")];
      27  
      28  		xsprintf(buf, "%" PRIu64 "*1024", lim / 1024);
      29  		str = buf;
      30  	}
      31  
      32  	if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
      33  		PRINT_VAL_U(lim);
      34  
      35  	if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
      36  		return;
      37  
      38  	(xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
      39                  ? tprints_comment : tprints_string)(str);
      40  }
      41  
      42  static void
      43  print_rlimit64(struct tcb *const tcp, const kernel_ulong_t addr)
      44  {
      45  	struct rlimit_64 {
      46  		uint64_t rlim_cur;
      47  		uint64_t rlim_max;
      48  	} rlim;
      49  
      50  	if (!umove_or_printaddr(tcp, addr, &rlim)) {
      51  		tprint_struct_begin();
      52  		PRINT_FIELD_OBJ_VAL(rlim, rlim_cur, print_rlim64_t);
      53  		tprint_struct_next();
      54  		PRINT_FIELD_OBJ_VAL(rlim, rlim_max, print_rlim64_t);
      55  		tprint_struct_end();
      56  	}
      57  }
      58  
      59  #if !defined(current_wordsize) || current_wordsize == 4
      60  
      61  static void
      62  print_rlim32_t(uint32_t lim) {
      63  	const char *str = NULL;
      64  
      65  	if (lim == UINT32_MAX)
      66  		str = "RLIM_INFINITY";
      67  	else if (lim > 1024 && lim % 1024 == 0) {
      68  		static char buf[sizeof(lim) * 3 + sizeof("*1024")];
      69  
      70  		xsprintf(buf, "%" PRIu32 "*1024", lim / 1024);
      71  		str = buf;
      72  	}
      73  
      74  	if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
      75  		PRINT_VAL_U(lim);
      76  
      77  	if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
      78  		return;
      79  
      80  	(xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
      81                  ? tprints_comment : tprints_string)(str);
      82  }
      83  
      84  static void
      85  print_rlimit32(struct tcb *const tcp, const kernel_ulong_t addr)
      86  {
      87  	struct rlimit_32 {
      88  		uint32_t rlim_cur;
      89  		uint32_t rlim_max;
      90  	} rlim;
      91  
      92  	if (!umove_or_printaddr(tcp, addr, &rlim)) {
      93  		tprint_struct_begin();
      94  		PRINT_FIELD_OBJ_VAL(rlim, rlim_cur, print_rlim32_t);
      95  		tprint_struct_next();
      96  		PRINT_FIELD_OBJ_VAL(rlim, rlim_max, print_rlim32_t);
      97  		tprint_struct_end();
      98  	}
      99  }
     100  
     101  static void
     102  decode_rlimit(struct tcb *const tcp, const kernel_ulong_t addr)
     103  {
     104  	/*
     105  	 * i386 is the only personality on X86_64 and X32
     106  	 * with 32-bit rlim_t.
     107  	 * When current_personality is X32, current_wordsize
     108  	 * equals to 4 but rlim_t is 64-bit.
     109  	 */
     110  	if (current_klongsize == 4)
     111  		print_rlimit32(tcp, addr);
     112  	else
     113  		print_rlimit64(tcp, addr);
     114  }
     115  
     116  #else /* defined(current_wordsize) && current_wordsize != 4 */
     117  
     118  # define decode_rlimit print_rlimit64
     119  
     120  #endif
     121  
     122  SYS_FUNC(getrlimit)
     123  {
     124  	if (entering(tcp)) {
     125  		/* resource */
     126  		printxval(resources, tcp->u_arg[0], "RLIMIT_???");
     127  		tprint_arg_next();
     128  	} else {
     129  		/* rlim */
     130  		decode_rlimit(tcp, tcp->u_arg[1]);
     131  	}
     132  	return 0;
     133  }
     134  
     135  SYS_FUNC(setrlimit)
     136  {
     137  	/* resource */
     138  	printxval(resources, tcp->u_arg[0], "RLIMIT_???");
     139  	tprint_arg_next();
     140  
     141  	/* rlim */
     142  	decode_rlimit(tcp, tcp->u_arg[1]);
     143  
     144  	return RVAL_DECODED;
     145  }
     146  
     147  SYS_FUNC(prlimit64)
     148  {
     149  	if (entering(tcp)) {
     150  		/* pid */
     151  		printpid(tcp, tcp->u_arg[0], PT_TGID);
     152  		tprint_arg_next();
     153  
     154  		/* resource */
     155  		printxval(resources, tcp->u_arg[1], "RLIMIT_???");
     156  		tprint_arg_next();
     157  
     158  		/* new_limit */
     159  		print_rlimit64(tcp, tcp->u_arg[2]);
     160  		tprint_arg_next();
     161  	} else {
     162  		/* old_limit */
     163  		print_rlimit64(tcp, tcp->u_arg[3]);
     164  	}
     165  	return 0;
     166  }
     167  
     168  #include "xlat/usagewho.h"
     169  
     170  SYS_FUNC(getrusage)
     171  {
     172  	if (entering(tcp)) {
     173  		/* who */
     174  		printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
     175  		tprint_arg_next();
     176  	} else {
     177  		/* usage */
     178  		printrusage(tcp, tcp->u_arg[1]);
     179  	}
     180  	return 0;
     181  }
     182  
     183  #ifdef ALPHA
     184  SYS_FUNC(osf_getrusage)
     185  {
     186  	if (entering(tcp)) {
     187  		/* who */
     188  		printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
     189  		tprint_arg_next();
     190  	} else {
     191  		/* usage */
     192  		printrusage32(tcp, tcp->u_arg[1]);
     193  	}
     194  	return 0;
     195  }
     196  #endif /* ALPHA */
     197  
     198  #include "xlat/priorities.h"
     199  
     200  static void
     201  priority_print_who(struct tcb *tcp, int which, int who)
     202  {
     203  	switch (which)
     204  	{
     205  	case PRIO_PROCESS:
     206  		printpid(tcp, who, PT_TGID);
     207  		break;
     208  	case PRIO_PGRP:
     209  		printpid(tcp, who, PT_PGID);
     210  		break;
     211  	default:
     212  		PRINT_VAL_D(who);
     213  		break;
     214  	}
     215  }
     216  
     217  SYS_FUNC(getpriority)
     218  {
     219  	/* which */
     220  	printxval(priorities, tcp->u_arg[0], "PRIO_???");
     221  	tprint_arg_next();
     222  
     223  	/* who */
     224  	priority_print_who(tcp, tcp->u_arg[0], tcp->u_arg[1]);
     225  
     226  	return RVAL_DECODED;
     227  }
     228  
     229  SYS_FUNC(setpriority)
     230  {
     231  	/* which */
     232  	printxval(priorities, tcp->u_arg[0], "PRIO_???");
     233  	tprint_arg_next();
     234  
     235  	/* who */
     236  	priority_print_who(tcp, tcp->u_arg[0], tcp->u_arg[1]);
     237  	tprint_arg_next();
     238  
     239  	/* prio */
     240  	PRINT_VAL_D((int) tcp->u_arg[2]);
     241  
     242  	return RVAL_DECODED;
     243  }