1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Linux Test Project, 2010-2020
4 */
5
6 #define _GNU_SOURCE
7 #include <sys/types.h>
8 #include <sys/mman.h>
9 #include <sys/resource.h>
10 #include <sys/stat.h>
11 #include <sys/wait.h>
12 #include <sys/mount.h>
13 #include <sys/xattr.h>
14 #include <sys/sysinfo.h>
15 #include <errno.h>
16 #include <libgen.h>
17 #include <limits.h>
18 #include <pwd.h>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <malloc.h>
23 #include <math.h>
24 #include "lapi/fcntl.h"
25 #include "test.h"
26 #include "safe_macros.h"
27
safe_basename(const char * file,const int lineno,void (* cleanup_fn)(void),char * path)28 char *safe_basename(const char *file, const int lineno,
29 void (*cleanup_fn) (void), char *path)
30 {
31 char *rval;
32
33 rval = basename(path);
34
35 if (rval == NULL) {
36 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
37 "basename(%s) failed", path);
38 }
39
40 return rval;
41 }
42
43 int
safe_chdir(const char * file,const int lineno,void (* cleanup_fn)(void),const char * path)44 safe_chdir(const char *file, const int lineno, void (*cleanup_fn) (void),
45 const char *path)
46 {
47 int rval;
48
49 rval = chdir(path);
50
51 if (rval == -1) {
52 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
53 "chdir(%s) failed", path);
54 } else if (rval) {
55 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
56 "Invalid chdir(%s) return value %d", path, rval);
57 }
58
59 return rval;
60 }
61
62 int
safe_close(const char * file,const int lineno,void (* cleanup_fn)(void),int fildes)63 safe_close(const char *file, const int lineno, void (*cleanup_fn) (void),
64 int fildes)
65 {
66 int rval;
67
68 rval = close(fildes);
69
70 if (rval == -1) {
71 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
72 "close(%d) failed", fildes);
73 } else if (rval) {
74 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
75 "Invalid close(%d) return value %d", fildes, rval);
76 }
77
78 return rval;
79 }
80
81 int
safe_creat(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname,mode_t mode)82 safe_creat(const char *file, const int lineno, void (*cleanup_fn) (void),
83 const char *pathname, mode_t mode)
84 {
85 int rval;
86
87 rval = creat(pathname, mode);
88
89 if (rval == -1) {
90 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
91 "creat(%s,%04o) failed", pathname, mode);
92 } else if (rval < 0) {
93 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
94 "Invalid creat(%s,%04o) return value %d", pathname,
95 mode, rval);
96 }
97
98 return rval;
99 }
100
safe_dirname(const char * file,const int lineno,void (* cleanup_fn)(void),char * path)101 char *safe_dirname(const char *file, const int lineno,
102 void (*cleanup_fn) (void), char *path)
103 {
104 char *rval;
105
106 rval = dirname(path);
107
108 if (rval == NULL) {
109 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
110 "dirname(%s) failed", path);
111 }
112
113 return rval;
114 }
115
safe_getcwd(const char * file,const int lineno,void (* cleanup_fn)(void),char * buf,size_t size)116 char *safe_getcwd(const char *file, const int lineno, void (*cleanup_fn) (void),
117 char *buf, size_t size)
118 {
119 char *rval;
120
121 rval = getcwd(buf, size);
122
123 if (rval == NULL) {
124 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
125 "getcwd(%p,%zu) failed", buf, size);
126 }
127
128 return rval;
129 }
130
safe_getpwnam(const char * file,const int lineno,void (* cleanup_fn)(void),const char * name)131 struct passwd *safe_getpwnam(const char *file, const int lineno,
132 void (*cleanup_fn) (void), const char *name)
133 {
134 struct passwd *rval;
135
136 rval = getpwnam(name);
137
138 if (rval == NULL) {
139 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
140 "getpwnam(%s) failed", name);
141 }
142
143 return rval;
144 }
145
146 int
safe_getrusage(const char * file,const int lineno,void (* cleanup_fn)(void),int who,struct rusage * usage)147 safe_getrusage(const char *file, const int lineno, void (*cleanup_fn) (void),
148 int who, struct rusage *usage)
149 {
150 int rval;
151
152 rval = getrusage(who, usage);
153
154 if (rval == -1) {
155 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
156 "getrusage(%d,%p) failed", who, usage);
157 } else if (rval) {
158 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
159 "Invalid getrusage(%d,%p) return value %d", who,
160 usage, rval);
161 }
162
163 return rval;
164 }
165
safe_malloc(const char * file,const int lineno,void (* cleanup_fn)(void),size_t size)166 void *safe_malloc(const char *file, const int lineno, void (*cleanup_fn) (void),
167 size_t size)
168 {
169 void *rval;
170
171 rval = malloc(size);
172
173 if (rval == NULL) {
174 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
175 "malloc(%zu) failed", size);
176 }
177
178 return rval;
179 }
180
safe_mkdir(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname,mode_t mode)181 int safe_mkdir(const char *file, const int lineno, void (*cleanup_fn) (void),
182 const char *pathname, mode_t mode)
183 {
184 int rval;
185
186 rval = mkdir(pathname, mode);
187
188 if (rval == -1) {
189 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
190 "mkdir(%s, %04o) failed", pathname, mode);
191 } else if (rval) {
192 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
193 "Invalid mkdir(%s, %04o) return value %d", pathname,
194 mode, rval);
195 }
196
197 return (rval);
198 }
199
safe_rmdir(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname)200 int safe_rmdir(const char *file, const int lineno, void (*cleanup_fn) (void),
201 const char *pathname)
202 {
203 int rval;
204
205 rval = rmdir(pathname);
206
207 if (rval == -1) {
208 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
209 "rmdir(%s) failed", pathname);
210 } else if (rval) {
211 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
212 "Invalid rmdir(%s) return value %d", pathname, rval);
213 }
214
215 return (rval);
216 }
217
safe_munmap(const char * file,const int lineno,void (* cleanup_fn)(void),void * addr,size_t length)218 int safe_munmap(const char *file, const int lineno, void (*cleanup_fn) (void),
219 void *addr, size_t length)
220 {
221 int rval;
222
223 rval = munmap(addr, length);
224
225 if (rval == -1) {
226 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
227 "munmap(%p,%zu) failed", addr, length);
228 } else if (rval) {
229 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
230 "Invalid munmap(%p,%zu) return value %d", addr,
231 length, rval);
232 }
233
234 return rval;
235 }
236
safe_open(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname,int oflags,...)237 int safe_open(const char *file, const int lineno, void (*cleanup_fn) (void),
238 const char *pathname, int oflags, ...)
239 {
240 int rval;
241 mode_t mode = 0;
242
243 if (TST_OPEN_NEEDS_MODE(oflags)) {
244 va_list ap;
245
246 va_start(ap, oflags);
247
248 /* Android's NDK's mode_t is smaller than an int, which results in
249 * SIGILL here when passing the mode_t type.
250 */
251 mode = va_arg(ap, int);
252
253 va_end(ap);
254 }
255
256 rval = open(pathname, oflags, mode);
257
258 if (rval == -1) {
259 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
260 "open(%s,%d,%04o) failed", pathname, oflags, mode);
261 } else if (rval < 0) {
262 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
263 "Invalid open(%s,%d,%04o) return value %d", pathname,
264 oflags, mode, rval);
265 }
266
267 return rval;
268 }
269
safe_pipe(const char * file,const int lineno,void (* cleanup_fn)(void),int fildes[2])270 int safe_pipe(const char *file, const int lineno, void (*cleanup_fn) (void),
271 int fildes[2])
272 {
273 int rval;
274
275 rval = pipe(fildes);
276
277 if (rval == -1) {
278 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
279 "pipe({%d,%d}) failed", fildes[0], fildes[1]);
280 } else if (rval) {
281 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
282 "Invalid pipe({%d,%d}) return value %d", fildes[0],
283 fildes[1], rval);
284 }
285
286 return rval;
287 }
288
safe_read(const char * file,const int lineno,void (* cleanup_fn)(void),char len_strict,int fildes,void * buf,size_t nbyte)289 ssize_t safe_read(const char *file, const int lineno, void (*cleanup_fn) (void),
290 char len_strict, int fildes, void *buf, size_t nbyte)
291 {
292 ssize_t rval;
293
294 rval = read(fildes, buf, nbyte);
295
296 if (rval == -1 || (len_strict && (size_t)rval != nbyte)) {
297 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
298 "read(%d,%p,%zu) failed, returned %zd", fildes, buf,
299 nbyte, rval);
300 } else if (rval < 0) {
301 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
302 "Invalid read(%d,%p,%zu) return value %zd", fildes,
303 buf, nbyte, rval);
304 }
305
306 return rval;
307 }
308
safe_setegid(const char * file,const int lineno,void (* cleanup_fn)(void),gid_t egid)309 int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void),
310 gid_t egid)
311 {
312 int rval;
313
314 rval = setegid(egid);
315
316 if (rval == -1) {
317 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
318 "setegid(%u) failed", (unsigned int)egid);
319 } else if (rval) {
320 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
321 "Invalid setegid(%u) return value %d",
322 (unsigned int)egid, rval);
323 }
324
325 return rval;
326 }
327
safe_seteuid(const char * file,const int lineno,void (* cleanup_fn)(void),uid_t euid)328 int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void),
329 uid_t euid)
330 {
331 int rval;
332
333 rval = seteuid(euid);
334
335 if (rval == -1) {
336 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
337 "seteuid(%u) failed", (unsigned int)euid);
338 } else if (rval) {
339 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
340 "Invalid seteuid(%u) return value %d",
341 (unsigned int)euid, rval);
342 }
343
344 return rval;
345 }
346
safe_setgid(const char * file,const int lineno,void (* cleanup_fn)(void),gid_t gid)347 int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void),
348 gid_t gid)
349 {
350 int rval;
351
352 rval = setgid(gid);
353
354 if (rval == -1) {
355 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
356 "setgid(%u) failed", (unsigned int)gid);
357 } else if (rval) {
358 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
359 "Invalid setgid(%u) return value %d",
360 (unsigned int)gid, rval);
361 }
362
363 return rval;
364 }
365
safe_setuid(const char * file,const int lineno,void (* cleanup_fn)(void),uid_t uid)366 int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void),
367 uid_t uid)
368 {
369 int rval;
370
371 rval = setuid(uid);
372
373 if (rval == -1) {
374 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
375 "setuid(%u) failed", (unsigned int)uid);
376 } else if (rval) {
377 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
378 "Invalid setuid(%u) return value %d",
379 (unsigned int)uid, rval);
380 }
381
382 return rval;
383 }
384
safe_getresuid(const char * file,const int lineno,void (* cleanup_fn)(void),uid_t * ruid,uid_t * euid,uid_t * suid)385 int safe_getresuid(const char *file, const int lineno, void (*cleanup_fn)(void),
386 uid_t *ruid, uid_t *euid, uid_t *suid)
387 {
388 int rval;
389
390 rval = getresuid(ruid, euid, suid);
391
392 if (rval == -1) {
393 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
394 "getresuid(%p, %p, %p) failed", ruid, euid, suid);
395 } else if (rval) {
396 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
397 "Invalid getresuid(%p, %p, %p) return value %d", ruid,
398 euid, suid, rval);
399 }
400
401 return rval;
402 }
403
safe_getresgid(const char * file,const int lineno,void (* cleanup_fn)(void),gid_t * rgid,gid_t * egid,gid_t * sgid)404 int safe_getresgid(const char *file, const int lineno, void (*cleanup_fn)(void),
405 gid_t *rgid, gid_t *egid, gid_t *sgid)
406 {
407 int rval;
408
409 rval = getresgid(rgid, egid, sgid);
410
411 if (rval == -1) {
412 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
413 "getresgid(%p, %p, %p) failed", rgid, egid, sgid);
414 } else if (rval) {
415 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
416 "Invalid getresgid(%p, %p, %p) return value %d", rgid,
417 egid, sgid, rval);
418 }
419
420 return rval;
421 }
422
safe_unlink(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname)423 int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void),
424 const char *pathname)
425 {
426 int rval;
427
428 rval = unlink(pathname);
429
430 if (rval == -1) {
431 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
432 "unlink(%s) failed", pathname);
433 } else if (rval) {
434 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
435 "Invalid unlink(%s) return value %d", pathname, rval);
436 }
437
438 return rval;
439 }
440
441
safe_link(const char * file,const int lineno,void (cleanup_fn)(void),const char * oldpath,const char * newpath)442 int safe_link(const char *file, const int lineno,
443 void (cleanup_fn)(void), const char *oldpath,
444 const char *newpath)
445 {
446 int rval;
447
448 rval = link(oldpath, newpath);
449
450 if (rval == -1) {
451 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
452 "link(%s,%s) failed", oldpath, newpath);
453 } else if (rval) {
454 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
455 "Invalid link(%s,%s) return value %d", oldpath,
456 newpath, rval);
457 }
458
459 return rval;
460 }
461
safe_linkat(const char * file,const int lineno,void (cleanup_fn)(void),int olddirfd,const char * oldpath,int newdirfd,const char * newpath,int flags)462 int safe_linkat(const char *file, const int lineno,
463 void (cleanup_fn)(void), int olddirfd, const char *oldpath,
464 int newdirfd, const char *newpath, int flags)
465 {
466 int rval;
467
468 rval = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
469
470 if (rval == -1) {
471 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
472 "linkat(%d,%s,%d,%s,%d) failed", olddirfd, oldpath,
473 newdirfd, newpath, flags);
474 } else if (rval) {
475 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
476 "Invalid linkat(%d,%s,%d,%s,%d) return value %d",
477 olddirfd, oldpath, newdirfd, newpath, flags, rval);
478 }
479
480 return rval;
481 }
482
safe_readlink(const char * file,const int lineno,void (cleanup_fn)(void),const char * path,char * buf,size_t bufsize)483 ssize_t safe_readlink(const char *file, const int lineno,
484 void (cleanup_fn)(void), const char *path,
485 char *buf, size_t bufsize)
486 {
487 ssize_t rval;
488
489 rval = readlink(path, buf, bufsize);
490
491 if (rval == -1) {
492 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
493 "readlink(%s,%p,%zu) failed", path, buf, bufsize);
494 } else if (rval < 0) {
495 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
496 "Invalid readlink(%s,%p,%zu) return value %zd", path,
497 buf, bufsize, rval);
498 } else {
499 /* readlink does not append a NUL byte to the buffer.
500 * Add it now. */
501 if ((size_t) rval < bufsize)
502 buf[rval] = '\0';
503 else
504 buf[bufsize-1] = '\0';
505 }
506
507 return rval;
508 }
509
safe_symlink(const char * file,const int lineno,void (cleanup_fn)(void),const char * oldpath,const char * newpath)510 int safe_symlink(const char *file, const int lineno,
511 void (cleanup_fn)(void), const char *oldpath,
512 const char *newpath)
513 {
514 int rval;
515
516 rval = symlink(oldpath, newpath);
517
518 if (rval == -1) {
519 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
520 "symlink(%s,%s) failed", oldpath, newpath);
521 } else if (rval) {
522 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
523 "Invalid symlink(%s,%s) return value %d", oldpath,
524 newpath, rval);
525 }
526
527 return rval;
528 }
529
safe_write(const char * file,const int lineno,void (cleanup_fn)(void),enum safe_write_opts len_strict,int fildes,const void * buf,size_t nbyte)530 ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void),
531 enum safe_write_opts len_strict, int fildes, const void *buf,
532 size_t nbyte)
533 {
534 ssize_t rval;
535 const void *wbuf = buf;
536 size_t len = nbyte;
537 int iter = 0;
538
539 do {
540 iter++;
541 rval = write(fildes, wbuf, len);
542 if (rval == -1) {
543 if (len_strict == SAFE_WRITE_RETRY)
544 tst_resm_(file, lineno, TINFO,
545 "write() wrote %zu bytes in %d calls",
546 nbyte-len, iter);
547 tst_brkm_(file, lineno, TBROK | TERRNO,
548 cleanup_fn, "write(%d,%p,%zu) failed",
549 fildes, buf, nbyte);
550 }
551
552 if (len_strict == SAFE_WRITE_ANY)
553 return rval;
554
555 if (len_strict == SAFE_WRITE_ALL) {
556 if ((size_t)rval != nbyte)
557 tst_brkm_(file, lineno, TBROK | TERRNO,
558 cleanup_fn, "short write(%d,%p,%zu) "
559 "return value %zd",
560 fildes, buf, nbyte, rval);
561 return rval;
562 }
563
564 wbuf += rval;
565 len -= rval;
566 } while (len > 0);
567
568 return rval;
569 }
570
safe_strtol(const char * file,const int lineno,void (cleanup_fn)(void),char * str,long min,long max)571 long safe_strtol(const char *file, const int lineno,
572 void (cleanup_fn) (void), char *str, long min, long max)
573 {
574 long rval;
575 char *endptr;
576
577 errno = 0;
578 rval = strtol(str, &endptr, 10);
579
580 if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN))
581 || (errno != 0 && rval == 0)) {
582 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
583 "strtol(%s) failed", str);
584 return rval;
585 }
586
587 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
588 tst_brkm_(file, lineno, TBROK, cleanup_fn,
589 "strtol(%s): Invalid value", str);
590 return 0;
591 }
592
593 if (rval > max || rval < min) {
594 tst_brkm_(file, lineno, TBROK, cleanup_fn,
595 "strtol(%s): %ld is out of range %ld - %ld",
596 str, rval, min, max);
597 return 0;
598 }
599
600 return rval;
601 }
602
safe_strtoul(const char * file,const int lineno,void (cleanup_fn)(void),char * str,unsigned long min,unsigned long max)603 unsigned long safe_strtoul(const char *file, const int lineno,
604 void (cleanup_fn) (void), char *str,
605 unsigned long min, unsigned long max)
606 {
607 unsigned long rval;
608 char *endptr;
609
610 errno = 0;
611 rval = strtoul(str, &endptr, 10);
612
613 if ((errno == ERANGE && rval == ULONG_MAX)
614 || (errno != 0 && rval == 0)) {
615 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
616 "strtoul(%s) failed", str);
617 return rval;
618 }
619
620 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
621 tst_brkm_(file, lineno, TBROK, cleanup_fn,
622 "Invalid value: '%s'", str);
623 return 0;
624 }
625
626 if (rval > max || rval < min) {
627 tst_brkm_(file, lineno, TBROK, cleanup_fn,
628 "strtoul(%s): %lu is out of range %lu - %lu",
629 str, rval, min, max);
630 return 0;
631 }
632
633 return rval;
634 }
635
safe_strtof(const char * file,const int lineno,void (cleanup_fn)(void),char * str,float min,float max)636 float safe_strtof(const char *file, const int lineno,
637 void (cleanup_fn) (void), char *str,
638 float min, float max)
639 {
640 float rval;
641 char *endptr;
642
643 errno = 0;
644 rval = strtof(str, &endptr);
645
646 if (errno) {
647 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
648 "strtof(%s) failed", str);
649 return rval;
650 }
651
652 if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
653 tst_brkm_(file, lineno, TBROK, cleanup_fn,
654 "Invalid value: '%s'", str);
655 return 0;
656 }
657
658 if (rval > max || rval < min) {
659 tst_brkm_(file, lineno, TBROK, cleanup_fn,
660 "strtof(%s): %f is out of range %f - %f",
661 str, rval, min, max);
662 return 0;
663 }
664
665 return rval;
666 }
667
safe_sysconf(const char * file,const int lineno,void (cleanup_fn)(void),int name)668 long safe_sysconf(const char *file, const int lineno,
669 void (cleanup_fn) (void), int name)
670 {
671 long rval;
672
673 errno = 0;
674 rval = sysconf(name);
675
676 if (rval == -1) {
677 if (errno) {
678 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
679 "sysconf(%d) failed", name);
680 } else {
681 tst_resm_(file, lineno, TINFO,
682 "sysconf(%d): queried option is not available or there is no definite limit",
683 name);
684 }
685 }
686
687 return rval;
688 }
689
safe_chmod(const char * file,const int lineno,void (cleanup_fn)(void),const char * path,mode_t mode)690 int safe_chmod(const char *file, const int lineno,
691 void (cleanup_fn)(void), const char *path, mode_t mode)
692 {
693 int rval;
694
695 rval = chmod(path, mode);
696
697 if (rval == -1) {
698 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
699 "chmod(%s,%04o) failed", path, mode);
700 } else if (rval) {
701 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
702 "Invalid chmod(%s,%04o) return value %d", path, mode,
703 rval);
704 }
705
706 return rval;
707 }
708
safe_fchmod(const char * file,const int lineno,void (cleanup_fn)(void),int fd,mode_t mode)709 int safe_fchmod(const char *file, const int lineno,
710 void (cleanup_fn)(void), int fd, mode_t mode)
711 {
712 int rval;
713
714 rval = fchmod(fd, mode);
715
716 if (rval == -1) {
717 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
718 "fchmod(%d,%04o) failed", fd, mode);
719 } else if (rval) {
720 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
721 "Invalid fchmod(%d,%04o) return value %d", fd, mode,
722 rval);
723 }
724
725 return rval;
726 }
727
safe_chown(const char * file,const int lineno,void (cleanup_fn)(void),const char * path,uid_t owner,gid_t group)728 int safe_chown(const char *file, const int lineno, void (cleanup_fn)(void),
729 const char *path, uid_t owner, gid_t group)
730 {
731 int rval;
732
733 rval = chown(path, owner, group);
734
735 if (rval == -1) {
736 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
737 "chown(%s,%d,%d) failed", path, owner, group);
738 } else if (rval) {
739 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
740 "Invalid chown(%s,%d,%d) return value %d", path,
741 owner, group, rval);
742 }
743
744 return rval;
745 }
746
safe_fchown(const char * file,const int lineno,void (cleanup_fn)(void),int fd,uid_t owner,gid_t group)747 int safe_fchown(const char *file, const int lineno, void (cleanup_fn)(void),
748 int fd, uid_t owner, gid_t group)
749 {
750 int rval;
751
752 rval = fchown(fd, owner, group);
753
754 if (rval == -1) {
755 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
756 "fchown(%d,%d,%d) failed", fd, owner, group);
757 } else if (rval) {
758 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
759 "Invalid fchown(%d,%d,%d) return value %d", fd,
760 owner, group, rval);
761 }
762
763 return rval;
764 }
765
safe_wait(const char * file,const int lineno,void (cleanup_fn)(void),int * status)766 pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void),
767 int *status)
768 {
769 pid_t rval;
770
771 rval = wait(status);
772
773 if (rval == -1) {
774 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
775 "wait(%p) failed", status);
776 } else if (rval < 0) {
777 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
778 "Invalid wait(%p) return value %d", status, rval);
779 }
780
781 return rval;
782 }
783
safe_waitpid(const char * file,const int lineno,void (cleanup_fn)(void),pid_t pid,int * status,int opts)784 pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void),
785 pid_t pid, int *status, int opts)
786 {
787 pid_t rval;
788
789 rval = waitpid(pid, status, opts);
790
791 if (rval == -1) {
792 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
793 "waitpid(%d,%p,%d) failed", pid, status, opts);
794 } else if (rval < 0) {
795 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
796 "Invalid waitpid(%d,%p,%d) return value %d", pid,
797 status, opts, rval);
798 }
799
800 return rval;
801 }
802
safe_memalign(const char * file,const int lineno,void (* cleanup_fn)(void),size_t alignment,size_t size)803 void *safe_memalign(const char *file, const int lineno,
804 void (*cleanup_fn) (void), size_t alignment, size_t size)
805 {
806 void *rval;
807
808 rval = memalign(alignment, size);
809
810 if (rval == NULL) {
811 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
812 "memalign() failed");
813 }
814
815 return rval;
816 }
817
safe_kill(const char * file,const int lineno,void (cleanup_fn)(void),pid_t pid,int sig)818 int safe_kill(const char *file, const int lineno, void (cleanup_fn)(void),
819 pid_t pid, int sig)
820 {
821 int rval;
822
823 rval = kill(pid, sig);
824
825 if (rval == -1) {
826 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
827 "kill(%d,%s) failed", pid, tst_strsig(sig));
828 } else if (rval) {
829 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
830 "Invalid kill(%d,%s) return value %d", pid,
831 tst_strsig(sig), rval);
832 }
833
834 return rval;
835 }
836
safe_mkfifo(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname,mode_t mode)837 int safe_mkfifo(const char *file, const int lineno,
838 void (*cleanup_fn)(void), const char *pathname, mode_t mode)
839 {
840 int rval;
841
842 rval = mkfifo(pathname, mode);
843
844 if (rval == -1) {
845 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
846 "mkfifo(%s, %04o) failed", pathname, mode);
847 } else if (rval) {
848 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
849 "Invalid mkfifo(%s, %04o) return value %d", pathname,
850 mode, rval);
851 }
852
853 return rval;
854 }
855
safe_rename(const char * file,const int lineno,void (* cleanup_fn)(void),const char * oldpath,const char * newpath)856 int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void),
857 const char *oldpath, const char *newpath)
858 {
859 int rval;
860
861 rval = rename(oldpath, newpath);
862
863 if (rval == -1) {
864 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
865 "rename(%s, %s) failed", oldpath, newpath);
866 } else if (rval) {
867 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
868 "Invalid rename(%s, %s) return value %d", oldpath,
869 newpath, rval);
870 }
871
872 return rval;
873 }
874
875 static const char *const fuse_fs_types[] = {
876 "exfat",
877 "ntfs",
878 };
879
possibly_fuse(const char * fs_type)880 static int possibly_fuse(const char *fs_type)
881 {
882 unsigned int i;
883
884 if (!fs_type)
885 return 0;
886
887 for (i = 0; i < ARRAY_SIZE(fuse_fs_types); i++) {
888 if (!strcmp(fuse_fs_types[i], fs_type))
889 return 1;
890 }
891
892 return 0;
893 }
894
safe_mount(const char * file,const int lineno,void (* cleanup_fn)(void),const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)895 int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
896 const char *source, const char *target,
897 const char *filesystemtype, unsigned long mountflags,
898 const void *data)
899 {
900 int rval = -1;
901 char mpath[PATH_MAX];
902
903 if (realpath(target, mpath)) {
904 tst_resm_(file, lineno, TINFO,
905 "Mounting %s to %s fstyp=%s flags=%lx",
906 source, mpath, filesystemtype, mountflags);
907 } else {
908 tst_resm_(file, lineno, TINFO | TERRNO,
909 "Cannot resolve the absolute path of %s", target);
910 }
911 /*
912 * Don't try using the kernel's NTFS driver when mounting NTFS, since
913 * the kernel's NTFS driver doesn't have proper write support.
914 */
915 if (!filesystemtype || strcmp(filesystemtype, "ntfs")) {
916 mode_t old_umask = umask(0);
917
918 rval = mount(source, target, filesystemtype, mountflags, data);
919 umask(old_umask);
920 if (!rval)
921 return 0;
922 }
923
924 /*
925 * The FUSE filesystem executes mount.fuse helper, which tries to
926 * execute corresponding binary name which is encoded at the start of
927 * the source string and separated by # from the device name.
928 *
929 * The mount helpers are called mount.$fs_type.
930 */
931 if (possibly_fuse(filesystemtype)) {
932 char buf[1024];
933
934 tst_resm_(file, lineno, TINFO, "Trying FUSE...");
935 snprintf(buf, sizeof(buf), "mount.%s '%s' '%s'",
936 filesystemtype, source, target);
937
938 rval = tst_system(buf);
939 if (WIFEXITED(rval) && WEXITSTATUS(rval) == 0)
940 return 0;
941
942 tst_brkm_(file, lineno, TBROK, cleanup_fn,
943 "mount.%s failed with %i", filesystemtype, rval);
944 return -1;
945 } else if (rval == -1) {
946 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
947 "mount(%s, %s, %s, %lu, %p) failed", source, target,
948 filesystemtype, mountflags, data);
949 } else {
950 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
951 "Invalid mount(%s, %s, %s, %lu, %p) return value %d",
952 source, target, filesystemtype, mountflags, data,
953 rval);
954 }
955
956 return rval;
957 }
958
safe_umount(const char * file,const int lineno,void (* cleanup_fn)(void),const char * target)959 int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void),
960 const char *target)
961 {
962 int rval;
963 char mpath[PATH_MAX];
964
965 if (realpath(target, mpath)) {
966 tst_resm_(file, lineno, TINFO, "Umounting %s", mpath);
967 } else {
968 tst_resm_(file, lineno, TINFO | TERRNO,
969 "Cannot resolve the absolute path of %s", target);
970 }
971
972 rval = tst_umount(target);
973
974 if (rval == -1) {
975 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
976 "umount(%s) failed", target);
977 } else if (rval) {
978 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
979 "Invalid umount(%s) return value %d", target, rval);
980 }
981
982 return rval;
983 }
984
safe_opendir(const char * file,const int lineno,void (cleanup_fn)(void),const char * name)985 DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void),
986 const char *name)
987 {
988 DIR *rval;
989
990 rval = opendir(name);
991
992 if (!rval) {
993 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
994 "opendir(%s) failed", name);
995 }
996
997 return rval;
998 }
999
safe_closedir(const char * file,const int lineno,void (cleanup_fn)(void),DIR * dirp)1000 int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void),
1001 DIR *dirp)
1002 {
1003 int rval;
1004
1005 rval = closedir(dirp);
1006
1007 if (rval == -1) {
1008 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1009 "closedir(%p) failed", dirp);
1010 } else if (rval) {
1011 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1012 "Invalid closedir(%p) return value %d", dirp, rval);
1013 }
1014
1015 return rval;
1016 }
1017
safe_readdir(const char * file,const int lineno,void (cleanup_fn)(void),DIR * dirp)1018 struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void),
1019 DIR *dirp)
1020 {
1021 struct dirent *rval;
1022 int err = errno;
1023
1024 errno = 0;
1025 rval = readdir(dirp);
1026
1027 if (!rval && errno) {
1028 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1029 "readdir(%p) failed", dirp);
1030 }
1031
1032 errno = err;
1033 return rval;
1034 }
1035
safe_getpriority(const char * file,const int lineno,int which,id_t who)1036 int safe_getpriority(const char *file, const int lineno, int which, id_t who)
1037 {
1038 int rval, err = errno;
1039
1040 errno = 0;
1041 rval = getpriority(which, who);
1042
1043 if (rval == -1 && errno) {
1044 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1045 "getpriority(%i, %i) failed", which, who);
1046 } else if (errno) {
1047 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1048 "getpriority(%i, %i) failed with return value %d",
1049 which, who, rval);
1050 }
1051
1052 errno = err;
1053 return rval;
1054 }
1055
safe_getxattr(const char * file,const int lineno,const char * path,const char * name,void * value,size_t size)1056 ssize_t safe_getxattr(const char *file, const int lineno, const char *path,
1057 const char *name, void *value, size_t size)
1058 {
1059 ssize_t rval;
1060
1061 rval = getxattr(path, name, value, size);
1062
1063 if (rval == -1) {
1064 if (errno == ENOTSUP) {
1065 tst_brkm_(file, lineno, TCONF, NULL,
1066 "no xattr support in fs or mounted without user_xattr option");
1067 return rval;
1068 }
1069
1070 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1071 "getxattr(%s, %s, %p, %zu) failed",
1072 path, name, value, size);
1073 } else if (rval < 0) {
1074 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1075 "Invalid getxattr(%s, %s, %p, %zu) return value %zd",
1076 path, name, value, size, rval);
1077 }
1078
1079 return rval;
1080 }
1081
safe_setxattr(const char * file,const int lineno,const char * path,const char * name,const void * value,size_t size,int flags)1082 int safe_setxattr(const char *file, const int lineno, const char *path,
1083 const char *name, const void *value, size_t size, int flags)
1084 {
1085 int rval;
1086
1087 rval = setxattr(path, name, value, size, flags);
1088
1089 if (rval == -1) {
1090 if (errno == ENOTSUP) {
1091 tst_brkm_(file, lineno, TCONF, NULL,
1092 "no xattr support in fs, mounted without user_xattr option "
1093 "or invalid namespace/name format");
1094 return rval;
1095 }
1096
1097 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1098 "setxattr(%s, %s, %p, %zu) failed",
1099 path, name, value, size);
1100 } else if (rval) {
1101 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1102 "Invalid setxattr(%s, %s, %p, %zu) return value %d",
1103 path, name, value, size, rval);
1104 }
1105
1106 return rval;
1107 }
1108
safe_lsetxattr(const char * file,const int lineno,const char * path,const char * name,const void * value,size_t size,int flags)1109 int safe_lsetxattr(const char *file, const int lineno, const char *path,
1110 const char *name, const void *value, size_t size, int flags)
1111 {
1112 int rval;
1113
1114 rval = lsetxattr(path, name, value, size, flags);
1115
1116 if (rval == -1) {
1117 if (errno == ENOTSUP) {
1118 tst_brkm_(file, lineno, TCONF, NULL,
1119 "no xattr support in fs, mounted without user_xattr option "
1120 "or invalid namespace/name format");
1121 return rval;
1122 }
1123
1124 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1125 "lsetxattr(%s, %s, %p, %zu, %i) failed",
1126 path, name, value, size, flags);
1127 } else if (rval) {
1128 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1129 "Invalid lsetxattr(%s, %s, %p, %zu, %i) return value %d",
1130 path, name, value, size, flags, rval);
1131 }
1132
1133 return rval;
1134 }
1135
safe_fsetxattr(const char * file,const int lineno,int fd,const char * name,const void * value,size_t size,int flags)1136 int safe_fsetxattr(const char *file, const int lineno, int fd, const char *name,
1137 const void *value, size_t size, int flags)
1138 {
1139 int rval;
1140
1141 rval = fsetxattr(fd, name, value, size, flags);
1142
1143 if (rval == -1) {
1144 if (errno == ENOTSUP) {
1145 tst_brkm_(file, lineno, TCONF, NULL,
1146 "no xattr support in fs, mounted without user_xattr option "
1147 "or invalid namespace/name format");
1148 return rval;
1149 }
1150
1151 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1152 "fsetxattr(%i, %s, %p, %zu, %i) failed",
1153 fd, name, value, size, flags);
1154 } else if (rval) {
1155 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1156 "Invalid fsetxattr(%i, %s, %p, %zu, %i) return value %d",
1157 fd, name, value, size, flags, rval);
1158 }
1159
1160 return rval;
1161 }
1162
safe_removexattr(const char * file,const int lineno,const char * path,const char * name)1163 int safe_removexattr(const char *file, const int lineno, const char *path,
1164 const char *name)
1165 {
1166 int rval;
1167
1168 rval = removexattr(path, name);
1169
1170 if (rval == -1) {
1171 if (errno == ENOTSUP) {
1172 tst_brkm_(file, lineno, TCONF, NULL,
1173 "no xattr support in fs or mounted without user_xattr option");
1174 return rval;
1175 }
1176
1177 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1178 "removexattr(%s, %s) failed", path, name);
1179 } else if (rval) {
1180 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1181 "Invalid removexattr(%s, %s) return value %d", path,
1182 name, rval);
1183 }
1184
1185 return rval;
1186 }
1187
safe_lremovexattr(const char * file,const int lineno,const char * path,const char * name)1188 int safe_lremovexattr(const char *file, const int lineno, const char *path,
1189 const char *name)
1190 {
1191 int rval;
1192
1193 rval = lremovexattr(path, name);
1194
1195 if (rval == -1) {
1196 if (errno == ENOTSUP) {
1197 tst_brkm_(file, lineno, TCONF, NULL,
1198 "no xattr support in fs or mounted without user_xattr option");
1199 return rval;
1200 }
1201
1202 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1203 "lremovexattr(%s, %s) failed", path, name);
1204 } else if (rval) {
1205 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1206 "Invalid lremovexattr(%s, %s) return value %d", path,
1207 name, rval);
1208 }
1209
1210 return rval;
1211 }
1212
safe_fremovexattr(const char * file,const int lineno,int fd,const char * name)1213 int safe_fremovexattr(const char *file, const int lineno, int fd,
1214 const char *name)
1215 {
1216 int rval;
1217
1218 rval = fremovexattr(fd, name);
1219
1220 if (rval == -1) {
1221 if (errno == ENOTSUP) {
1222 tst_brkm_(file, lineno, TCONF, NULL,
1223 "no xattr support in fs or mounted without user_xattr option");
1224 return rval;
1225 }
1226
1227 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1228 "fremovexattr(%i, %s) failed", fd, name);
1229 } else if (rval) {
1230 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1231 "Invalid fremovexattr(%i, %s) return value %d", fd,
1232 name, rval);
1233 }
1234
1235 return rval;
1236 }
1237
safe_fsync(const char * file,const int lineno,int fd)1238 int safe_fsync(const char *file, const int lineno, int fd)
1239 {
1240 int rval;
1241
1242 rval = fsync(fd);
1243
1244 if (rval == -1) {
1245 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1246 "fsync(%i) failed", fd);
1247 } else if (rval) {
1248 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1249 "Invalid fsync(%i) return value %d", fd, rval);
1250 }
1251
1252 return rval;
1253 }
1254
safe_setsid(const char * file,const int lineno)1255 pid_t safe_setsid(const char *file, const int lineno)
1256 {
1257 pid_t rval;
1258
1259 rval = setsid();
1260
1261 if (rval == -1) {
1262 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1263 "setsid() failed");
1264 }
1265
1266 return rval;
1267 }
1268
safe_mknod(const char * file,const int lineno,const char * pathname,mode_t mode,dev_t dev)1269 int safe_mknod(const char *file, const int lineno, const char *pathname,
1270 mode_t mode, dev_t dev)
1271 {
1272 int rval;
1273
1274 rval = mknod(pathname, mode, dev);
1275
1276 if (rval == -1) {
1277 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1278 "mknod() failed");
1279 } else if (rval) {
1280 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1281 "Invalid mknod() return value %d", rval);
1282 }
1283
1284 return rval;
1285 }
1286
safe_mlock(const char * file,const int lineno,const void * addr,size_t len)1287 int safe_mlock(const char *file, const int lineno, const void *addr,
1288 size_t len)
1289 {
1290 int rval;
1291
1292 rval = mlock(addr, len);
1293
1294 if (rval == -1) {
1295 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1296 "mlock() failed");
1297 } else if (rval) {
1298 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1299 "Invalid mlock() return value %d", rval);
1300 }
1301
1302 return rval;
1303 }
1304
safe_munlock(const char * file,const int lineno,const void * addr,size_t len)1305 int safe_munlock(const char *file, const int lineno, const void *addr,
1306 size_t len)
1307 {
1308 int rval;
1309
1310 rval = munlock(addr, len);
1311
1312 if (rval == -1) {
1313 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1314 "munlock() failed");
1315 } else if (rval) {
1316 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1317 "Invalid munlock() return value %d", rval);
1318 }
1319
1320 return rval;
1321 }
1322
safe_mincore(const char * file,const int lineno,void * start,size_t length,unsigned char * vec)1323 int safe_mincore(const char *file, const int lineno, void *start,
1324 size_t length, unsigned char *vec)
1325 {
1326 int rval;
1327
1328 rval = mincore(start, length, vec);
1329
1330 if (rval == -1) {
1331 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1332 "mincore() failed");
1333 } else if (rval) {
1334 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1335 "Invalid mincore() return value %d", rval);
1336 }
1337
1338 return rval;
1339 }
1340
safe_sysinfo(const char * file,const int lineno,struct sysinfo * info)1341 int safe_sysinfo(const char *file, const int lineno, struct sysinfo *info)
1342 {
1343 int ret;
1344
1345 errno = 0;
1346 ret = sysinfo(info);
1347
1348 if (ret == -1) {
1349 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1350 "sysinfo() failed");
1351 } else if (ret) {
1352 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1353 "Invalid sysinfo() return value %d", ret);
1354 }
1355
1356 return ret;
1357 }
1358