1*5e3eaea3SApple OSS Distributions /*
2*5e3eaea3SApple OSS Distributions * cd $XNU/tests
3*5e3eaea3SApple OSS Distributions * xcrun -sdk macosx.internal/iphoneos.internal make proc_rlimit LDFLAGS="-ldarwintest"
4*5e3eaea3SApple OSS Distributions */
5*5e3eaea3SApple OSS Distributions #include <stdio.h>
6*5e3eaea3SApple OSS Distributions #include <unistd.h>
7*5e3eaea3SApple OSS Distributions #include <sys/resource.h>
8*5e3eaea3SApple OSS Distributions #include <errno.h>
9*5e3eaea3SApple OSS Distributions #include <sys/sysctl.h>
10*5e3eaea3SApple OSS Distributions #include <darwintest.h>
11*5e3eaea3SApple OSS Distributions
12*5e3eaea3SApple OSS Distributions /* Defined in <sys/resource.h> but not visible to user space */
13*5e3eaea3SApple OSS Distributions #define RLIMIT_NLIMITS 9
14*5e3eaea3SApple OSS Distributions
15*5e3eaea3SApple OSS Distributions /* Defined in <sys/resource.h> and visible to user space */
16*5e3eaea3SApple OSS Distributions static const char *RESOURCE_STRING[] = {
17*5e3eaea3SApple OSS Distributions "RLIMIT_CPU", /* #define RLIMIT_CPU 0 */
18*5e3eaea3SApple OSS Distributions "RLIMIT_FSIZE", /* #define RLIMIT_FSIZE 1 */
19*5e3eaea3SApple OSS Distributions "RLIMIT_DATA", /* #define RLIMIT_DATA 2 */
20*5e3eaea3SApple OSS Distributions "RLIMIT_STACK", /* #define RLIMIT_STACK 3 */
21*5e3eaea3SApple OSS Distributions "RLIMIT_CORE", /* #define RLIMIT_CORE 4 */
22*5e3eaea3SApple OSS Distributions "RLIMIT_AS/RSS", /* #define RLIMIT_AS 5 */
23*5e3eaea3SApple OSS Distributions /* #define RLIMIT_RSS RLIMIT_AS */
24*5e3eaea3SApple OSS Distributions "RLIMIT_MEMLOCK", /* #define RLIMIT_MEMLOCK 6 */
25*5e3eaea3SApple OSS Distributions "RLIMIT_NPROC", /* #define RLIMIT_NPROC 7 */
26*5e3eaea3SApple OSS Distributions "RLIMIT_NOFILE" /* #define RLIMIT_NOFILE 8 */
27*5e3eaea3SApple OSS Distributions };
28*5e3eaea3SApple OSS Distributions
29*5e3eaea3SApple OSS Distributions /* Change limit values by this arbitrary amount */
30*5e3eaea3SApple OSS Distributions #define LIMIT_DIFF 64
31*5e3eaea3SApple OSS Distributions
32*5e3eaea3SApple OSS Distributions /* Limit type */
33*5e3eaea3SApple OSS Distributions #define SOFT_LIMIT 0
34*5e3eaea3SApple OSS Distributions #define HARD_LIMIT 1
35*5e3eaea3SApple OSS Distributions
36*5e3eaea3SApple OSS Distributions /* Action on changing limit values */
37*5e3eaea3SApple OSS Distributions #define LOWER 0
38*5e3eaea3SApple OSS Distributions #define RAISE 1
39*5e3eaea3SApple OSS Distributions
40*5e3eaea3SApple OSS Distributions static struct rlimit orig_rlimit[RLIMIT_NLIMITS];
41*5e3eaea3SApple OSS Distributions
42*5e3eaea3SApple OSS Distributions /* Maximum number of open files allowed by normal user */
43*5e3eaea3SApple OSS Distributions static rlim_t maxfilesperproc;
44*5e3eaea3SApple OSS Distributions static size_t maxfilesperproc_size = sizeof(maxfilesperproc);
45*5e3eaea3SApple OSS Distributions
46*5e3eaea3SApple OSS Distributions /* Maximum number of open files allowed by super user */
47*5e3eaea3SApple OSS Distributions static rlim_t maxfiles;
48*5e3eaea3SApple OSS Distributions static size_t maxfiles_size = sizeof(maxfiles);
49*5e3eaea3SApple OSS Distributions
50*5e3eaea3SApple OSS Distributions /* Maximum number of simultaneous processes allowed by normal user */
51*5e3eaea3SApple OSS Distributions static rlim_t maxprocperuid;
52*5e3eaea3SApple OSS Distributions static size_t maxprocperuid_size = sizeof(maxprocperuid);
53*5e3eaea3SApple OSS Distributions
54*5e3eaea3SApple OSS Distributions /* Maximum number of simultaneous processes allowed by super user */
55*5e3eaea3SApple OSS Distributions static rlim_t maxproc;
56*5e3eaea3SApple OSS Distributions static size_t maxproc_size = sizeof(maxproc);
57*5e3eaea3SApple OSS Distributions
58*5e3eaea3SApple OSS Distributions static bool superuser = FALSE;
59*5e3eaea3SApple OSS Distributions
60*5e3eaea3SApple OSS Distributions static int
get_initial_rlimits(void)61*5e3eaea3SApple OSS Distributions get_initial_rlimits(void)
62*5e3eaea3SApple OSS Distributions {
63*5e3eaea3SApple OSS Distributions int err = -1;
64*5e3eaea3SApple OSS Distributions int i;
65*5e3eaea3SApple OSS Distributions
66*5e3eaea3SApple OSS Distributions for (i = 0; i < RLIMIT_NLIMITS; i++) {
67*5e3eaea3SApple OSS Distributions err = getrlimit(i, &orig_rlimit[i]);
68*5e3eaea3SApple OSS Distributions T_QUIET; T_EXPECT_EQ(0, err, "getrlimit(%15s, soft: 0x%16llx, hard 0x%16llx) %s", RESOURCE_STRING[i], orig_rlimit[i].rlim_cur, orig_rlimit[i].rlim_max, err == 0 ? "" : strerror(errno));
69*5e3eaea3SApple OSS Distributions }
70*5e3eaea3SApple OSS Distributions return err;
71*5e3eaea3SApple OSS Distributions }
72*5e3eaea3SApple OSS Distributions
73*5e3eaea3SApple OSS Distributions static void
print_rlimits(bool initial_limits)74*5e3eaea3SApple OSS Distributions print_rlimits(bool initial_limits)
75*5e3eaea3SApple OSS Distributions {
76*5e3eaea3SApple OSS Distributions int err;
77*5e3eaea3SApple OSS Distributions int i;
78*5e3eaea3SApple OSS Distributions
79*5e3eaea3SApple OSS Distributions for (i = 0; i < RLIMIT_NLIMITS; i++) {
80*5e3eaea3SApple OSS Distributions struct rlimit lim;
81*5e3eaea3SApple OSS Distributions
82*5e3eaea3SApple OSS Distributions if (initial_limits) {
83*5e3eaea3SApple OSS Distributions lim = orig_rlimit[i];
84*5e3eaea3SApple OSS Distributions } else {
85*5e3eaea3SApple OSS Distributions err = getrlimit(i, &lim);
86*5e3eaea3SApple OSS Distributions T_QUIET; T_EXPECT_EQ(0, err, "getrlimit(%15s, soft: 0x%16llx, hard 0x%16llx) %s", RESOURCE_STRING[i], lim.rlim_cur, lim.rlim_max, err == 0 ? "" : strerror(errno));
87*5e3eaea3SApple OSS Distributions }
88*5e3eaea3SApple OSS Distributions T_LOG("%35s soft: 0x%16llx hard 0x%16llx", RESOURCE_STRING[i], lim.rlim_cur, lim.rlim_max);
89*5e3eaea3SApple OSS Distributions }
90*5e3eaea3SApple OSS Distributions }
91*5e3eaea3SApple OSS Distributions
92*5e3eaea3SApple OSS Distributions /*
93*5e3eaea3SApple OSS Distributions * Change "limit_type" of all of the process's "rlimit" by amount
94*5e3eaea3SApple OSS Distributions *
95*5e3eaea3SApple OSS Distributions * limit_type: SOFT_LIMIT/HARD_LIMIT
96*5e3eaea3SApple OSS Distributions * amount: rlim_t
97*5e3eaea3SApple OSS Distributions * action: RAISE/LOWER
98*5e3eaea3SApple OSS Distributions */
99*5e3eaea3SApple OSS Distributions static void
change_rlimits(int limit_type,rlim_t amount,int action)100*5e3eaea3SApple OSS Distributions change_rlimits(int limit_type, rlim_t amount, int action)
101*5e3eaea3SApple OSS Distributions {
102*5e3eaea3SApple OSS Distributions int err = -1;
103*5e3eaea3SApple OSS Distributions int i;
104*5e3eaea3SApple OSS Distributions
105*5e3eaea3SApple OSS Distributions for (i = 0; i < RLIMIT_NLIMITS; i++) {
106*5e3eaea3SApple OSS Distributions struct rlimit newlim; // for setrlimit
107*5e3eaea3SApple OSS Distributions struct rlimit verifylim; // for getrlimit
108*5e3eaea3SApple OSS Distributions bool expect_failure = FALSE;
109*5e3eaea3SApple OSS Distributions int expect_errno = 0;
110*5e3eaea3SApple OSS Distributions
111*5e3eaea3SApple OSS Distributions /* Get the current limit values */
112*5e3eaea3SApple OSS Distributions err = getrlimit(i, &newlim);
113*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(0, err, "getrlimit(%15s, soft: 0x%16llx, hard 0x%16llx) %s", RESOURCE_STRING[i], newlim.rlim_cur, newlim.rlim_max, err == 0 ? "" : strerror(errno));
114*5e3eaea3SApple OSS Distributions
115*5e3eaea3SApple OSS Distributions /* Changing soft limit */
116*5e3eaea3SApple OSS Distributions if (limit_type == SOFT_LIMIT) {
117*5e3eaea3SApple OSS Distributions if (action == RAISE) {
118*5e3eaea3SApple OSS Distributions /* Raising soft limits to exceed hard limits is not allowed and we expect to see failure on setrlimit call later */
119*5e3eaea3SApple OSS Distributions if (newlim.rlim_cur + amount > newlim.rlim_max) {
120*5e3eaea3SApple OSS Distributions expect_failure = TRUE;
121*5e3eaea3SApple OSS Distributions expect_errno = EINVAL;
122*5e3eaea3SApple OSS Distributions }
123*5e3eaea3SApple OSS Distributions newlim.rlim_cur += amount;
124*5e3eaea3SApple OSS Distributions } else if (action == LOWER) {
125*5e3eaea3SApple OSS Distributions if (newlim.rlim_cur == 0) {
126*5e3eaea3SApple OSS Distributions /* Soft limit might be 0 already, if so skip lowering it */
127*5e3eaea3SApple OSS Distributions } else {
128*5e3eaea3SApple OSS Distributions newlim.rlim_cur -= amount;
129*5e3eaea3SApple OSS Distributions }
130*5e3eaea3SApple OSS Distributions } else {
131*5e3eaea3SApple OSS Distributions T_FAIL("Unknown action on soft limit: %d", action);
132*5e3eaea3SApple OSS Distributions }
133*5e3eaea3SApple OSS Distributions }
134*5e3eaea3SApple OSS Distributions /* Changing hard limit */
135*5e3eaea3SApple OSS Distributions else if (limit_type == HARD_LIMIT) {
136*5e3eaea3SApple OSS Distributions if (action == RAISE) {
137*5e3eaea3SApple OSS Distributions newlim.rlim_max += amount;
138*5e3eaea3SApple OSS Distributions
139*5e3eaea3SApple OSS Distributions /* Raising hard limits is not allowed for normal user and we expect to see failure on setrlimit call later */
140*5e3eaea3SApple OSS Distributions expect_failure = TRUE;
141*5e3eaea3SApple OSS Distributions expect_errno = EPERM;
142*5e3eaea3SApple OSS Distributions } else if (action == LOWER) {
143*5e3eaea3SApple OSS Distributions if (newlim.rlim_max == 0) {
144*5e3eaea3SApple OSS Distributions /* Hard limit might be 0 already, if so skip lowering it (e.g., RLIMIT_CORE on iOS) */
145*5e3eaea3SApple OSS Distributions } else {
146*5e3eaea3SApple OSS Distributions newlim.rlim_max -= amount;
147*5e3eaea3SApple OSS Distributions }
148*5e3eaea3SApple OSS Distributions /* Soft limit might need to be changed as well since soft cannot be greater than hard */
149*5e3eaea3SApple OSS Distributions if (newlim.rlim_cur > newlim.rlim_max) {
150*5e3eaea3SApple OSS Distributions newlim.rlim_cur = newlim.rlim_max;
151*5e3eaea3SApple OSS Distributions }
152*5e3eaea3SApple OSS Distributions } else {
153*5e3eaea3SApple OSS Distributions T_FAIL("Unknown action on hard limit: %d", action);
154*5e3eaea3SApple OSS Distributions }
155*5e3eaea3SApple OSS Distributions }
156*5e3eaea3SApple OSS Distributions /* Changing unknown limit type */
157*5e3eaea3SApple OSS Distributions else {
158*5e3eaea3SApple OSS Distributions T_FAIL("Unknown limit type: %d", limit_type);
159*5e3eaea3SApple OSS Distributions }
160*5e3eaea3SApple OSS Distributions
161*5e3eaea3SApple OSS Distributions /* Request the kernel to change limit values */
162*5e3eaea3SApple OSS Distributions err = setrlimit(i, &newlim);
163*5e3eaea3SApple OSS Distributions
164*5e3eaea3SApple OSS Distributions if (expect_failure) {
165*5e3eaea3SApple OSS Distributions /* We expect the setrlimit call to fail */
166*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(-1, err, "setrlimit(%15s, soft: 0x%16llx, hard 0x%16llx) failed as expected: %s", RESOURCE_STRING[i], newlim.rlim_cur, newlim.rlim_max, strerror(errno));
167*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(expect_errno, errno, "Expect errno %d, errno returned %d", expect_errno, errno);
168*5e3eaea3SApple OSS Distributions continue;
169*5e3eaea3SApple OSS Distributions } else {
170*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(0, err, "setrlimit(%15s, soft: 0x%16llx, hard 0x%16llx) %s", RESOURCE_STRING[i], newlim.rlim_cur, newlim.rlim_max, err == 0 ? "" : strerror(errno));
171*5e3eaea3SApple OSS Distributions }
172*5e3eaea3SApple OSS Distributions
173*5e3eaea3SApple OSS Distributions /* Verify the kernel correctly changed the limit values */
174*5e3eaea3SApple OSS Distributions err = getrlimit(i, &verifylim);
175*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(0, err, "getrlimit(%15s, soft: 0x%16llx, hard 0x%16llx) %s", RESOURCE_STRING[i], verifylim.rlim_cur, verifylim.rlim_max, err == 0 ? "" : strerror(errno));
176*5e3eaea3SApple OSS Distributions
177*5e3eaea3SApple OSS Distributions /* The kernel forces the hard limit of RLIMIT_NOFILE to be at most maxfileperproc for normal user when changing the hard limit with setrlimit */
178*5e3eaea3SApple OSS Distributions if (i == RLIMIT_NOFILE && limit_type == HARD_LIMIT && newlim.rlim_max > maxfilesperproc) {
179*5e3eaea3SApple OSS Distributions if (newlim.rlim_cur != verifylim.rlim_cur ||
180*5e3eaea3SApple OSS Distributions maxfilesperproc != verifylim.rlim_max) {
181*5e3eaea3SApple OSS Distributions T_FAIL("Mismatch limit values %s despite a successful setrlimit call (setrlimit'd soft 0x%16llx hard 0x%16llx but getrlimit'd soft 0x%16llx hard 0x%16llx)",
182*5e3eaea3SApple OSS Distributions RESOURCE_STRING[i], newlim.rlim_cur, newlim.rlim_max, verifylim.rlim_cur, verifylim.rlim_max);
183*5e3eaea3SApple OSS Distributions }
184*5e3eaea3SApple OSS Distributions }
185*5e3eaea3SApple OSS Distributions /* The kernel forces the hard limit of RLIMIT_NPROC to be at most maxproc for normal user when changing either soft/hard limit with setrlimit */
186*5e3eaea3SApple OSS Distributions else if (i == RLIMIT_NPROC && newlim.rlim_max > maxprocperuid) {
187*5e3eaea3SApple OSS Distributions if (newlim.rlim_cur != verifylim.rlim_cur ||
188*5e3eaea3SApple OSS Distributions maxprocperuid != verifylim.rlim_max) {
189*5e3eaea3SApple OSS Distributions T_FAIL("Mismatch limit values %s despite a successful setrlimit call (setrlimit'd soft 0x%16llx hard 0x%16llx but getrlimit'd soft 0x%16llx hard 0x%16llx)",
190*5e3eaea3SApple OSS Distributions RESOURCE_STRING[i], newlim.rlim_cur, newlim.rlim_max, verifylim.rlim_cur, verifylim.rlim_max);
191*5e3eaea3SApple OSS Distributions }
192*5e3eaea3SApple OSS Distributions } else {
193*5e3eaea3SApple OSS Distributions if (newlim.rlim_cur != verifylim.rlim_cur ||
194*5e3eaea3SApple OSS Distributions newlim.rlim_max != verifylim.rlim_max) {
195*5e3eaea3SApple OSS Distributions T_FAIL("Mismatch limit values %s despite a successful setrlimit call (setrlimit'd soft 0x%16llx hard 0x%16llx but getrlimit'd soft 0x%16llx hard 0x%16llx)",
196*5e3eaea3SApple OSS Distributions RESOURCE_STRING[i], newlim.rlim_cur, newlim.rlim_max, verifylim.rlim_cur, verifylim.rlim_max);
197*5e3eaea3SApple OSS Distributions }
198*5e3eaea3SApple OSS Distributions }
199*5e3eaea3SApple OSS Distributions }
200*5e3eaea3SApple OSS Distributions }
201*5e3eaea3SApple OSS Distributions
202*5e3eaea3SApple OSS Distributions T_DECL(proc_rlimit,
203*5e3eaea3SApple OSS Distributions "Test basic functionalities of the getrlimit and setrlimit")
204*5e3eaea3SApple OSS Distributions {
205*5e3eaea3SApple OSS Distributions int err;
206*5e3eaea3SApple OSS Distributions struct rlimit lim;
207*5e3eaea3SApple OSS Distributions
208*5e3eaea3SApple OSS Distributions T_SETUPBEGIN;
209*5e3eaea3SApple OSS Distributions
210*5e3eaea3SApple OSS Distributions if (geteuid() == 0) {
211*5e3eaea3SApple OSS Distributions superuser = TRUE;
212*5e3eaea3SApple OSS Distributions T_SKIP("This test should not be run as super user.");
213*5e3eaea3SApple OSS Distributions }
214*5e3eaea3SApple OSS Distributions
215*5e3eaea3SApple OSS Distributions /* Use sysctl to query the real limits of RLIMIT_NOFILE/RLIMIT_NPROC for normal user on Apple's systems */
216*5e3eaea3SApple OSS Distributions err = sysctlbyname("kern.maxfilesperproc", &maxfilesperproc, &maxfilesperproc_size, NULL, 0);
217*5e3eaea3SApple OSS Distributions T_EXPECT_EQ_INT(0, err, "maxfilesperproc: %llu", maxfilesperproc);
218*5e3eaea3SApple OSS Distributions
219*5e3eaea3SApple OSS Distributions err = sysctlbyname("kern.maxprocperuid", &maxprocperuid, &maxprocperuid_size, NULL, 0);
220*5e3eaea3SApple OSS Distributions T_EXPECT_EQ_INT(0, err, "maxprocperuid: %llu", maxprocperuid);
221*5e3eaea3SApple OSS Distributions
222*5e3eaea3SApple OSS Distributions /* Use sysctl to query the real limits of RLIMIT_NOFILE/RLIMIT_NPROC for super user on Apple's systems (placeholder for adding super user tests) */
223*5e3eaea3SApple OSS Distributions err = sysctlbyname("kern.maxfiles", &maxfiles, &maxfiles_size, NULL, 0);
224*5e3eaea3SApple OSS Distributions T_EXPECT_EQ_INT(0, err, "maxfiles: %llu", maxfiles);
225*5e3eaea3SApple OSS Distributions
226*5e3eaea3SApple OSS Distributions err = sysctlbyname("kern.maxproc", &maxproc, &maxproc_size, NULL, 0);
227*5e3eaea3SApple OSS Distributions T_EXPECT_EQ_INT(0, err, "maxproc: %llu", maxproc);
228*5e3eaea3SApple OSS Distributions
229*5e3eaea3SApple OSS Distributions /* Issue getrlimit syscall to retrieve the initial resource limit values before calling setrlimit */
230*5e3eaea3SApple OSS Distributions err = get_initial_rlimits();
231*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(0, err, "Obtained initial resource values.");
232*5e3eaea3SApple OSS Distributions
233*5e3eaea3SApple OSS Distributions /* Print out resource limit values to stdout for less-painful triage in case needed */
234*5e3eaea3SApple OSS Distributions T_LOG("Resource limits before the test:");
235*5e3eaea3SApple OSS Distributions print_rlimits(TRUE);
236*5e3eaea3SApple OSS Distributions
237*5e3eaea3SApple OSS Distributions T_SETUPEND;
238*5e3eaea3SApple OSS Distributions
239*5e3eaea3SApple OSS Distributions /* Lower soft limits by arbitrary amount */
240*5e3eaea3SApple OSS Distributions T_LOG("---------Lowering soft limits by 0x%x---------:\n", LIMIT_DIFF);
241*5e3eaea3SApple OSS Distributions change_rlimits(SOFT_LIMIT, LIMIT_DIFF, LOWER);
242*5e3eaea3SApple OSS Distributions
243*5e3eaea3SApple OSS Distributions /* Raise soft limits back to the orginal values */
244*5e3eaea3SApple OSS Distributions T_LOG("---------Raising soft limits by 0x%x---------:\n", LIMIT_DIFF);
245*5e3eaea3SApple OSS Distributions change_rlimits(SOFT_LIMIT, LIMIT_DIFF, RAISE);
246*5e3eaea3SApple OSS Distributions
247*5e3eaea3SApple OSS Distributions /* Lower hard limits */
248*5e3eaea3SApple OSS Distributions T_LOG("---------Lowering hard limits by 0x%x---------:", LIMIT_DIFF);
249*5e3eaea3SApple OSS Distributions change_rlimits(HARD_LIMIT, LIMIT_DIFF, LOWER);
250*5e3eaea3SApple OSS Distributions
251*5e3eaea3SApple OSS Distributions /* Raise soft limits to exceed hard limits (setrlimit should fail, but the darwintest should pass) */
252*5e3eaea3SApple OSS Distributions T_LOG("---------Attempting to raised soft limits by 0x%x to exceed hard limits---------:", LIMIT_DIFF);
253*5e3eaea3SApple OSS Distributions change_rlimits(SOFT_LIMIT, LIMIT_DIFF, RAISE);
254*5e3eaea3SApple OSS Distributions
255*5e3eaea3SApple OSS Distributions /* Raise hard limits (setrlimit should fail, but the darwintest should pass) */
256*5e3eaea3SApple OSS Distributions T_LOG("---------Attempting to raise hard limits by 0x%x---------:", LIMIT_DIFF);
257*5e3eaea3SApple OSS Distributions change_rlimits(HARD_LIMIT, LIMIT_DIFF, RAISE);
258*5e3eaea3SApple OSS Distributions
259*5e3eaea3SApple OSS Distributions /* Get and set a non-existing resource limit */
260*5e3eaea3SApple OSS Distributions T_LOG("---------Accessing a non-existing resource---------:");
261*5e3eaea3SApple OSS Distributions err = getrlimit(RLIMIT_NLIMITS + 1, &lim);
262*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(-1, err, "Expect getrlimit to fail when accessing a non-existing resource: %s\n", strerror(errno));
263*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(EINVAL, errno, "Expect errno %d, errno returned %d", EINVAL, errno);
264*5e3eaea3SApple OSS Distributions
265*5e3eaea3SApple OSS Distributions err = setrlimit(RLIMIT_NLIMITS + 1, &lim);
266*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(-1, err, "Expect setrlimit to fail when accessing a non-existing resource: %s\n", strerror(errno));
267*5e3eaea3SApple OSS Distributions T_EXPECT_EQ(EINVAL, errno, "Expect errno %d, errno returned %d", EINVAL, errno);
268*5e3eaea3SApple OSS Distributions
269*5e3eaea3SApple OSS Distributions T_LOG("Resource limits after the test:");
270*5e3eaea3SApple OSS Distributions print_rlimits(FALSE);
271*5e3eaea3SApple OSS Distributions }
272