* sim/cris/c/pipe2.c: Adjust expected output.
[external/binutils.git] / sim / testsuite / sim / cris / c / pipe2.c
1 /* Check that closing a pipe with a nonempty buffer works.
2 #notarget: cris*-*-elf
3 #output: got: a\ngot: b\nexit: 0\n
4 */
5
6
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <limits.h>
11 #include <unistd.h>
12 #include <sched.h>
13 #include <signal.h>
14 #include <errno.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <string.h>
18 int pip[2];
19
20 int pipemax;
21
22 int
23 process (void *arg)
24 {
25   char *s = arg;
26   int lots = pipemax + 256;
27   char *buf = malloc (lots);
28   int ret;
29
30   if (buf == NULL)
31     abort ();
32
33   *buf = *s;
34
35   /* The first write should go straight through.  */
36   if (write (pip[1], buf, 1) != 1)
37     abort ();
38
39   *buf = s[1];
40
41   /* The second write may or may not be successful for the whole
42      write, but should be successful for at least the pipemax part.
43      As linux/limits.h clamps PIPE_BUF to 4096, but the page size is
44      actually 8k, we can get away with that much.  There should be no
45      error, though.  Doing this on host shows that for
46      x86_64-unknown-linux-gnu (2.6.14-1.1656_FC4) pipemax * 10 can be
47      successfully written, perhaps for similar reasons.  */
48   ret = write (pip[1], buf, lots);
49   if (ret < pipemax)
50     {
51       fprintf (stderr, "ret: %d, %s, %d\n", ret, strerror (errno), pipemax);
52       fflush (0);
53       abort ();
54     }
55
56   return 0;
57 }
58
59 int
60 main (void)
61 {
62   int retcode;
63   int pid;
64   int st = 0;
65   long stack[16384];
66   char buf[1];
67
68   /* We need to turn this off because we don't want (to have to model) a
69      SIGPIPE resulting from the close.  */
70   if (signal (SIGPIPE, SIG_IGN) != SIG_DFL)
71     abort ();
72
73   retcode = pipe (pip);
74
75   if (retcode != 0)
76     {
77       fprintf (stderr, "Bad pipe %d\n", retcode);
78       abort ();
79     }
80
81 #ifdef PIPE_MAX
82   pipemax = PIPE_MAX;
83 #else
84   pipemax = fpathconf (pip[1], _PC_PIPE_BUF);
85 #endif
86
87   if (pipemax <= 0)
88     {
89       fprintf (stderr, "Bad pipemax %d\n", pipemax);
90       abort ();
91     }
92
93   pid = clone (process, (char *) stack + sizeof (stack) - 64,
94                (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
95                | SIGCHLD, "ab");
96   if (pid <= 0)
97     {
98       fprintf (stderr, "Bad clone %d\n", pid);
99       abort ();
100     }
101
102   while ((retcode = read (pip[0], buf, 1)) == 0)
103     ;
104
105   if (retcode != 1)
106     {
107       fprintf (stderr, "Bad read 1: %d\n", retcode);
108       abort ();
109     }
110
111   printf ("got: %c\n", buf[0]);
112
113   /* Need to read out something from the second write too before
114      closing, or the writer can get EPIPE. */
115   while ((retcode = read (pip[0], buf, 1)) == 0)
116     ;
117
118   if (retcode != 1)
119     {
120       fprintf (stderr, "Bad read 2: %d\n", retcode);
121       abort ();
122     }
123
124   printf ("got: %c\n", buf[0]);
125
126   if (close (pip[0]) != 0)
127     {
128       perror ("pip close");
129       abort ();
130     }
131
132   retcode = waitpid (pid, &st, __WALL);
133
134   if (retcode != pid || !WIFEXITED (st))
135     {
136       fprintf (stderr, "Bad wait %d:%d %x\n", pid, retcode, st);
137       perror ("errno");
138       abort ();
139     }
140
141   printf ("exit: %d\n", WEXITSTATUS (st));
142   return 0;
143 }