1 /*
2 * Check decoding of getrlimit/ugetrlimit 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 <errno.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <sys/resource.h>
15 #include <unistd.h>
16
17 #include "xlat.h"
18 #include "xlat/resources.h"
19
20 static const char *
21 sprint_rlim(kernel_ulong_t lim)
22 {
23 static char buf[2][ /* space for 2 llu strings */
24 2*sizeof(lim)*3 +
25 /* space for XLAT_STYLE_ABBREV decoding */
26 sizeof("*1024") + sizeof("RLIM64_INFINITY") +
27 /* space for C style comments */
28 6];
29 static unsigned int i;
30
31 i &= 1;
32
33 #if XLAT_RAW
34 sprintf(buf[i], "%llu", (unsigned long long) lim);
35 return buf[i++];
36 #else
37 if (sizeof(lim) == sizeof(uint64_t)) {
38 if (lim == (kernel_ulong_t) -1ULL) {
39 # if XLAT_VERBOSE
40 sprintf(buf[i], "%llu /* RLIM64_INFINITY */",
41 (unsigned long long) lim);
42 return buf[i++];
43 # else /* XLAT_ABBREV */
44 return "RLIM64_INFINITY";
45 # endif
46 }
47 } else {
48 if (lim == (kernel_ulong_t) -1U) {
49 # if XLAT_VERBOSE
50 sprintf(buf[i], "%llu /* RLIM_INFINITY */",
51 (unsigned long long) lim);
52 return buf[i++];
53 # else /* XLAT_ABBREV */
54 return "RLIM_INFINITY";
55 # endif
56 }
57 }
58
59 if (lim > 1024 && lim % 1024 == 0)
60 # if XLAT_VERBOSE
61 sprintf(buf[i], "%llu /* %llu*1024 */",
62 (unsigned long long) lim,
63 (unsigned long long) lim / 1024);
64 # else /* XLAT_ABBREV */
65 sprintf(buf[i], "%llu*1024", (unsigned long long) lim / 1024);
66 # endif
67 else
68 sprintf(buf[i], "%llu", (unsigned long long) lim);
69
70 return buf[i++];
71 #endif /* !XLAT_RAW */
72 }
73
74 #ifdef NR_GETRLIMIT
75
76 int
77 main(void)
78 {
79 kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
80 const struct xlat_data *xlat;
81 size_t i;
82 long rc;
83
84 rc = syscall(NR_GETRLIMIT, 16, 0);
85 printf("%s(0x10 /* RLIMIT_??? */, NULL) = %s\n",
86 STR_GETRLIMIT, sprintrc(rc));
87
88 for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
89 if (!xlat->str)
90 continue;
91
92 unsigned long res = 0xfacefeed00000000ULL | xlat->val;
93 rc = syscall(NR_GETRLIMIT, res, 0);
94 if (rc && ENOSYS == errno)
95 perror_msg_and_skip(STR_GETRLIMIT);
96 printf("%s(%s, NULL) = %s\n",
97 STR_GETRLIMIT, xlat->str, sprintrc(rc));
98
99 rc = syscall(NR_GETRLIMIT, res, rlimit);
100 if (rc)
101 printf("%s(%s, %p) = %s\n",
102 STR_GETRLIMIT, xlat->str, rlimit, sprintrc(rc));
103 else
104 printf("%s(%s, {rlim_cur=%s, rlim_max=%s})"
105 " = 0\n", STR_GETRLIMIT, xlat->str,
106 sprint_rlim(rlimit[0]), sprint_rlim(rlimit[1]));
107 }
108
109 puts("+++ exited with 0 +++");
110 return 0;
111 }
112
113 #endif /* NR_GETRLIMIT */