ab21cd31575f72c56d0ae7df658f5d04acdf7fdc
[ccan] / ccan / read_write_all / test / run-write_all.c
1 /* FIXME: Do something tricky to ensure we really do loop in write_all. */
2
3 #include "read_write_all/read_write_all.h"
4 #include "read_write_all/read_write_all.c"
5 #include "tap/tap.h"
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <signal.h>
9 #include <limits.h>
10 #include <sys/wait.h>
11 #include <err.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15
16 static volatile int sigcount;
17 static void got_signal(int sig)
18 {
19         sigcount++;
20 }
21
22 /* < PIPE_BUF *will* be atomic.  But > PIPE_BUF only *might* be non-atomic. */
23 #define BUFSZ (1024*1024)
24
25 int main(int argc, char *argv[])
26 {
27         char buffer[BUFSZ*2] = { 0 };
28         int p2c[2];
29         int status;
30         pid_t child;
31
32         plan_tests(4);
33
34         /* We fork and torture parent. */
35         if (pipe(p2c) != 0)
36                 err(1, "pipe");
37         child = fork();
38
39         if (!child) {
40                 close(p2c[1]);
41                 /* Make sure they started writing. */
42                 if (read(p2c[0], buffer, 1) != 1)
43                         exit(1);
44                 if (kill(getppid(), SIGUSR1) != 0)
45                         exit(2);
46                 if (!read_all(p2c[0], buffer+1, sizeof(buffer)-1))
47                         exit(3);
48                 if (memchr(buffer, 0, sizeof(buffer))) {
49                         fprintf(stderr, "buffer has 0 at offset %ti\n",
50                                 memchr(buffer, 0, sizeof(buffer)) - (void *)buffer);
51                         exit(4);
52                 }
53                 exit(0);
54         }
55         if (child == -1)
56                 err(1, "forking");
57
58         close(p2c[0]);
59         memset(buffer, 0xff, sizeof(buffer));
60         signal(SIGUSR1, got_signal);
61         ok1(write_all(p2c[1], buffer, sizeof(buffer)));
62         ok1(sigcount == 1);
63         ok1(wait(&status) == child);
64         ok(WIFEXITED(status) && WEXITSTATUS(status) == 0,
65            "WIFEXITED(status) = %u, WEXITSTATUS(status) = %u",
66            WIFEXITED(status), WEXITSTATUS(status));
67         return exit_status();
68 }