• 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) {
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 	} else if (len_strict && (size_t)rval != nbyte) {
305 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
306 			  "Short read(%d,%p,%zu) returned only %zd",
307 			  fildes, buf, nbyte, rval);
308 	}
309 
310 	return rval;
311 }
312 
safe_setegid(const char * file,const int lineno,void (* cleanup_fn)(void),gid_t egid)313 int safe_setegid(const char *file, const int lineno, void (*cleanup_fn) (void),
314                  gid_t egid)
315 {
316 	int rval;
317 
318 	rval = setegid(egid);
319 
320 	if (rval == -1) {
321 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
322 			"setegid(%u) failed", (unsigned int)egid);
323 	} else if (rval) {
324 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
325 			"Invalid setegid(%u) return value %d",
326 			(unsigned int)egid, rval);
327 	}
328 
329 	return rval;
330 }
331 
safe_seteuid(const char * file,const int lineno,void (* cleanup_fn)(void),uid_t euid)332 int safe_seteuid(const char *file, const int lineno, void (*cleanup_fn) (void),
333                  uid_t euid)
334 {
335 	int rval;
336 
337 	rval = seteuid(euid);
338 
339 	if (rval == -1) {
340 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
341 			"seteuid(%u) failed", (unsigned int)euid);
342 	} else if (rval) {
343 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
344 			"Invalid seteuid(%u) return value %d",
345 			(unsigned int)euid, rval);
346 	}
347 
348 	return rval;
349 }
350 
safe_setgid(const char * file,const int lineno,void (* cleanup_fn)(void),gid_t gid)351 int safe_setgid(const char *file, const int lineno, void (*cleanup_fn) (void),
352                 gid_t gid)
353 {
354 	int rval;
355 
356 	rval = setgid(gid);
357 
358 	if (rval == -1) {
359 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
360 			"setgid(%u) failed", (unsigned int)gid);
361 	} else if (rval) {
362 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
363 			"Invalid setgid(%u) return value %d",
364 			(unsigned int)gid, rval);
365 	}
366 
367 	return rval;
368 }
369 
safe_setuid(const char * file,const int lineno,void (* cleanup_fn)(void),uid_t uid)370 int safe_setuid(const char *file, const int lineno, void (*cleanup_fn) (void),
371                 uid_t uid)
372 {
373 	int rval;
374 
375 	rval = setuid(uid);
376 
377 	if (rval == -1) {
378 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
379 			"setuid(%u) failed", (unsigned int)uid);
380 	} else if (rval) {
381 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
382 			"Invalid setuid(%u) return value %d",
383 			(unsigned int)uid, rval);
384 	}
385 
386 	return rval;
387 }
388 
safe_getresuid(const char * file,const int lineno,void (* cleanup_fn)(void),uid_t * ruid,uid_t * euid,uid_t * suid)389 int safe_getresuid(const char *file, const int lineno, void (*cleanup_fn)(void),
390 		   uid_t *ruid, uid_t *euid, uid_t *suid)
391 {
392 	int rval;
393 
394 	rval = getresuid(ruid, euid, suid);
395 
396 	if (rval == -1) {
397 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
398 			"getresuid(%p, %p, %p) failed", ruid, euid, suid);
399 	} else if (rval) {
400 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
401 			"Invalid getresuid(%p, %p, %p) return value %d", ruid,
402 			euid, suid, rval);
403 	}
404 
405 	return rval;
406 }
407 
safe_getresgid(const char * file,const int lineno,void (* cleanup_fn)(void),gid_t * rgid,gid_t * egid,gid_t * sgid)408 int safe_getresgid(const char *file, const int lineno, void (*cleanup_fn)(void),
409 		   gid_t *rgid, gid_t *egid, gid_t *sgid)
410 {
411 	int rval;
412 
413 	rval = getresgid(rgid, egid, sgid);
414 
415 	if (rval == -1) {
416 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
417 			"getresgid(%p, %p, %p) failed", rgid, egid, sgid);
418 	} else if (rval) {
419 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
420 			"Invalid getresgid(%p, %p, %p) return value %d", rgid,
421 			egid, sgid, rval);
422 	}
423 
424 	return rval;
425 }
426 
safe_unlink(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname)427 int safe_unlink(const char *file, const int lineno, void (*cleanup_fn) (void),
428                 const char *pathname)
429 {
430 	int rval;
431 
432 	rval = unlink(pathname);
433 
434 	if (rval == -1) {
435 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
436 			"unlink(%s) failed", pathname);
437 	} else if (rval) {
438 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
439 			"Invalid unlink(%s) return value %d", pathname, rval);
440 	}
441 
442 	return rval;
443 }
444 
445 
safe_link(const char * file,const int lineno,void (cleanup_fn)(void),const char * oldpath,const char * newpath)446 int safe_link(const char *file, const int lineno,
447               void (cleanup_fn)(void), const char *oldpath,
448               const char *newpath)
449 {
450 	int rval;
451 
452 	rval = link(oldpath, newpath);
453 
454 	if (rval == -1) {
455 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
456 		        "link(%s,%s) failed", oldpath, newpath);
457 	} else if (rval) {
458 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
459 		        "Invalid link(%s,%s) return value %d", oldpath,
460 			newpath, rval);
461 	}
462 
463 	return rval;
464 }
465 
safe_linkat(const char * file,const int lineno,void (cleanup_fn)(void),int olddirfd,const char * oldpath,int newdirfd,const char * newpath,int flags)466 int safe_linkat(const char *file, const int lineno,
467 		void (cleanup_fn)(void), int olddirfd, const char *oldpath,
468 		int newdirfd, const char *newpath, int flags)
469 {
470 	int rval;
471 
472 	rval = linkat(olddirfd, oldpath, newdirfd, newpath, flags);
473 
474 	if (rval == -1) {
475 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
476 			"linkat(%d,%s,%d,%s,%d) failed", olddirfd, oldpath,
477 			newdirfd, newpath, flags);
478 	} else if (rval) {
479 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
480 			"Invalid linkat(%d,%s,%d,%s,%d) return value %d",
481 			olddirfd, oldpath, newdirfd, newpath, flags, rval);
482 	}
483 
484 	return rval;
485 }
486 
safe_readlink(const char * file,const int lineno,void (cleanup_fn)(void),const char * path,char * buf,size_t bufsize)487 ssize_t safe_readlink(const char *file, const int lineno,
488 		  void (cleanup_fn)(void), const char *path,
489 		  char *buf, size_t bufsize)
490 {
491 	ssize_t rval;
492 
493 	rval = readlink(path, buf, bufsize);
494 
495 	if (rval == -1) {
496 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
497 			"readlink(%s,%p,%zu) failed", path, buf, bufsize);
498 	} else if (rval < 0) {
499 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
500 			"Invalid readlink(%s,%p,%zu) return value %zd", path,
501 			buf, bufsize, rval);
502 	} else {
503 		/* readlink does not append a NUL byte to the buffer.
504 		 * Add it now. */
505 		if ((size_t) rval < bufsize)
506 			buf[rval] = '\0';
507 		else
508 			buf[bufsize-1] = '\0';
509 	}
510 
511 	return rval;
512 }
513 
safe_symlink(const char * file,const int lineno,void (cleanup_fn)(void),const char * oldpath,const char * newpath)514 int safe_symlink(const char *file, const int lineno,
515                  void (cleanup_fn)(void), const char *oldpath,
516                  const char *newpath)
517 {
518 	int rval;
519 
520 	rval = symlink(oldpath, newpath);
521 
522 	if (rval == -1) {
523 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
524 			"symlink(%s,%s) failed", oldpath, newpath);
525 	} else if (rval) {
526 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
527 			"Invalid symlink(%s,%s) return value %d", oldpath,
528 			newpath, rval);
529 	}
530 
531 	return rval;
532 }
533 
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)534 ssize_t safe_write(const char *file, const int lineno, void (cleanup_fn) (void),
535 		   enum safe_write_opts len_strict, int fildes, const void *buf,
536 		   size_t nbyte)
537 {
538 	ssize_t rval;
539 	const void *wbuf = buf;
540 	size_t len = nbyte;
541 	int iter = 0;
542 
543 	do {
544 		iter++;
545 		rval = write(fildes, wbuf, len);
546 		if (rval == -1) {
547 			if (len_strict == SAFE_WRITE_RETRY)
548 				tst_resm_(file, lineno, TINFO,
549 					"write() wrote %zu bytes in %d calls",
550 					nbyte-len, iter);
551 			tst_brkm_(file, lineno, TBROK | TERRNO,
552 				cleanup_fn, "write(%d,%p,%zu) failed",
553 				fildes, buf, nbyte);
554 			return rval;
555 		}
556 
557 		if (rval < 0) {
558 			tst_brkm_(file, lineno, TBROK, cleanup_fn,
559 			          "invalid write() return value %zi",
560 				  rval);
561 			return rval;
562 		}
563 
564 		if (len_strict == SAFE_WRITE_ANY)
565 			return rval;
566 
567 		if (len_strict == SAFE_WRITE_ALL) {
568 			if ((size_t)rval != nbyte)
569 				tst_brkm_(file, lineno, TBROK,
570 					cleanup_fn, "short write(%d,%p,%zu) "
571 					"return value %zd",
572 					fildes, buf, nbyte, rval);
573 			return rval;
574 		}
575 
576 		wbuf += rval;
577 		len -= rval;
578 	} while (len > 0);
579 
580 	return rval;
581 }
582 
safe_strtol(const char * file,const int lineno,void (cleanup_fn)(void),char * str,long min,long max)583 long safe_strtol(const char *file, const int lineno,
584 		 void (cleanup_fn) (void), char *str, long min, long max)
585 {
586 	long rval;
587 	char *endptr;
588 
589 	errno = 0;
590 	rval = strtol(str, &endptr, 10);
591 
592 	if ((errno == ERANGE && (rval == LONG_MAX || rval == LONG_MIN))
593 	    || (errno != 0 && rval == 0)) {
594 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
595 			"strtol(%s) failed", str);
596 		return rval;
597 	}
598 
599 	if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
600 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
601 			"strtol(%s): Invalid value", str);
602 		return 0;
603 	}
604 
605 	if (rval > max || rval < min) {
606 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
607 			"strtol(%s): %ld is out of range %ld - %ld",
608 			str, rval, min, max);
609 		return 0;
610 	}
611 
612 	return rval;
613 }
614 
safe_strtoul(const char * file,const int lineno,void (cleanup_fn)(void),char * str,unsigned long min,unsigned long max)615 unsigned long safe_strtoul(const char *file, const int lineno,
616 			   void (cleanup_fn) (void), char *str,
617 			   unsigned long min, unsigned long max)
618 {
619 	unsigned long rval;
620 	char *endptr;
621 
622 	errno = 0;
623 	rval = strtoul(str, &endptr, 10);
624 
625 	if ((errno == ERANGE && rval == ULONG_MAX)
626 	    || (errno != 0 && rval == 0)) {
627 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
628 			"strtoul(%s) failed", str);
629 		return rval;
630 	}
631 
632 	if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
633 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
634 			"Invalid value: '%s'", str);
635 		return 0;
636 	}
637 
638 	if (rval > max || rval < min) {
639 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
640 			"strtoul(%s): %lu is out of range %lu - %lu",
641 			str, rval, min, max);
642 		return 0;
643 	}
644 
645 	return rval;
646 }
647 
safe_strtof(const char * file,const int lineno,void (cleanup_fn)(void),char * str,float min,float max)648 float safe_strtof(const char *file, const int lineno,
649 		  void (cleanup_fn) (void), char *str,
650 		  float min, float max)
651 {
652 	float rval;
653 	char *endptr;
654 
655 	errno = 0;
656 	rval = strtof(str, &endptr);
657 
658 	if (errno) {
659 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
660 			"strtof(%s) failed", str);
661 		return rval;
662 	}
663 
664 	if (endptr == str || (*endptr != '\0' && *endptr != '\n')) {
665 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
666 			"Invalid value: '%s'", str);
667 		return 0;
668 	}
669 
670 	if (rval > max || rval < min) {
671 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
672 			"strtof(%s): %f is out of range %f - %f",
673 			str, rval, min, max);
674 		return 0;
675 	}
676 
677 	return rval;
678 }
679 
safe_sysconf(const char * file,const int lineno,void (cleanup_fn)(void),int name)680 long safe_sysconf(const char *file, const int lineno,
681 		  void (cleanup_fn) (void), int name)
682 {
683 	long rval;
684 
685 	errno = 0;
686 	rval = sysconf(name);
687 
688 	if (rval == -1) {
689 		if (errno) {
690 			tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
691 				"sysconf(%d) failed", name);
692 		} else {
693 			tst_resm_(file, lineno, TINFO,
694 				"sysconf(%d): queried option is not available or there is no definite limit",
695 				name);
696 		}
697 	}
698 
699 	return rval;
700 }
701 
safe_chmod(const char * file,const int lineno,void (cleanup_fn)(void),const char * path,mode_t mode)702 int safe_chmod(const char *file, const int lineno,
703                void (cleanup_fn)(void), const char *path, mode_t mode)
704 {
705 	int rval;
706 
707 	rval = chmod(path, mode);
708 
709 	if (rval == -1) {
710 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
711 			"chmod(%s,%04o) failed", path, mode);
712 	} else if (rval) {
713 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
714 			"Invalid chmod(%s,%04o) return value %d", path, mode,
715 			rval);
716 	}
717 
718 	return rval;
719 }
720 
safe_fchmod(const char * file,const int lineno,void (cleanup_fn)(void),int fd,mode_t mode)721 int safe_fchmod(const char *file, const int lineno,
722                 void (cleanup_fn)(void), int fd, mode_t mode)
723 {
724 	int rval;
725 
726 	rval = fchmod(fd, mode);
727 
728 	if (rval == -1) {
729 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
730 			"fchmod(%d,%04o) failed", fd, mode);
731 	} else if (rval) {
732 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
733 			"Invalid fchmod(%d,%04o) return value %d", fd, mode,
734 			rval);
735 	}
736 
737 	return rval;
738 }
739 
safe_chown(const char * file,const int lineno,void (cleanup_fn)(void),const char * path,uid_t owner,gid_t group)740 int safe_chown(const char *file, const int lineno, void (cleanup_fn)(void),
741 			const char *path, uid_t owner, gid_t group)
742 {
743 	int rval;
744 
745 	rval = chown(path, owner, group);
746 
747 	if (rval == -1) {
748 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
749 			"chown(%s,%d,%d) failed", path, owner, group);
750 	} else if (rval) {
751 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
752 			"Invalid chown(%s,%d,%d) return value %d", path,
753 			owner, group, rval);
754 	}
755 
756 	return rval;
757 }
758 
safe_fchown(const char * file,const int lineno,void (cleanup_fn)(void),int fd,uid_t owner,gid_t group)759 int safe_fchown(const char *file, const int lineno, void (cleanup_fn)(void),
760                 int fd, uid_t owner, gid_t group)
761 {
762 	int rval;
763 
764 	rval = fchown(fd, owner, group);
765 
766 	if (rval == -1) {
767 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
768 			"fchown(%d,%d,%d) failed", fd, owner, group);
769 	} else if (rval) {
770 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
771 			"Invalid fchown(%d,%d,%d) return value %d", fd,
772 			owner, group, rval);
773 	}
774 
775 	return rval;
776 }
777 
safe_wait(const char * file,const int lineno,void (cleanup_fn)(void),int * status)778 pid_t safe_wait(const char *file, const int lineno, void (cleanup_fn)(void),
779                 int *status)
780 {
781 	pid_t rval;
782 
783 	rval = wait(status);
784 
785 	if (rval == -1) {
786 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
787 			"wait(%p) failed", status);
788 	} else if (rval < 0) {
789 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
790 			"Invalid wait(%p) return value %d", status, rval);
791 	}
792 
793 	return rval;
794 }
795 
safe_waitpid(const char * file,const int lineno,void (cleanup_fn)(void),pid_t pid,int * status,int opts)796 pid_t safe_waitpid(const char *file, const int lineno, void (cleanup_fn)(void),
797                    pid_t pid, int *status, int opts)
798 {
799 	pid_t rval;
800 
801 	rval = waitpid(pid, status, opts);
802 
803 	if (rval == -1) {
804 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
805 			"waitpid(%d,%p,%d) failed", pid, status, opts);
806 	} else if (rval < 0) {
807 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
808 			"Invalid waitpid(%d,%p,%d) return value %d", pid,
809 			status, opts, rval);
810 	}
811 
812 	return rval;
813 }
814 
safe_memalign(const char * file,const int lineno,void (* cleanup_fn)(void),size_t alignment,size_t size)815 void *safe_memalign(const char *file, const int lineno,
816 		    void (*cleanup_fn) (void), size_t alignment, size_t size)
817 {
818 	void *rval;
819 
820 	rval = memalign(alignment, size);
821 
822 	if (rval == NULL) {
823 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
824 			"memalign() failed");
825 	}
826 
827 	return rval;
828 }
829 
safe_kill(const char * file,const int lineno,void (cleanup_fn)(void),pid_t pid,int sig)830 int safe_kill(const char *file, const int lineno, void (cleanup_fn)(void),
831 	      pid_t pid, int sig)
832 {
833 	int rval;
834 
835 	rval = kill(pid, sig);
836 
837 	if (rval == -1) {
838 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
839 			"kill(%d,%s) failed", pid, tst_strsig(sig));
840 	} else if (rval) {
841 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
842 			"Invalid kill(%d,%s) return value %d", pid,
843 			tst_strsig(sig), rval);
844 	}
845 
846 	return rval;
847 }
848 
safe_mkfifo(const char * file,const int lineno,void (* cleanup_fn)(void),const char * pathname,mode_t mode)849 int safe_mkfifo(const char *file, const int lineno,
850                 void (*cleanup_fn)(void), const char *pathname, mode_t mode)
851 {
852 	int rval;
853 
854 	rval = mkfifo(pathname, mode);
855 
856 	if (rval == -1) {
857 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
858 			"mkfifo(%s, %04o) failed", pathname, mode);
859 	} else if (rval) {
860 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
861 			"Invalid mkfifo(%s, %04o) return value %d", pathname,
862 			mode, rval);
863 	}
864 
865 	return rval;
866 }
867 
safe_rename(const char * file,const int lineno,void (* cleanup_fn)(void),const char * oldpath,const char * newpath)868 int safe_rename(const char *file, const int lineno, void (*cleanup_fn)(void),
869 		const char *oldpath, const char *newpath)
870 {
871 	int rval;
872 
873 	rval = rename(oldpath, newpath);
874 
875 	if (rval == -1) {
876 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
877 			"rename(%s, %s) failed", oldpath, newpath);
878 	} else if (rval) {
879 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
880 			"Invalid rename(%s, %s) return value %d", oldpath,
881 			newpath, rval);
882 	}
883 
884 	return rval;
885 }
886 
887 static const char *const fuse_fs_types[] = {
888 	"exfat",
889 	"ntfs",
890 };
891 
possibly_fuse(const char * fs_type)892 static int possibly_fuse(const char *fs_type)
893 {
894 	unsigned int i;
895 
896 	if (!fs_type)
897 		return 0;
898 
899 	for (i = 0; i < ARRAY_SIZE(fuse_fs_types); i++) {
900 		if (!strcmp(fuse_fs_types[i], fs_type))
901 			return 1;
902 	}
903 
904 	return 0;
905 }
906 
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)907 int safe_mount(const char *file, const int lineno, void (*cleanup_fn)(void),
908 	       const char *source, const char *target,
909 	       const char *filesystemtype, unsigned long mountflags,
910 	       const void *data)
911 {
912 	int rval = -1;
913 	char mpath[PATH_MAX];
914 
915 	if (realpath(target, mpath)) {
916 		tst_resm_(file, lineno, TINFO,
917 			"Mounting %s to %s fstyp=%s flags=%lx",
918 			source, mpath, filesystemtype, mountflags);
919 	} else {
920 		tst_resm_(file, lineno, TINFO | TERRNO,
921 			"Cannot resolve the absolute path of %s", target);
922 	}
923 	/*
924 	 * Don't try using the kernel's NTFS driver when mounting NTFS, since
925 	 * the kernel's NTFS driver doesn't have proper write support.
926 	 */
927 	if (!filesystemtype || strcmp(filesystemtype, "ntfs")) {
928 		mode_t old_umask = umask(0);
929 
930 		rval = mount(source, target, filesystemtype, mountflags, data);
931 		umask(old_umask);
932 		if (!rval)
933 			return 0;
934 	}
935 
936 	/*
937 	 * The FUSE filesystem executes mount.fuse helper, which tries to
938 	 * execute corresponding binary name which is encoded at the start of
939 	 * the source string and separated by # from the device name.
940          *
941 	 * The mount helpers are called mount.$fs_type.
942 	 */
943 	if (possibly_fuse(filesystemtype)) {
944 		char buf[1024];
945 
946 		tst_resm_(file, lineno, TINFO, "Trying FUSE...");
947 		snprintf(buf, sizeof(buf), "mount.%s '%s' '%s'",
948 			filesystemtype, source, target);
949 
950 		rval = tst_system(buf);
951 		if (WIFEXITED(rval) && WEXITSTATUS(rval) == 0)
952 			return 0;
953 
954 		tst_brkm_(file, lineno, TBROK, cleanup_fn,
955 			"mount.%s failed with %i", filesystemtype, rval);
956 		return -1;
957 	} else if (rval == -1) {
958 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
959 			"mount(%s, %s, %s, %lu, %p) failed", source, target,
960 			filesystemtype, mountflags, data);
961 	} else {
962 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
963 			"Invalid mount(%s, %s, %s, %lu, %p) return value %d",
964 			source, target, filesystemtype, mountflags, data,
965 			rval);
966 	}
967 
968 	return rval;
969 }
970 
safe_umount(const char * file,const int lineno,void (* cleanup_fn)(void),const char * target)971 int safe_umount(const char *file, const int lineno, void (*cleanup_fn)(void),
972 		const char *target)
973 {
974 	int rval;
975 	char mpath[PATH_MAX];
976 
977 	if (realpath(target, mpath)) {
978 		tst_resm_(file, lineno, TINFO, "Umounting %s", mpath);
979 	} else {
980 		tst_resm_(file, lineno, TINFO | TERRNO,
981 			"Cannot resolve the absolute path of %s", target);
982 	}
983 
984 	rval = tst_umount(target);
985 
986 	if (rval == -1) {
987 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
988 			"umount(%s) failed", target);
989 	} else if (rval) {
990 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
991 			"Invalid umount(%s) return value %d", target, rval);
992 	}
993 
994 	return rval;
995 }
996 
safe_opendir(const char * file,const int lineno,void (cleanup_fn)(void),const char * name)997 DIR* safe_opendir(const char *file, const int lineno, void (cleanup_fn)(void),
998                   const char *name)
999 {
1000 	DIR *rval;
1001 
1002 	rval = opendir(name);
1003 
1004 	if (!rval) {
1005 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1006 			"opendir(%s) failed", name);
1007 	}
1008 
1009 	return rval;
1010 }
1011 
safe_closedir(const char * file,const int lineno,void (cleanup_fn)(void),DIR * dirp)1012 int safe_closedir(const char *file, const int lineno, void (cleanup_fn)(void),
1013                   DIR *dirp)
1014 {
1015 	int rval;
1016 
1017 	rval = closedir(dirp);
1018 
1019 	if (rval == -1) {
1020 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1021 			"closedir(%p) failed", dirp);
1022 	} else if (rval) {
1023 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1024 			"Invalid closedir(%p) return value %d", dirp, rval);
1025 	}
1026 
1027 	return rval;
1028 }
1029 
safe_readdir(const char * file,const int lineno,void (cleanup_fn)(void),DIR * dirp)1030 struct dirent *safe_readdir(const char *file, const int lineno, void (cleanup_fn)(void),
1031                             DIR *dirp)
1032 {
1033 	struct dirent *rval;
1034 	int err = errno;
1035 
1036 	errno = 0;
1037 	rval = readdir(dirp);
1038 
1039 	if (!rval && errno) {
1040 		tst_brkm_(file, lineno, TBROK | TERRNO, cleanup_fn,
1041 			"readdir(%p) failed", dirp);
1042 	}
1043 
1044 	errno = err;
1045 	return rval;
1046 }
1047 
safe_getpriority(const char * file,const int lineno,int which,id_t who)1048 int safe_getpriority(const char *file, const int lineno, int which, id_t who)
1049 {
1050 	int rval, err = errno;
1051 
1052 	errno = 0;
1053 	rval = getpriority(which, who);
1054 
1055 	if (rval == -1 && errno) {
1056 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1057 			"getpriority(%i, %i) failed", which, who);
1058 	} else if (errno) {
1059 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1060 			"getpriority(%i, %i) failed with return value %d",
1061 			which, who, rval);
1062 	}
1063 
1064 	errno = err;
1065 	return rval;
1066 }
1067 
safe_getxattr(const char * file,const int lineno,const char * path,const char * name,void * value,size_t size)1068 ssize_t safe_getxattr(const char *file, const int lineno, const char *path,
1069 		      const char *name, void *value, size_t size)
1070 {
1071 	ssize_t rval;
1072 
1073 	rval = getxattr(path, name, value, size);
1074 
1075 	if (rval == -1) {
1076 		if (errno == ENOTSUP) {
1077 			tst_brkm_(file, lineno, TCONF, NULL,
1078 				"no xattr support in fs or mounted without user_xattr option");
1079 			return rval;
1080 		}
1081 
1082 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1083 			"getxattr(%s, %s, %p, %zu) failed",
1084 			path, name, value, size);
1085 	} else if (rval < 0) {
1086 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1087 			"Invalid getxattr(%s, %s, %p, %zu) return value %zd",
1088 			path, name, value, size, rval);
1089 	}
1090 
1091 	return rval;
1092 }
1093 
safe_setxattr(const char * file,const int lineno,const char * path,const char * name,const void * value,size_t size,int flags)1094 int safe_setxattr(const char *file, const int lineno, const char *path,
1095 		  const char *name, const void *value, size_t size, int flags)
1096 {
1097 	int rval;
1098 
1099 	rval = setxattr(path, name, value, size, flags);
1100 
1101 	if (rval == -1) {
1102 		if (errno == ENOTSUP) {
1103 			tst_brkm_(file, lineno, TCONF, NULL,
1104 				"no xattr support in fs, mounted without user_xattr option "
1105 				"or invalid namespace/name format");
1106 			return rval;
1107 		}
1108 
1109 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1110 			"setxattr(%s, %s, %p, %zu) failed",
1111 			path, name, value, size);
1112 	} else if (rval) {
1113 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1114 			"Invalid setxattr(%s, %s, %p, %zu) return value %d",
1115 			path, name, value, size, rval);
1116 	}
1117 
1118 	return rval;
1119 }
1120 
safe_lsetxattr(const char * file,const int lineno,const char * path,const char * name,const void * value,size_t size,int flags)1121 int safe_lsetxattr(const char *file, const int lineno, const char *path,
1122 		   const char *name, const void *value, size_t size, int flags)
1123 {
1124 	int rval;
1125 
1126 	rval = lsetxattr(path, name, value, size, flags);
1127 
1128 	if (rval == -1) {
1129 		if (errno == ENOTSUP) {
1130 			tst_brkm_(file, lineno, TCONF, NULL,
1131 				"no xattr support in fs, mounted without user_xattr option "
1132 				"or invalid namespace/name format");
1133 			return rval;
1134 		}
1135 
1136 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1137 			"lsetxattr(%s, %s, %p, %zu, %i) failed",
1138 			path, name, value, size, flags);
1139 	} else if (rval) {
1140 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1141 			"Invalid lsetxattr(%s, %s, %p, %zu, %i) return value %d",
1142 			path, name, value, size, flags, rval);
1143 	}
1144 
1145 	return rval;
1146 }
1147 
safe_fsetxattr(const char * file,const int lineno,int fd,const char * name,const void * value,size_t size,int flags)1148 int safe_fsetxattr(const char *file, const int lineno, int fd, const char *name,
1149 		   const void *value, size_t size, int flags)
1150 {
1151 	int rval;
1152 
1153 	rval = fsetxattr(fd, name, value, size, flags);
1154 
1155 	if (rval == -1) {
1156 		if (errno == ENOTSUP) {
1157 			tst_brkm_(file, lineno, TCONF, NULL,
1158 				"no xattr support in fs, mounted without user_xattr option "
1159 				"or invalid namespace/name format");
1160 			return rval;
1161 		}
1162 
1163 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1164 			"fsetxattr(%i, %s, %p, %zu, %i) failed",
1165 			fd, name, value, size, flags);
1166 	} else if (rval) {
1167 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1168 			"Invalid fsetxattr(%i, %s, %p, %zu, %i) return value %d",
1169 			fd, name, value, size, flags, rval);
1170 	}
1171 
1172 	return rval;
1173 }
1174 
safe_removexattr(const char * file,const int lineno,const char * path,const char * name)1175 int safe_removexattr(const char *file, const int lineno, const char *path,
1176 		const char *name)
1177 {
1178 	int rval;
1179 
1180 	rval = removexattr(path, name);
1181 
1182 	if (rval == -1) {
1183 		if (errno == ENOTSUP) {
1184 			tst_brkm_(file, lineno, TCONF, NULL,
1185 				"no xattr support in fs or mounted without user_xattr option");
1186 			return rval;
1187 		}
1188 
1189 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1190 			"removexattr(%s, %s) failed", path, name);
1191 	} else if (rval) {
1192 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1193 			"Invalid removexattr(%s, %s) return value %d", path,
1194 			name, rval);
1195 	}
1196 
1197 	return rval;
1198 }
1199 
safe_lremovexattr(const char * file,const int lineno,const char * path,const char * name)1200 int safe_lremovexattr(const char *file, const int lineno, const char *path,
1201 		const char *name)
1202 {
1203 	int rval;
1204 
1205 	rval = lremovexattr(path, name);
1206 
1207 	if (rval == -1) {
1208 		if (errno == ENOTSUP) {
1209 			tst_brkm_(file, lineno, TCONF, NULL,
1210 				"no xattr support in fs or mounted without user_xattr option");
1211 			return rval;
1212 		}
1213 
1214 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1215 			"lremovexattr(%s, %s) failed", path, name);
1216 	} else if (rval) {
1217 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1218 			"Invalid lremovexattr(%s, %s) return value %d", path,
1219 			name, rval);
1220 	}
1221 
1222 	return rval;
1223 }
1224 
safe_fremovexattr(const char * file,const int lineno,int fd,const char * name)1225 int safe_fremovexattr(const char *file, const int lineno, int fd,
1226 		const char *name)
1227 {
1228 	int rval;
1229 
1230 	rval = fremovexattr(fd, name);
1231 
1232 	if (rval == -1) {
1233 		if (errno == ENOTSUP) {
1234 			tst_brkm_(file, lineno, TCONF, NULL,
1235 				"no xattr support in fs or mounted without user_xattr option");
1236 			return rval;
1237 		}
1238 
1239 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1240 			"fremovexattr(%i, %s) failed", fd, name);
1241 	} else if (rval) {
1242 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1243 			"Invalid fremovexattr(%i, %s) return value %d", fd,
1244 			name, rval);
1245 	}
1246 
1247 	return rval;
1248 }
1249 
safe_fsync(const char * file,const int lineno,int fd)1250 int safe_fsync(const char *file, const int lineno, int fd)
1251 {
1252 	int rval;
1253 
1254 	rval = fsync(fd);
1255 
1256 	if (rval == -1) {
1257 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1258 			"fsync(%i) failed", fd);
1259 	} else if (rval) {
1260 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1261 			"Invalid fsync(%i) return value %d", fd, rval);
1262 	}
1263 
1264 	return rval;
1265 }
1266 
safe_setsid(const char * file,const int lineno)1267 pid_t safe_setsid(const char *file, const int lineno)
1268 {
1269 	pid_t rval;
1270 
1271 	rval = setsid();
1272 
1273 	if (rval == -1) {
1274 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1275 			"setsid() failed");
1276 	}
1277 
1278 	return rval;
1279 }
1280 
safe_mknod(const char * file,const int lineno,const char * pathname,mode_t mode,dev_t dev)1281 int safe_mknod(const char *file, const int lineno, const char *pathname,
1282 	mode_t mode, dev_t dev)
1283 {
1284 	int rval;
1285 
1286 	rval = mknod(pathname, mode, dev);
1287 
1288 	if (rval == -1) {
1289 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1290 			"mknod() failed");
1291 	} else if (rval) {
1292 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1293 			"Invalid mknod() return value %d", rval);
1294 	}
1295 
1296 	return rval;
1297 }
1298 
safe_mlock(const char * file,const int lineno,const void * addr,size_t len)1299 int safe_mlock(const char *file, const int lineno, const void *addr,
1300 	size_t len)
1301 {
1302 	int rval;
1303 
1304 	rval = mlock(addr, len);
1305 
1306 	if (rval == -1) {
1307 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1308 			"mlock() failed");
1309 	} else if (rval) {
1310 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1311 			"Invalid mlock() return value %d", rval);
1312 	}
1313 
1314 	return rval;
1315 }
1316 
safe_munlock(const char * file,const int lineno,const void * addr,size_t len)1317 int safe_munlock(const char *file, const int lineno, const void *addr,
1318 	size_t len)
1319 {
1320 	int rval;
1321 
1322 	rval = munlock(addr, len);
1323 
1324 	if (rval == -1) {
1325 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1326 			"munlock() failed");
1327 	} else if (rval) {
1328 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1329 			"Invalid munlock() return value %d", rval);
1330 	}
1331 
1332 	return rval;
1333 }
1334 
safe_mincore(const char * file,const int lineno,void * start,size_t length,unsigned char * vec)1335 int safe_mincore(const char *file, const int lineno, void *start,
1336 	size_t length, unsigned char *vec)
1337 {
1338 	int rval;
1339 
1340 	rval = mincore(start, length, vec);
1341 
1342 	if (rval == -1) {
1343 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1344 			"mincore() failed");
1345 	} else if (rval) {
1346 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1347 			"Invalid mincore() return value %d", rval);
1348 	}
1349 
1350 	return rval;
1351 }
1352 
safe_sysinfo(const char * file,const int lineno,struct sysinfo * info)1353 int safe_sysinfo(const char *file, const int lineno, struct sysinfo *info)
1354 {
1355 	int ret;
1356 
1357 	errno = 0;
1358 	ret = sysinfo(info);
1359 
1360 	if (ret == -1) {
1361 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1362 			"sysinfo() failed");
1363 	} else if (ret) {
1364 		tst_brkm_(file, lineno, TBROK | TERRNO, NULL,
1365 			"Invalid sysinfo() return value %d", ret);
1366 	}
1367 
1368 	return ret;
1369 }
1370