]> git.saurik.com Git - apple/copyfile.git/blob - copyfile_test/systemx.c
copyfile-166.tar.gz
[apple/copyfile.git] / copyfile_test / systemx.c
1 //
2 // systemx.c
3 // copyfile_test
4 // Stolen from the test routines from the apfs project.
5 //
6 #include <fcntl.h>
7 #include <libgen.h>
8 #include <spawn.h>
9 #include <stdarg.h>
10 #include <stdbool.h>
11 #include <unistd.h>
12 #include <sys/stat.h>
13
14 #include "systemx.h"
15 #include "test_utils.h"
16
17
18 int __attribute__((sentinel)) systemx(const char *prog, ...)
19 {
20 const char *args[64];
21
22 va_list ap;
23
24 const char **parg = args;
25
26 *parg++ = basename((char *)prog);
27
28 va_start(ap, prog);
29
30 bool quiet = false, quiet_stderr = false;
31
32 while ((*parg = va_arg(ap, char *))) {
33 if (*parg == SYSTEMX_QUIET) {
34 quiet = true;
35 } else if (*parg == SYSTEMX_QUIET_STDERR)
36 quiet_stderr = true;
37 else
38 ++parg;
39 }
40
41 va_end(ap);
42
43 posix_spawn_file_actions_t facts, *pfacts = NULL;
44
45 if (quiet || quiet_stderr) {
46 posix_spawn_file_actions_init(&facts);
47 if (quiet)
48 posix_spawn_file_actions_addopen(&facts, STDOUT_FILENO, "/dev/null", O_APPEND, 0);
49 if (quiet_stderr)
50 posix_spawn_file_actions_addopen(&facts, STDERR_FILENO, "/dev/null", O_APPEND, 0);
51 pfacts = &facts;
52 }
53
54 pid_t pid;
55 assert_no_err(errno = posix_spawn(&pid, prog, pfacts, NULL,
56 (char * const *)args, NULL));
57
58 if (pfacts)
59 posix_spawn_file_actions_destroy(pfacts);
60
61 int status;
62 assert(ignore_eintr(waitpid(pid, &status, 0), -1) == pid);
63
64 if (WIFEXITED(status))
65 return WEXITSTATUS(status);
66 else
67 return -1;
68 }