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 rval = mount(source, target, filesystemtype, mountflags, data);
917 if (!rval)
918 return 0;
919 }
920
921 /*
922 * The FUSE filesystem executes mount.fuse helper, which tries to
923 * execute corresponding binary name which is encoded at the start of
924 * the source string and separated by # from the device name.
925 *
926 * The mount helpers are called mount.$fs_type.
927 */
928 if (possibly_fuse(filesystemtype)) {
929 char buf[1024];
930
931 tst_resm_(file, lineno, TINFO, "Trying FUSE...");
932 snprintf(buf, sizeof(buf), "mount.%s '%s' '%s'",
933 filesystemtype, source, target);
934
935 rval = tst_system(buf);
936 if (WIFEXITED(rval) && WEXITSTATUS(rval) == 0)
937 return 0;
938
939 tst_brkm_(file, lineno, TBROK, cleanup_fn,
940 "mount.%s failed with %i", filesystemtype, rval);
941 return -1;
942 } else if (rval == -1) {
943 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
944 "mount(%s, %s, %s, %lu, %p) failed", source, target,
945 filesystemtype, mountflags, data);
946 } else {
947 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
948 "Invalid mount(%s, %s, %s, %lu, %p) return value %d",
949 source, target, filesystemtype, mountflags, data,
950 rval);
951 }
952
953 return rval;
954 }
955
safe_umount(const char * file,const int lineno,void (* cleanup_fn)(void),const char * target)956 int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void),
957 const char *target)
958 {
959 int rval;
960 char mpath[PATH_MAX];
961
962 if (realpath(target, mpath)) {
963 tst_resm_(file, lineno, TINFO, "Umounting %s", mpath);
964 } else {
965 tst_resm_(file, lineno, TINFO | TERRNO,
966 "Cannot resolve the absolute path of %s", target);
967 }
968
969 rval = tst_umount(target);
970
971 if (rval == -1) {
972 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
973 "umount(%s) failed", target);
974 } else if (rval) {
975 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
976 "Invalid umount(%s) return value %d", target, rval);
977 }
978
979 return rval;
980 }
981
safe_opendir(const char * file,const int lineno,void (cleanup_fn)(void),const char * name)982 DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void),
983 const char *name)
984 {
985 DIR *rval;
986
987 rval = opendir(name);
988
989 if (!rval) {
990 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
991 "opendir(%s) failed", name);
992 }
993
994 return rval;
995 }
996
safe_closedir(const char * file,const int lineno,void (cleanup_fn)(void),DIR * dirp)997 int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void),
998 DIR *dirp)
999 {
1000 int rval;
1001
1002 rval = closedir(dirp);
1003
1004 if (rval == -1) {
1005 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1006 "closedir(%p) failed", dirp);
1007 } else if (rval) {
1008 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1009 "Invalid closedir(%p) return value %d", dirp, rval);
1010 }
1011
1012 return rval;
1013 }
1014
safe_readdir(const char * file,const int lineno,void (cleanup_fn)(void),DIR * dirp)1015 struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void),
1016 DIR *dirp)
1017 {
1018 struct dirent *rval;
1019 int err = errno;
1020
1021 errno = 0;
1022 rval = readdir(dirp);
1023
1024 if (!rval && errno) {
1025 tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1026 "readdir(%p) failed", dirp);
1027 }
1028
1029 errno = err;
1030 return rval;
1031 }
1032
safe_getpriority(const char * file,const int lineno,int which,id_t who)1033 int safe_getpriority(const char *file, const int lineno, int which, id_t who)
1034 {
1035 int rval, err = errno;
1036
1037 errno = 0;
1038 rval = getpriority(which, who);
1039
1040 if (rval == -1 && errno) {
1041 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1042 "getpriority(%i, %i) failed", which, who);
1043 } else if (errno) {
1044 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1045 "getpriority(%i, %i) failed with return value %d",
1046 which, who, rval);
1047 }
1048
1049 errno = err;
1050 return rval;
1051 }
1052
safe_getxattr(const char * file,const int lineno,const char * path,const char * name,void * value,size_t size)1053 ssize_t safe_getxattr(const char *file, const int lineno, const char *path,
1054 const char *name, void *value, size_t size)
1055 {
1056 ssize_t rval;
1057
1058 rval = getxattr(path, name, value, size);
1059
1060 if (rval == -1) {
1061 if (errno == ENOTSUP) {
1062 tst_brkm_(file, lineno, TCONF, NULL,
1063 "no xattr support in fs or mounted without user_xattr option");
1064 return rval;
1065 }
1066
1067 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1068 "getxattr(%s, %s, %p, %zu) failed",
1069 path, name, value, size);
1070 } else if (rval < 0) {
1071 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1072 "Invalid getxattr(%s, %s, %p, %zu) return value %zd",
1073 path, name, value, size, rval);
1074 }
1075
1076 return rval;
1077 }
1078
safe_setxattr(const char * file,const int lineno,const char * path,const char * name,const void * value,size_t size,int flags)1079 int safe_setxattr(const char *file, const int lineno, const char *path,
1080 const char *name, const void *value, size_t size, int flags)
1081 {
1082 int rval;
1083
1084 rval = setxattr(path, name, value, size, flags);
1085
1086 if (rval == -1) {
1087 if (errno == ENOTSUP) {
1088 tst_brkm_(file, lineno, TCONF, NULL,
1089 "no xattr support in fs, mounted without user_xattr option "
1090 "or invalid namespace/name format");
1091 return rval;
1092 }
1093
1094 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1095 "setxattr(%s, %s, %p, %zu) failed",
1096 path, name, value, size);
1097 } else if (rval) {
1098 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1099 "Invalid setxattr(%s, %s, %p, %zu) return value %d",
1100 path, name, value, size, rval);
1101 }
1102
1103 return rval;
1104 }
1105
safe_lsetxattr(const char * file,const int lineno,const char * path,const char * name,const void * value,size_t size,int flags)1106 int safe_lsetxattr(const char *file, const int lineno, const char *path,
1107 const char *name, const void *value, size_t size, int flags)
1108 {
1109 int rval;
1110
1111 rval = lsetxattr(path, name, value, size, flags);
1112
1113 if (rval == -1) {
1114 if (errno == ENOTSUP) {
1115 tst_brkm_(file, lineno, TCONF, NULL,
1116 "no xattr support in fs, mounted without user_xattr option "
1117 "or invalid namespace/name format");
1118 return rval;
1119 }
1120
1121 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1122 "lsetxattr(%s, %s, %p, %zu, %i) failed",
1123 path, name, value, size, flags);
1124 } else if (rval) {
1125 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1126 "Invalid lsetxattr(%s, %s, %p, %zu, %i) return value %d",
1127 path, name, value, size, flags, rval);
1128 }
1129
1130 return rval;
1131 }
1132
safe_fsetxattr(const char * file,const int lineno,int fd,const char * name,const void * value,size_t size,int flags)1133 int safe_fsetxattr(const char *file, const int lineno, int fd, const char *name,
1134 const void *value, size_t size, int flags)
1135 {
1136 int rval;
1137
1138 rval = fsetxattr(fd, name, value, size, flags);
1139
1140 if (rval == -1) {
1141 if (errno == ENOTSUP) {
1142 tst_brkm_(file, lineno, TCONF, NULL,
1143 "no xattr support in fs, mounted without user_xattr option "
1144 "or invalid namespace/name format");
1145 return rval;
1146 }
1147
1148 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1149 "fsetxattr(%i, %s, %p, %zu, %i) failed",
1150 fd, name, value, size, flags);
1151 } else if (rval) {
1152 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1153 "Invalid fsetxattr(%i, %s, %p, %zu, %i) return value %d",
1154 fd, name, value, size, flags, rval);
1155 }
1156
1157 return rval;
1158 }
1159
safe_removexattr(const char * file,const int lineno,const char * path,const char * name)1160 int safe_removexattr(const char *file, const int lineno, const char *path,
1161 const char *name)
1162 {
1163 int rval;
1164
1165 rval = removexattr(path, name);
1166
1167 if (rval == -1) {
1168 if (errno == ENOTSUP) {
1169 tst_brkm_(file, lineno, TCONF, NULL,
1170 "no xattr support in fs or mounted without user_xattr option");
1171 return rval;
1172 }
1173
1174 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1175 "removexattr(%s, %s) failed", path, name);
1176 } else if (rval) {
1177 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1178 "Invalid removexattr(%s, %s) return value %d", path,
1179 name, rval);
1180 }
1181
1182 return rval;
1183 }
1184
safe_lremovexattr(const char * file,const int lineno,const char * path,const char * name)1185 int safe_lremovexattr(const char *file, const int lineno, const char *path,
1186 const char *name)
1187 {
1188 int rval;
1189
1190 rval = lremovexattr(path, name);
1191
1192 if (rval == -1) {
1193 if (errno == ENOTSUP) {
1194 tst_brkm_(file, lineno, TCONF, NULL,
1195 "no xattr support in fs or mounted without user_xattr option");
1196 return rval;
1197 }
1198
1199 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1200 "lremovexattr(%s, %s) failed", path, name);
1201 } else if (rval) {
1202 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1203 "Invalid lremovexattr(%s, %s) return value %d", path,
1204 name, rval);
1205 }
1206
1207 return rval;
1208 }
1209
safe_fremovexattr(const char * file,const int lineno,int fd,const char * name)1210 int safe_fremovexattr(const char *file, const int lineno, int fd,
1211 const char *name)
1212 {
1213 int rval;
1214
1215 rval = fremovexattr(fd, name);
1216
1217 if (rval == -1) {
1218 if (errno == ENOTSUP) {
1219 tst_brkm_(file, lineno, TCONF, NULL,
1220 "no xattr support in fs or mounted without user_xattr option");
1221 return rval;
1222 }
1223
1224 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1225 "fremovexattr(%i, %s) failed", fd, name);
1226 } else if (rval) {
1227 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1228 "Invalid fremovexattr(%i, %s) return value %d", fd,
1229 name, rval);
1230 }
1231
1232 return rval;
1233 }
1234
safe_fsync(const char * file,const int lineno,int fd)1235 int safe_fsync(const char *file, const int lineno, int fd)
1236 {
1237 int rval;
1238
1239 rval = fsync(fd);
1240
1241 if (rval == -1) {
1242 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1243 "fsync(%i) failed", fd);
1244 } else if (rval) {
1245 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1246 "Invalid fsync(%i) return value %d", fd, rval);
1247 }
1248
1249 return rval;
1250 }
1251
safe_setsid(const char * file,const int lineno)1252 pid_t safe_setsid(const char *file, const int lineno)
1253 {
1254 pid_t rval;
1255
1256 rval = setsid();
1257
1258 if (rval == -1) {
1259 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1260 "setsid() failed");
1261 }
1262
1263 return rval;
1264 }
1265
safe_mknod(const char * file,const int lineno,const char * pathname,mode_t mode,dev_t dev)1266 int safe_mknod(const char *file, const int lineno, const char *pathname,
1267 mode_t mode, dev_t dev)
1268 {
1269 int rval;
1270
1271 rval = mknod(pathname, mode, dev);
1272
1273 if (rval == -1) {
1274 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1275 "mknod() failed");
1276 } else if (rval) {
1277 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1278 "Invalid mknod() return value %d", rval);
1279 }
1280
1281 return rval;
1282 }
1283
safe_mlock(const char * file,const int lineno,const void * addr,size_t len)1284 int safe_mlock(const char *file, const int lineno, const void *addr,
1285 size_t len)
1286 {
1287 int rval;
1288
1289 rval = mlock(addr, len);
1290
1291 if (rval == -1) {
1292 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1293 "mlock() failed");
1294 } else if (rval) {
1295 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1296 "Invalid mlock() return value %d", rval);
1297 }
1298
1299 return rval;
1300 }
1301
safe_munlock(const char * file,const int lineno,const void * addr,size_t len)1302 int safe_munlock(const char *file, const int lineno, const void *addr,
1303 size_t len)
1304 {
1305 int rval;
1306
1307 rval = munlock(addr, len);
1308
1309 if (rval == -1) {
1310 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1311 "munlock() failed");
1312 } else if (rval) {
1313 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1314 "Invalid munlock() return value %d", rval);
1315 }
1316
1317 return rval;
1318 }
1319
safe_mincore(const char * file,const int lineno,void * start,size_t length,unsigned char * vec)1320 int safe_mincore(const char *file, const int lineno, void *start,
1321 size_t length, unsigned char *vec)
1322 {
1323 int rval;
1324
1325 rval = mincore(start, length, vec);
1326
1327 if (rval == -1) {
1328 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1329 "mincore() failed");
1330 } else if (rval) {
1331 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1332 "Invalid mincore() return value %d", rval);
1333 }
1334
1335 return rval;
1336 }
1337
safe_sysinfo(const char * file,const int lineno,struct sysinfo * info)1338 int safe_sysinfo(const char *file, const int lineno, struct sysinfo *info)
1339 {
1340 int ret;
1341
1342 errno = 0;
1343 ret = sysinfo(info);
1344
1345 if (ret == -1) {
1346 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1347 "sysinfo() failed");
1348 } else if (ret) {
1349 tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1350 "Invalid sysinfo() return value %d", ret);
1351 }
1352
1353 return ret;
1354 }
1355