read_write_all: use calloc instead of huge stack var in tests.
[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 <ccan/read_write_all/read_write_all.h>
4 #include <ccan/read_write_all/read_write_all.c>
5 #include <ccan/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;
28         int p2c[2];
29         int status;
30         pid_t child;
31
32         buffer = calloc(BUFSZ, 1);
33         plan_tests(4);
34
35         /* We fork and torture parent. */
36         if (pipe(p2c) != 0)
37                 err(1, "pipe");
38         child = fork();
39
40         if (!child) {
41                 close(p2c[1]);
42                 /* Make sure they started writing. */
43                 if (read(p2c[0], buffer, 1) != 1)
44                         exit(1);
45                 if (kill(getppid(), SIGUSR1) != 0)
46                         exit(2);
47                 if (!read_all(p2c[0], buffer+1, BUFSZ-1))
48                         exit(3);
49                 if (memchr(buffer, 0, BUFSZ)) {
50                         fprintf(stderr, "buffer has 0 at offset %ti\n",
51                                 memchr(buffer, 0, BUFSZ) - (void *)buffer);
52                         exit(4);
53                 }
54                 exit(0);
55         }
56         if (child == -1)
57                 err(1, "forking");
58
59         close(p2c[0]);
60         memset(buffer, 0xff, BUFSZ);
61         signal(SIGUSR1, got_signal);
62         ok1(write_all(p2c[1], buffer, BUFSZ));
63         ok1(sigcount == 1);
64         ok1(wait(&status) == child);
65         ok(WIFEXITED(status) && WEXITSTATUS(status) == 0,
66            "WIFEXITED(status) = %u, WEXITSTATUS(status) = %u",
67            WIFEXITED(status), WEXITSTATUS(status));
68         return exit_status();
69 }