• 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 	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