pipecmd: test can't-exec case.
[ccan] / ccan / pipecmd / test / run.c
1 #include <ccan/pipecmd/pipecmd.h>
2 /* Include the C files directly. */
3 #include <ccan/pipecmd/pipecmd.c>
4 #include <ccan/tap/tap.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8
9 int main(int argc, char *argv[])
10 {
11         pid_t child;
12         int infd, outfd, status;
13         char buf[5] = "test";
14
15         /* We call ourselves, to test pipe. */
16         if (argc == 2) {
17                 if (strcmp(argv[1], "out") == 0) {
18                         if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf))
19                                 exit(1);
20                 } else if (strcmp(argv[1], "in") == 0) {
21                         if (read(STDIN_FILENO, buf, sizeof(buf)) != sizeof(buf))
22                                 exit(1);
23                         if (memcmp(buf, "test", sizeof(buf)) != 0)
24                                 exit(1);
25                 } else if (strcmp(argv[1], "inout") == 0) {
26                         if (read(STDIN_FILENO, buf, sizeof(buf)) != sizeof(buf))
27                                 exit(1);
28                         buf[0]++;
29                         if (write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf))
30                                 exit(1);
31                 } else
32                         abort();
33                 exit(0);
34         }
35
36         /* This is how many tests you plan to run */
37         plan_tests(28);
38         child = pipecmd(&outfd, &infd, argv[0], "inout", NULL);
39         if (!ok1(child > 0))
40                 exit(1);
41         ok1(write(infd, buf, sizeof(buf)) == sizeof(buf));
42         ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf));
43         buf[0]--;
44         ok1(memcmp(buf, "test", sizeof(buf)) == 0);
45         ok1(waitpid(child, &status, 0) == child);
46         ok1(WIFEXITED(status));
47         ok1(WEXITSTATUS(status) == 0);
48
49         child = pipecmd(NULL, &infd, argv[0], "in", NULL);
50         if (!ok1(child > 0))
51                 exit(1);
52         ok1(write(infd, buf, sizeof(buf)) == sizeof(buf));
53         ok1(waitpid(child, &status, 0) == child);
54         ok1(WIFEXITED(status));
55         ok1(WEXITSTATUS(status) == 0);
56
57         child = pipecmd(&outfd, NULL, argv[0], "out", NULL);
58         if (!ok1(child > 0))
59                 exit(1);
60         ok1(read(outfd, buf, sizeof(buf)) == sizeof(buf));
61         ok1(memcmp(buf, "test", sizeof(buf)) == 0);
62         ok1(waitpid(child, &status, 0) == child);
63         ok1(WIFEXITED(status));
64         ok1(WEXITSTATUS(status) == 0);
65
66         // Writing to /dev/null should be fine.
67         child = pipecmd(NULL, NULL, argv[0], "out", NULL);
68         if (!ok1(child > 0))
69                 exit(1);
70         ok1(waitpid(child, &status, 0) == child);
71         ok1(WIFEXITED(status));
72         ok1(WEXITSTATUS(status) == 0);
73
74         // Reading should fail.
75         child = pipecmd(NULL, NULL, argv[0], "in", NULL);
76         if (!ok1(child > 0))
77                 exit(1);
78         ok1(waitpid(child, &status, 0) == child);
79         ok1(WIFEXITED(status));
80         ok1(WEXITSTATUS(status) == 1);
81
82         // Can't run non-existent file, but errno set correctly.
83         child = pipecmd(NULL, NULL, "/doesnotexist", "in", NULL);
84         ok1(errno == ENOENT);
85         ok1(child < 0);
86
87         /* This exits depending on whether all tests passed */
88         return exit_status();
89 }