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