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