(root)/
strace-6.5/
tests-m32/
prlimit64.c
       1  /*
       2   * Check decoding of prlimit64 syscall.
       3   *
       4   * Copyright (c) 2016-2018 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  
      14  #include <inttypes.h>
      15  #include <stdio.h>
      16  #include <stdint.h>
      17  #include <stdlib.h>
      18  #include <sys/resource.h>
      19  #include <unistd.h>
      20  
      21  #include "pidns.h"
      22  #include "xlat.h"
      23  #include "xlat/resources.h"
      24  
      25  #ifndef RETVAL_INJECTED
      26  # define RETVAL_INJECTED 0
      27  #endif
      28  
      29  #if RETVAL_INJECTED
      30  # define INJ_STR " (INJECTED)"
      31  #else
      32  # define INJ_STR ""
      33  #endif
      34  #define INJECT_RETVAL 42
      35  
      36  static const char *
      37  sprint_rlim(uint64_t lim)
      38  {
      39  	if (lim == -1ULL)
      40  		return "RLIM64_INFINITY";
      41  
      42  	static char buf[2][sizeof(lim)*3 + sizeof("*1024")];
      43  	static int i;
      44  	i &= 1;
      45  	if (lim > 1024 && lim % 1024 == 0)
      46  		sprintf(buf[i], "%" PRIu64 "*1024", lim / 1024);
      47  	else
      48  		sprintf(buf[i], "%" PRIu64, lim);
      49  
      50  	return buf[i++];
      51  }
      52  
      53  int
      54  main(int argc, char *argv[])
      55  {
      56  	PIDNS_TEST_INIT;
      57  
      58  	unsigned long pid =
      59  		(unsigned long) 0xdefaced00000000ULL | (unsigned) getpid();
      60  	const char *pid_str = pidns_pid2str(PT_TGID);
      61  	uint64_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
      62  	const struct xlat_data *xlat;
      63  	long rc;
      64  	unsigned long num_skip = 256;
      65  	size_t i = 0;
      66  
      67  	if (argc >= 2)
      68  		num_skip = strtoul(argv[1], NULL, 0);
      69  
      70  	for (i = 0; i < num_skip; i++) {
      71  		long rc = syscall(__NR_prlimit64, 0, 16, 0, 0);
      72  		pidns_print_leader();
      73  		printf("prlimit64(0, 0x10 /* RLIMIT_??? */, NULL, NULL)"
      74  		       " = %s%s\n",
      75  		       sprintrc(rc), rc == INJECT_RETVAL ? INJ_STR : "");
      76  	}
      77  
      78  	/* The shortest output */
      79  	rc = syscall(__NR_prlimit64, 0, RLIMIT_AS, 0, 0);
      80  	pidns_print_leader();
      81  	printf("prlimit64(0, RLIMIT_AS, NULL, NULL) = %s" INJ_STR "\n",
      82  	       sprintrc(rc));
      83  
      84  	for (i = 0, xlat = resources->data; i < resources->size; ++xlat, ++i) {
      85  		if (!xlat->str)
      86  			continue;
      87  
      88  		unsigned long res = 0xfacefeed00000000ULL | xlat->val;
      89  		rc = syscall(__NR_prlimit64, pid, res, 0, rlimit);
      90  		pidns_print_leader();
      91  		if (!RETVAL_INJECTED && (rc < 0)) {
      92  			printf("prlimit64(%d%s, %s, NULL, %p) = %s\n",
      93  			       (unsigned) pid, pid_str,
      94  			       xlat->str, rlimit,
      95  			       sprintrc(rc));
      96  		} else {
      97  			printf("prlimit64(%d%s, %s, NULL"
      98  			       ", {rlim_cur=%s, rlim_max=%s})"
      99  			       " = %d" INJ_STR "\n",
     100  			       (unsigned) pid, pid_str,
     101  			       xlat->str,
     102  			       sprint_rlim(rlimit[0]),
     103  			       sprint_rlim(rlimit[1]),
     104  			       RETVAL_INJECTED ? INJECT_RETVAL : 0);
     105  		}
     106  	}
     107  
     108  	pidns_print_leader();
     109  	puts("+++ exited with 0 +++");
     110  	return 0;
     111  }