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