xref: /minix3/minix/tests/test38.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* Many of the tests require 1.6.n, n > 16, so we may as well assume that
2*433d6423SLionel Sambuc  * POSIX signals are implemented.
3*433d6423SLionel Sambuc  */
4*433d6423SLionel Sambuc #define SIGACTION
5*433d6423SLionel Sambuc 
6*433d6423SLionel Sambuc /* test38: read(), write()	Author: Jan-Mark Wams (jms@cs.vu.nl) */
7*433d6423SLionel Sambuc 
8*433d6423SLionel Sambuc #include <sys/types.h>
9*433d6423SLionel Sambuc #include <sys/stat.h>
10*433d6423SLionel Sambuc #include <sys/wait.h>
11*433d6423SLionel Sambuc #include <stdlib.h>
12*433d6423SLionel Sambuc #include <unistd.h>
13*433d6423SLionel Sambuc #include <string.h>
14*433d6423SLionel Sambuc #include <fcntl.h>
15*433d6423SLionel Sambuc #include <limits.h>
16*433d6423SLionel Sambuc #include <errno.h>
17*433d6423SLionel Sambuc #include <time.h>
18*433d6423SLionel Sambuc #include <signal.h>
19*433d6423SLionel Sambuc #include <stdio.h>
20*433d6423SLionel Sambuc 
21*433d6423SLionel Sambuc int max_error = 	4;
22*433d6423SLionel Sambuc #include "common.h"
23*433d6423SLionel Sambuc 
24*433d6423SLionel Sambuc #define ITERATIONS      3
25*433d6423SLionel Sambuc #define BUF_SIZE 1024
26*433d6423SLionel Sambuc 
27*433d6423SLionel Sambuc #define System(cmd)	if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
28*433d6423SLionel Sambuc #define Chdir(dir)	if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
29*433d6423SLionel Sambuc #define Stat(a,b)	if (stat(a,b) != 0) printf("Can't stat %s\n", a)
30*433d6423SLionel Sambuc 
31*433d6423SLionel Sambuc 
32*433d6423SLionel Sambuc int superuser;
33*433d6423SLionel Sambuc int signumber = 0;
34*433d6423SLionel Sambuc 
35*433d6423SLionel Sambuc void test38a(void);
36*433d6423SLionel Sambuc void test38b(void);
37*433d6423SLionel Sambuc void test38c(void);
38*433d6423SLionel Sambuc void setsignumber(int _signumber);
39*433d6423SLionel Sambuc 
main(int argc,char * argv[])40*433d6423SLionel Sambuc int main(int argc, char *argv[])
41*433d6423SLionel Sambuc {
42*433d6423SLionel Sambuc   int i, m = 0xFFFF;
43*433d6423SLionel Sambuc 
44*433d6423SLionel Sambuc   sync();
45*433d6423SLionel Sambuc   start(38);
46*433d6423SLionel Sambuc 
47*433d6423SLionel Sambuc   if (argc == 2) m = atoi(argv[1]);
48*433d6423SLionel Sambuc   superuser = (geteuid() == 0);
49*433d6423SLionel Sambuc   umask(0000);
50*433d6423SLionel Sambuc 
51*433d6423SLionel Sambuc   for (i = 0; i < ITERATIONS; i++) {
52*433d6423SLionel Sambuc 	if (m & 0001) test38a();
53*433d6423SLionel Sambuc 	if (m & 0002) test38b();
54*433d6423SLionel Sambuc 	if (m & 0004) test38c();
55*433d6423SLionel Sambuc   }
56*433d6423SLionel Sambuc   quit();
57*433d6423SLionel Sambuc 
58*433d6423SLionel Sambuc   return(-1);	/* Unreachable */
59*433d6423SLionel Sambuc }
60*433d6423SLionel Sambuc 
test38a()61*433d6423SLionel Sambuc void test38a()
62*433d6423SLionel Sambuc {				/* Try normal operation. */
63*433d6423SLionel Sambuc   int fd1;
64*433d6423SLionel Sambuc   struct stat st1, st2;
65*433d6423SLionel Sambuc   time_t time1;
66*433d6423SLionel Sambuc   char buf[BUF_SIZE];
67*433d6423SLionel Sambuc   int stat_loc;
68*433d6423SLionel Sambuc   int i, j;
69*433d6423SLionel Sambuc   int tube[2];
70*433d6423SLionel Sambuc 
71*433d6423SLionel Sambuc   subtest = 1;
72*433d6423SLionel Sambuc   System("rm -rf ../DIR_38/*");
73*433d6423SLionel Sambuc 
74*433d6423SLionel Sambuc   /* Let's open bar. */
75*433d6423SLionel Sambuc   if ((fd1 = open("bar", O_RDWR | O_CREAT, 0777)) != 3) e(1);
76*433d6423SLionel Sambuc   Stat("bar", &st1);
77*433d6423SLionel Sambuc 
78*433d6423SLionel Sambuc   /* Writing nothing should not affect the file at all. */
79*433d6423SLionel Sambuc   if (write(fd1, "", 0) != 0) e(2);
80*433d6423SLionel Sambuc   Stat("bar", &st2);
81*433d6423SLionel Sambuc   if (st1.st_uid != st2.st_uid) e(3);
82*433d6423SLionel Sambuc   if (st1.st_gid != st2.st_gid) e(4);	/* should be same */
83*433d6423SLionel Sambuc   if (st1.st_mode != st2.st_mode) e(5);
84*433d6423SLionel Sambuc   if (st1.st_size != st2.st_size) e(6);
85*433d6423SLionel Sambuc   if (st1.st_nlink != st2.st_nlink) e(7);
86*433d6423SLionel Sambuc   if (st1.st_mtime != st2.st_mtime) e(8);
87*433d6423SLionel Sambuc   if (st1.st_ctime != st2.st_ctime) e(9);
88*433d6423SLionel Sambuc   if (st1.st_atime != st2.st_atime) e(10);
89*433d6423SLionel Sambuc 
90*433d6423SLionel Sambuc   /* A write should update some status fields. */
91*433d6423SLionel Sambuc   time(&time1);
92*433d6423SLionel Sambuc   while (time1 >= time((time_t *)0))
93*433d6423SLionel Sambuc 	;
94*433d6423SLionel Sambuc   if (write(fd1, "foo", 4) != 4) e(11);
95*433d6423SLionel Sambuc   Stat("bar", &st2);
96*433d6423SLionel Sambuc   if (st1.st_mode != st2.st_mode) e(12);
97*433d6423SLionel Sambuc   if (st1.st_size >= st2.st_size) e(13);
98*433d6423SLionel Sambuc   if ((off_t) 4 != st2.st_size) e(14);
99*433d6423SLionel Sambuc   if (st1.st_nlink != st2.st_nlink) e(15);
100*433d6423SLionel Sambuc   if (st1.st_mtime >= st2.st_mtime) e(16);
101*433d6423SLionel Sambuc   if (st1.st_ctime >= st2.st_ctime) e(17);
102*433d6423SLionel Sambuc   if (st1.st_atime != st2.st_atime) e(18);
103*433d6423SLionel Sambuc 
104*433d6423SLionel Sambuc   /* Lseeks should not change the file status. */
105*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) - 2, SEEK_END) != 2) e(19);
106*433d6423SLionel Sambuc   Stat("bar", &st1);
107*433d6423SLionel Sambuc   if (st1.st_mode != st2.st_mode) e(20);
108*433d6423SLionel Sambuc   if (st1.st_size != st2.st_size) e(21);
109*433d6423SLionel Sambuc   if (st1.st_nlink != st2.st_nlink) e(22);
110*433d6423SLionel Sambuc   if (st1.st_mtime != st2.st_mtime) e(23);
111*433d6423SLionel Sambuc   if (st1.st_ctime != st2.st_ctime) e(24);
112*433d6423SLionel Sambuc   if (st1.st_atime != st2.st_atime) e(25);
113*433d6423SLionel Sambuc 
114*433d6423SLionel Sambuc   /* Writing should start at the current (2) position. */
115*433d6423SLionel Sambuc   if (write(fd1, "foo", 4) != 4) e(26);
116*433d6423SLionel Sambuc   Stat("bar", &st2);
117*433d6423SLionel Sambuc   if (st1.st_mode != st2.st_mode) e(27);
118*433d6423SLionel Sambuc   if (st1.st_size >= st2.st_size) e(28);
119*433d6423SLionel Sambuc   if ((off_t) 6 != st2.st_size) e(29);
120*433d6423SLionel Sambuc   if (st1.st_nlink != st2.st_nlink) e(30);
121*433d6423SLionel Sambuc   if (st1.st_mtime > st2.st_mtime) e(31);
122*433d6423SLionel Sambuc   if (st1.st_ctime > st2.st_ctime) e(32);
123*433d6423SLionel Sambuc   if (st1.st_atime != st2.st_atime) e(33);
124*433d6423SLionel Sambuc 
125*433d6423SLionel Sambuc   /* A read of zero bytes should not affect anything. */
126*433d6423SLionel Sambuc   if (read(fd1, buf, 0) != 0) e(34);
127*433d6423SLionel Sambuc   Stat("bar", &st1);
128*433d6423SLionel Sambuc   if (st1.st_uid != st2.st_uid) e(35);
129*433d6423SLionel Sambuc   if (st1.st_gid != st2.st_gid) e(36);	/* should be same */
130*433d6423SLionel Sambuc   if (st1.st_mode != st2.st_mode) e(37);
131*433d6423SLionel Sambuc   if (st1.st_size != st2.st_size) e(38);
132*433d6423SLionel Sambuc   if (st1.st_nlink != st2.st_nlink) e(39);
133*433d6423SLionel Sambuc   if (st1.st_mtime != st2.st_mtime) e(40);
134*433d6423SLionel Sambuc   if (st1.st_ctime != st2.st_ctime) e(41);
135*433d6423SLionel Sambuc   if (st1.st_atime != st2.st_atime) e(42);
136*433d6423SLionel Sambuc 
137*433d6423SLionel Sambuc   /* The file now should contain ``fofoo\0'' Let's check that. */
138*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(43);
139*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 6) e(44);
140*433d6423SLionel Sambuc   if (strcmp(buf, "fofoo") != 0) e(45);
141*433d6423SLionel Sambuc 
142*433d6423SLionel Sambuc   /* Only the Access Time should be updated. */
143*433d6423SLionel Sambuc   Stat("bar", &st2);
144*433d6423SLionel Sambuc   if (st1.st_mtime != st2.st_mtime) e(46);
145*433d6423SLionel Sambuc   if (st1.st_ctime != st2.st_ctime) e(47);
146*433d6423SLionel Sambuc   if (st1.st_atime >= st2.st_atime) e(48);
147*433d6423SLionel Sambuc 
148*433d6423SLionel Sambuc   /* A read of zero bytes should do nothing even at the end of the file. */
149*433d6423SLionel Sambuc   time(&time1);
150*433d6423SLionel Sambuc   while (time1 >= time((time_t *)0))
151*433d6423SLionel Sambuc 	;
152*433d6423SLionel Sambuc   if (read(fd1, buf, 0) != 0) e(49);
153*433d6423SLionel Sambuc   Stat("bar", &st1);
154*433d6423SLionel Sambuc   if (st1.st_size != st2.st_size) e(50);
155*433d6423SLionel Sambuc   if (st1.st_mtime != st2.st_mtime) e(51);
156*433d6423SLionel Sambuc   if (st1.st_ctime != st2.st_ctime) e(52);
157*433d6423SLionel Sambuc   if (st1.st_atime != st2.st_atime) e(53);
158*433d6423SLionel Sambuc 
159*433d6423SLionel Sambuc   /* Reading should be done from the current offset. */
160*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 0) e(54);
161*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(55);
162*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 4) e(56);
163*433d6423SLionel Sambuc   if (strcmp(buf, "foo") != 0) e(57);
164*433d6423SLionel Sambuc 
165*433d6423SLionel Sambuc   /* Reading should effect the current file position. */
166*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(58);
167*433d6423SLionel Sambuc   if (read(fd1, buf, 1) != 1) e(59);
168*433d6423SLionel Sambuc   if (*buf != 'f') e(60);
169*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(61);
170*433d6423SLionel Sambuc   if (read(fd1, buf, 1) != 1) e(62);
171*433d6423SLionel Sambuc   if (*buf != 'o') e(63);
172*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(64);
173*433d6423SLionel Sambuc   if (read(fd1, buf, 1) != 1) e(65);
174*433d6423SLionel Sambuc   if (*buf != 'o') e(66);
175*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 5) e(67);
176*433d6423SLionel Sambuc   if (read(fd1, buf, 1) != 1) e(68);
177*433d6423SLionel Sambuc   if (*buf != '\0') e(69);
178*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(70);
179*433d6423SLionel Sambuc 
180*433d6423SLionel Sambuc   /* Read's at EOF should return 0. */
181*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 0) e(71);
182*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(72);
183*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 0) e(73);
184*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(74);
185*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 0) e(75);
186*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(76);
187*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 0) e(77);
188*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(78);
189*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 0) e(79);
190*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(80);
191*433d6423SLionel Sambuc 
192*433d6423SLionel Sambuc   /* Writing should not always change the file size. */
193*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(81);
194*433d6423SLionel Sambuc   if (write(fd1, "ba", 2) != 2) e(82);
195*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(83);
196*433d6423SLionel Sambuc   Stat("bar", &st1);
197*433d6423SLionel Sambuc   if (st1.st_size != 6) e(84);
198*433d6423SLionel Sambuc 
199*433d6423SLionel Sambuc   /* Kill the \0 at the end. */
200*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 5, SEEK_SET) != 5) e(85);
201*433d6423SLionel Sambuc   if (write(fd1, "x", 1) != 1) e(86);
202*433d6423SLionel Sambuc 
203*433d6423SLionel Sambuc   /* And close the bar. */
204*433d6423SLionel Sambuc   if (close(fd1) != 0) e(87);
205*433d6423SLionel Sambuc 
206*433d6423SLionel Sambuc   /* Try some stuff with O_APPEND. Bar contains ``fobaox'' */
207*433d6423SLionel Sambuc   if ((fd1 = open("bar", O_RDWR | O_APPEND)) != 3) e(88);
208*433d6423SLionel Sambuc 
209*433d6423SLionel Sambuc   /* No matter what the file position is. Writes should append. */
210*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(89);
211*433d6423SLionel Sambuc   if (write(fd1, "y", 1) != 1) e(90);
212*433d6423SLionel Sambuc   Stat("bar", &st1);
213*433d6423SLionel Sambuc   if (st1.st_size != (off_t) 7) e(91);
214*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 7) e(92);
215*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(93);
216*433d6423SLionel Sambuc   if (write(fd1, "z", 2) != 2) e(94);
217*433d6423SLionel Sambuc 
218*433d6423SLionel Sambuc   /* The file should contain ``fobaoxyz\0'' == 9 chars long. */
219*433d6423SLionel Sambuc   Stat("bar", &st1);
220*433d6423SLionel Sambuc   if (st1.st_size != (off_t) 9) e(95);
221*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(96);
222*433d6423SLionel Sambuc 
223*433d6423SLionel Sambuc   /* Reading on a O_APPEND flag should be from the current offset. */
224*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(97);
225*433d6423SLionel Sambuc   if (read(fd1, buf, BUF_SIZE) != 9) e(98);
226*433d6423SLionel Sambuc   if (strcmp(buf, "fobaoxyz") != 0) e(99);
227*433d6423SLionel Sambuc   if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(100);
228*433d6423SLionel Sambuc 
229*433d6423SLionel Sambuc   if (close(fd1) != 0) e(101);
230*433d6423SLionel Sambuc 
231*433d6423SLionel Sambuc   /* Let's test fifo writes. First blocking. */
232*433d6423SLionel Sambuc   if (mkfifo("fifo", 0777) != 0) e(102);
233*433d6423SLionel Sambuc 
234*433d6423SLionel Sambuc   /* Read from fifo but no writer. */
235*433d6423SLionel Sambuc   System("rm -rf /tmp/sema.38a");
236*433d6423SLionel Sambuc   switch (fork()) {
237*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
238*433d6423SLionel Sambuc 
239*433d6423SLionel Sambuc       case 0:
240*433d6423SLionel Sambuc 	alarm(20);
241*433d6423SLionel Sambuc 	if ((fd1 = open("fifo", O_RDONLY)) != 3) e(103);
242*433d6423SLionel Sambuc 	system("> /tmp/sema.38a");
243*433d6423SLionel Sambuc 	system("while test -f /tmp/sema.38a; do sleep 1; done");
244*433d6423SLionel Sambuc errno =0;
245*433d6423SLionel Sambuc 	if (read(fd1, buf, BUF_SIZE) != 0) e(104);
246*433d6423SLionel Sambuc 	if (read(fd1, buf, BUF_SIZE) != 0) e(105);
247*433d6423SLionel Sambuc 	if (read(fd1, buf, BUF_SIZE) != 0) e(106);
248*433d6423SLionel Sambuc 	if (close(fd1) != 0) e(107);
249*433d6423SLionel Sambuc 	exit(0);
250*433d6423SLionel Sambuc 
251*433d6423SLionel Sambuc       default:
252*433d6423SLionel Sambuc 	if ((fd1 = open("fifo", O_WRONLY)) != 3) e(108);
253*433d6423SLionel Sambuc 	while (stat("/tmp/sema.38a", &st1) != 0) sleep(1);
254*433d6423SLionel Sambuc 	if (close(fd1) != 0) e(109);
255*433d6423SLionel Sambuc 	unlink("/tmp/sema.38a");
256*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(110);
257*433d6423SLionel Sambuc 	if (stat_loc != 0) e(111);	/* Alarm? */
258*433d6423SLionel Sambuc   }
259*433d6423SLionel Sambuc 
260*433d6423SLionel Sambuc   /* Read from fifo should wait for writer. */
261*433d6423SLionel Sambuc   switch (fork()) {
262*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
263*433d6423SLionel Sambuc 
264*433d6423SLionel Sambuc       case 0:
265*433d6423SLionel Sambuc 	alarm(20);
266*433d6423SLionel Sambuc 	if ((fd1 = open("fifo", O_RDONLY)) != 3) e(112);
267*433d6423SLionel Sambuc 	if (read(fd1, buf, BUF_SIZE) != 10) e(113);
268*433d6423SLionel Sambuc 	if (strcmp(buf, "Hi reader") != 0) e(114);
269*433d6423SLionel Sambuc 	if (close(fd1) != 0) e(115);
270*433d6423SLionel Sambuc 	exit(0);
271*433d6423SLionel Sambuc 
272*433d6423SLionel Sambuc       default:
273*433d6423SLionel Sambuc 	if ((fd1 = open("fifo", O_WRONLY)) != 3) e(116);
274*433d6423SLionel Sambuc 	sleep(1);
275*433d6423SLionel Sambuc 	if (write(fd1, "Hi reader", 10) != 10) e(117);
276*433d6423SLionel Sambuc 	if (close(fd1) != 0) e(118);
277*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(119);
278*433d6423SLionel Sambuc 	if (stat_loc != 0) e(120);	/* Alarm? */
279*433d6423SLionel Sambuc   }
280*433d6423SLionel Sambuc 
281*433d6423SLionel Sambuc #if DEAD_CODE
282*433d6423SLionel Sambuc   /* Does this test test what it is supposed to test??? */
283*433d6423SLionel Sambuc 
284*433d6423SLionel Sambuc   /* Read from fifo should wait for all writers to close. */
285*433d6423SLionel Sambuc   switch (fork()) {
286*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
287*433d6423SLionel Sambuc 
288*433d6423SLionel Sambuc       case 0:
289*433d6423SLionel Sambuc 	alarm(60);
290*433d6423SLionel Sambuc 	switch (fork()) {
291*433d6423SLionel Sambuc 	    case -1:	printf("Can't fork\n");	break;
292*433d6423SLionel Sambuc 	    case 0:
293*433d6423SLionel Sambuc 		alarm(20);
294*433d6423SLionel Sambuc 		if ((fd1 = open("fifo", O_WRONLY)) != 3) e(121);
295*433d6423SLionel Sambuc 		printf("C2 did open\n");
296*433d6423SLionel Sambuc 		if (close(fd1) != 0) e(122);
297*433d6423SLionel Sambuc 		printf("C2 did close\n");
298*433d6423SLionel Sambuc 		exit(0);
299*433d6423SLionel Sambuc 	    default:
300*433d6423SLionel Sambuc 		printf("C1 scheduled\n");
301*433d6423SLionel Sambuc 		if ((fd1 = open("fifo", O_WRONLY)) != 3) e(123);
302*433d6423SLionel Sambuc 		printf("C1 did open\n");
303*433d6423SLionel Sambuc 		sleep(2);
304*433d6423SLionel Sambuc 		if (close(fd1) != 0) e(124);
305*433d6423SLionel Sambuc 		printf("C1 did close\n");
306*433d6423SLionel Sambuc 		sleep(1);
307*433d6423SLionel Sambuc 		if (wait(&stat_loc) == -1) e(125);
308*433d6423SLionel Sambuc 		if (stat_loc != 0) e(126);	/* Alarm? */
309*433d6423SLionel Sambuc 	}
310*433d6423SLionel Sambuc 	exit(stat_loc);
311*433d6423SLionel Sambuc 
312*433d6423SLionel Sambuc       default: {
313*433d6423SLionel Sambuc 	int wait_status;
314*433d6423SLionel Sambuc 	printf("Parent running\n");
315*433d6423SLionel Sambuc 	sleep(1);				/* open in childs first */
316*433d6423SLionel Sambuc 	if ((fd1 = open("fifo", O_RDONLY)) != 3) e(127);
317*433d6423SLionel Sambuc 	if (read(fd1, buf, BUF_SIZE) != 0) e(128);
318*433d6423SLionel Sambuc 	if (close(fd1) != 0) e(129);
319*433d6423SLionel Sambuc 	printf("Parent closed\n");
320*433d6423SLionel Sambuc 	if ((wait_status=wait(&stat_loc)) == -1) e(130);
321*433d6423SLionel Sambuc 
322*433d6423SLionel Sambuc       printf("wait_status %d, stat_loc %d:", wait_status, stat_loc);
323*433d6423SLionel Sambuc       if (WIFSIGNALED(stat_loc)) {
324*433d6423SLionel Sambuc           printf(" killed, signal number %d\n", WTERMSIG(stat_loc));
325*433d6423SLionel Sambuc       }
326*433d6423SLionel Sambuc       else if (WIFEXITED(stat_loc)) {
327*433d6423SLionel Sambuc           printf(" normal exit, status %d\n", WEXITSTATUS(stat_loc));
328*433d6423SLionel Sambuc       }
329*433d6423SLionel Sambuc 
330*433d6423SLionel Sambuc 	if (stat_loc != 0) e(131);	/* Alarm? */
331*433d6423SLionel Sambuc       }
332*433d6423SLionel Sambuc   }
333*433d6423SLionel Sambuc #endif
334*433d6423SLionel Sambuc 
335*433d6423SLionel Sambuc   /* PIPE_BUF has to have a nice value. */
336*433d6423SLionel Sambuc   if (PIPE_BUF < 5) e(132);
337*433d6423SLionel Sambuc   if (BUF_SIZE < 1000) e(133);
338*433d6423SLionel Sambuc 
339*433d6423SLionel Sambuc   /* Writes of blocks smaller than PIPE_BUF should be atomic. */
340*433d6423SLionel Sambuc   System("rm -rf /tmp/sema.38b;> /tmp/sema.38b");
341*433d6423SLionel Sambuc   switch (fork()) {
342*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
343*433d6423SLionel Sambuc 
344*433d6423SLionel Sambuc       case 0:
345*433d6423SLionel Sambuc 	alarm(20);
346*433d6423SLionel Sambuc 	switch (fork()) {
347*433d6423SLionel Sambuc 	    case -1:	printf("Can't fork\n");	break;
348*433d6423SLionel Sambuc 
349*433d6423SLionel Sambuc 	    case 0:
350*433d6423SLionel Sambuc 		alarm(20);
351*433d6423SLionel Sambuc 		if ((fd1 = open("fifo", O_WRONLY)) != 3) e(134);
352*433d6423SLionel Sambuc 		for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
353*433d6423SLionel Sambuc 		system("while test -f /tmp/sema.38b; do sleep 1; done");
354*433d6423SLionel Sambuc 		if (close(fd1) != 0) e(135);
355*433d6423SLionel Sambuc 		exit(0);
356*433d6423SLionel Sambuc 
357*433d6423SLionel Sambuc 	    default:
358*433d6423SLionel Sambuc 		if ((fd1 = open("fifo", O_WRONLY)) != 3) e(136);
359*433d6423SLionel Sambuc 		for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
360*433d6423SLionel Sambuc 		while (stat("/tmp/sema.38b", &st1) == 0) sleep(1);
361*433d6423SLionel Sambuc 		if (close(fd1) != 0) e(137);
362*433d6423SLionel Sambuc 		if (wait(&stat_loc) == -1) e(138);
363*433d6423SLionel Sambuc 		if (stat_loc != 0) e(139);	/* Alarm? */
364*433d6423SLionel Sambuc 	}
365*433d6423SLionel Sambuc 	exit(stat_loc);
366*433d6423SLionel Sambuc 
367*433d6423SLionel Sambuc       default:
368*433d6423SLionel Sambuc 	if ((fd1 = open("fifo", O_RDONLY)) != 3) e(140);
369*433d6423SLionel Sambuc 	i = 0;
370*433d6423SLionel Sambuc 	memset(buf, '\0', BUF_SIZE);
371*433d6423SLionel Sambuc 
372*433d6423SLionel Sambuc 	/* Read buffer full or till EOF. */
373*433d6423SLionel Sambuc 	do {
374*433d6423SLionel Sambuc 		j = read(fd1, buf + i, BUF_SIZE - i);
375*433d6423SLionel Sambuc 		if (j > 0) {
376*433d6423SLionel Sambuc 			if (j % 5 != 0) e(141);
377*433d6423SLionel Sambuc 			i += j;
378*433d6423SLionel Sambuc 		}
379*433d6423SLionel Sambuc 	} while (j > 0 && i < 1000);
380*433d6423SLionel Sambuc 
381*433d6423SLionel Sambuc 	/* Signal the children to close write ends. This should not be */
382*433d6423SLionel Sambuc 	/* Necessary. But due to a bug in 1.16.6 this is necessary. */
383*433d6423SLionel Sambuc 	unlink("/tmp/sema.38b");
384*433d6423SLionel Sambuc 	if (j < 0) e(142);
385*433d6423SLionel Sambuc 	if (i != 1000) e(143);
386*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(144);
387*433d6423SLionel Sambuc 	if (stat_loc != 0) e(145);	/* Alarm? */
388*433d6423SLionel Sambuc 
389*433d6423SLionel Sambuc 	/* Check 200 times 1234. */
390*433d6423SLionel Sambuc 	for (i = 0; i < 200; i++)
391*433d6423SLionel Sambuc 		if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
392*433d6423SLionel Sambuc 	if (i != 200) e(146);
393*433d6423SLionel Sambuc 	if (buf[1000] != '\0') e(147);
394*433d6423SLionel Sambuc 	if (buf[1005] != '\0') e(148);
395*433d6423SLionel Sambuc 	if (buf[1010] != '\0') e(149);
396*433d6423SLionel Sambuc 	if (read(fd1, buf, BUF_SIZE) != 0) e(150);
397*433d6423SLionel Sambuc 	if (close(fd1) != 0) e(151);
398*433d6423SLionel Sambuc   }
399*433d6423SLionel Sambuc 
400*433d6423SLionel Sambuc   /* Read from pipe should wait for writer. */
401*433d6423SLionel Sambuc   if (pipe(tube) != 0) e(152);
402*433d6423SLionel Sambuc   switch (fork()) {
403*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
404*433d6423SLionel Sambuc       case 0:
405*433d6423SLionel Sambuc 	alarm(20);
406*433d6423SLionel Sambuc 	if (close(tube[1]) != 0) e(153);
407*433d6423SLionel Sambuc 	if (read(tube[0], buf, BUF_SIZE) != 10) e(154);
408*433d6423SLionel Sambuc 	if (strcmp(buf, "Hi reader") != 0) e(155);
409*433d6423SLionel Sambuc 	if (close(tube[0]) != 0) e(156);
410*433d6423SLionel Sambuc 	exit(0);
411*433d6423SLionel Sambuc       default:
412*433d6423SLionel Sambuc 	if (close(tube[0]) != 0) e(157);
413*433d6423SLionel Sambuc 	sleep(1);
414*433d6423SLionel Sambuc 	if (write(tube[1], "Hi reader", 10) != 10) e(158);
415*433d6423SLionel Sambuc 	if (close(tube[1]) != 0) e(159);
416*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(160);
417*433d6423SLionel Sambuc 	if (stat_loc != 0) e(161);	/* Alarm? */
418*433d6423SLionel Sambuc   }
419*433d6423SLionel Sambuc 
420*433d6423SLionel Sambuc   /* Read from pipe should wait for all writers to close. */
421*433d6423SLionel Sambuc   if (pipe(tube) != 0) e(162);
422*433d6423SLionel Sambuc   switch (fork()) {
423*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
424*433d6423SLionel Sambuc       case 0:
425*433d6423SLionel Sambuc 	alarm(20);
426*433d6423SLionel Sambuc 	if (close(tube[0]) != 0) e(163);
427*433d6423SLionel Sambuc 	switch (fork()) {
428*433d6423SLionel Sambuc 	    case -1:	printf("Can't fork\n");	break;
429*433d6423SLionel Sambuc 	    case 0:
430*433d6423SLionel Sambuc 		alarm(20);
431*433d6423SLionel Sambuc 		if (close(tube[1]) != 0) e(164);
432*433d6423SLionel Sambuc 		exit(0);
433*433d6423SLionel Sambuc 	    default:
434*433d6423SLionel Sambuc 		sleep(1);
435*433d6423SLionel Sambuc 		if (close(tube[1]) != 0) e(165);
436*433d6423SLionel Sambuc 		if (wait(&stat_loc) == -1) e(166);
437*433d6423SLionel Sambuc 		if (stat_loc != 0) e(167);	/* Alarm? */
438*433d6423SLionel Sambuc 	}
439*433d6423SLionel Sambuc 	exit(stat_loc);
440*433d6423SLionel Sambuc       default:
441*433d6423SLionel Sambuc 	if (close(tube[1]) != 0) e(168);
442*433d6423SLionel Sambuc 	if (read(tube[0], buf, BUF_SIZE) != 0) e(169);
443*433d6423SLionel Sambuc 	if (close(tube[0]) != 0) e(170);
444*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(171);
445*433d6423SLionel Sambuc 	if (stat_loc != 0) e(172);	/* Alarm? */
446*433d6423SLionel Sambuc   }
447*433d6423SLionel Sambuc 
448*433d6423SLionel Sambuc   /* Writes of blocks smaller than PIPE_BUF should be atomic. */
449*433d6423SLionel Sambuc   System("rm -rf /tmp/sema.38c;> /tmp/sema.38c");
450*433d6423SLionel Sambuc   if (pipe(tube) != 0) e(173);
451*433d6423SLionel Sambuc   switch (fork()) {
452*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
453*433d6423SLionel Sambuc       case 0:
454*433d6423SLionel Sambuc 	alarm(20);
455*433d6423SLionel Sambuc 	if (close(tube[0]) != 0) e(174);
456*433d6423SLionel Sambuc 	switch (fork()) {
457*433d6423SLionel Sambuc 	    case -1:	printf("Can't fork\n");	break;
458*433d6423SLionel Sambuc 	    case 0:
459*433d6423SLionel Sambuc 		alarm(20);
460*433d6423SLionel Sambuc 		for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
461*433d6423SLionel Sambuc 		system("while test -f /tmp/sema.38c; do sleep 1; done");
462*433d6423SLionel Sambuc 		if (close(tube[1]) != 0) e(175);
463*433d6423SLionel Sambuc 		exit(0);
464*433d6423SLionel Sambuc 	    default:
465*433d6423SLionel Sambuc 		for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
466*433d6423SLionel Sambuc 		while (stat("/tmp/sema.38c", &st1) == 0) sleep(1);
467*433d6423SLionel Sambuc 		if (close(tube[1]) != 0) e(176);
468*433d6423SLionel Sambuc 		if (wait(&stat_loc) == -1) e(177);
469*433d6423SLionel Sambuc 		if (stat_loc != 0) e(178);	/* Alarm? */
470*433d6423SLionel Sambuc 	}
471*433d6423SLionel Sambuc 	exit(stat_loc);
472*433d6423SLionel Sambuc       default:
473*433d6423SLionel Sambuc 	i = 0;
474*433d6423SLionel Sambuc 	if (close(tube[1]) != 0) e(179);
475*433d6423SLionel Sambuc 	memset(buf, '\0', BUF_SIZE);
476*433d6423SLionel Sambuc 	do {
477*433d6423SLionel Sambuc 		j = read(tube[0], buf + i, BUF_SIZE - i);
478*433d6423SLionel Sambuc 		if (j > 0) {
479*433d6423SLionel Sambuc 			if (j % 5 != 0) e(180);
480*433d6423SLionel Sambuc 			i += j;
481*433d6423SLionel Sambuc 		} else
482*433d6423SLionel Sambuc 			break;	/* EOF seen. */
483*433d6423SLionel Sambuc 	} while (i < 1000);
484*433d6423SLionel Sambuc 	unlink("/tmp/sema.38c");
485*433d6423SLionel Sambuc 	if (j < 0) e(181);
486*433d6423SLionel Sambuc 	if (i != 1000) e(182);
487*433d6423SLionel Sambuc 	if (close(tube[0]) != 0) e(183);
488*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(184);
489*433d6423SLionel Sambuc 	if (stat_loc != 0) e(185);	/* Alarm? */
490*433d6423SLionel Sambuc 
491*433d6423SLionel Sambuc 	/* Check 200 times 1234. */
492*433d6423SLionel Sambuc 	for (i = 0; i < 200; i++)
493*433d6423SLionel Sambuc 		if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
494*433d6423SLionel Sambuc 	if (i != 200) e(186);
495*433d6423SLionel Sambuc   }
496*433d6423SLionel Sambuc }
497*433d6423SLionel Sambuc 
test38b()498*433d6423SLionel Sambuc void test38b()
499*433d6423SLionel Sambuc {
500*433d6423SLionel Sambuc   int i, fd, stat_loc;
501*433d6423SLionel Sambuc   char buf[BUF_SIZE];
502*433d6423SLionel Sambuc   char buf2[BUF_SIZE];
503*433d6423SLionel Sambuc   struct stat st;
504*433d6423SLionel Sambuc 
505*433d6423SLionel Sambuc   subtest = 2;
506*433d6423SLionel Sambuc   System("rm -rf ../DIR_38/*");
507*433d6423SLionel Sambuc 
508*433d6423SLionel Sambuc   /* Lets try sequential writes. */
509*433d6423SLionel Sambuc   system("rm -rf /tmp/sema.38d");
510*433d6423SLionel Sambuc   System("> testing");
511*433d6423SLionel Sambuc   switch (fork()) {
512*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
513*433d6423SLionel Sambuc       case 0:
514*433d6423SLionel Sambuc 	alarm(20);
515*433d6423SLionel Sambuc 	if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(1);
516*433d6423SLionel Sambuc 	if (write(fd, "one ", 4) != 4) e(2);
517*433d6423SLionel Sambuc 	if (close(fd) != 0) e(3);
518*433d6423SLionel Sambuc 	system("> /tmp/sema.38d");
519*433d6423SLionel Sambuc 	system("while test -f /tmp/sema.38d; do sleep 1; done");
520*433d6423SLionel Sambuc 	if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(4);
521*433d6423SLionel Sambuc 	if (write(fd, "three ", 6) != 6) e(5);
522*433d6423SLionel Sambuc 	if (close(fd) != 0) e(6);
523*433d6423SLionel Sambuc 	system("> /tmp/sema.38d");
524*433d6423SLionel Sambuc 	exit(0);
525*433d6423SLionel Sambuc       default:
526*433d6423SLionel Sambuc 	while (stat("/tmp/sema.38d", &st) != 0) sleep(1);
527*433d6423SLionel Sambuc 	if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(7);
528*433d6423SLionel Sambuc 	if (write(fd, "two ", 4) != 4) e(8);
529*433d6423SLionel Sambuc 	if (close(fd) != 0) e(9);
530*433d6423SLionel Sambuc 	unlink("/tmp/sema.38d");
531*433d6423SLionel Sambuc 	while (stat("/tmp/sema.38d", &st) != 0) sleep(1);
532*433d6423SLionel Sambuc 	if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(10);
533*433d6423SLionel Sambuc 	if (write(fd, "four", 5) != 5) e(11);
534*433d6423SLionel Sambuc 	if (close(fd) != 0) e(12);
535*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(13);
536*433d6423SLionel Sambuc 	if (stat_loc != 0) e(14);	/* The alarm went off? */
537*433d6423SLionel Sambuc 	unlink("/tmp/sema.38d");
538*433d6423SLionel Sambuc   }
539*433d6423SLionel Sambuc   if ((fd = open("testing", O_RDONLY)) != 3) e(15);
540*433d6423SLionel Sambuc   if (read(fd, buf, BUF_SIZE) != 19) e(16);
541*433d6423SLionel Sambuc   if (strcmp(buf, "one two three four") != 0) e(17);
542*433d6423SLionel Sambuc   if (close(fd) != 0) e(18);
543*433d6423SLionel Sambuc 
544*433d6423SLionel Sambuc   /* Non written bytes in regular files should be zero. */
545*433d6423SLionel Sambuc   memset(buf2, '\0', BUF_SIZE);
546*433d6423SLionel Sambuc   if ((fd = open("bigfile", O_RDWR | O_CREAT, 0644)) != 3) e(19);
547*433d6423SLionel Sambuc   if (lseek(fd, (off_t) 102400, SEEK_SET) != (off_t) 102400L) e(20);
548*433d6423SLionel Sambuc   if (read(fd, buf, BUF_SIZE) != 0) e(21);
549*433d6423SLionel Sambuc   if (write(fd, ".", 1) != 1) e(22);
550*433d6423SLionel Sambuc   Stat("bigfile", &st);
551*433d6423SLionel Sambuc   if (st.st_size != (off_t) 102401) e(23);
552*433d6423SLionel Sambuc   if (lseek(fd, (off_t) 0, SEEK_SET) != 0) e(24);
553*433d6423SLionel Sambuc   for (i = 0; i < 102400 / BUF_SIZE; i++) {
554*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != BUF_SIZE) e(25);
555*433d6423SLionel Sambuc 	if (memcmp(buf, buf2, BUF_SIZE) != 0) e(26);
556*433d6423SLionel Sambuc   }
557*433d6423SLionel Sambuc   if (close(fd) != 0) e(27);
558*433d6423SLionel Sambuc }
559*433d6423SLionel Sambuc 
test38c()560*433d6423SLionel Sambuc void test38c()
561*433d6423SLionel Sambuc {				/* Test correct error behavior. */
562*433d6423SLionel Sambuc   char buf[BUF_SIZE];
563*433d6423SLionel Sambuc   int fd, tube[2], stat_loc;
564*433d6423SLionel Sambuc   struct stat st;
565*433d6423SLionel Sambuc   pid_t pid;
566*433d6423SLionel Sambuc #ifdef SIGACTION
567*433d6423SLionel Sambuc   struct sigaction act, oact;
568*433d6423SLionel Sambuc #else
569*433d6423SLionel Sambuc   void (*oldfunc) (int);
570*433d6423SLionel Sambuc #endif
571*433d6423SLionel Sambuc 
572*433d6423SLionel Sambuc   subtest = 3;
573*433d6423SLionel Sambuc   System("rm -rf ../DIR_38/*");
574*433d6423SLionel Sambuc 
575*433d6423SLionel Sambuc   /* To test if writing processes on closed pipes are signumbered. */
576*433d6423SLionel Sambuc #ifdef SIGACTION
577*433d6423SLionel Sambuc   act.sa_handler = setsignumber;
578*433d6423SLionel Sambuc   sigemptyset(&act.sa_mask);
579*433d6423SLionel Sambuc   act.sa_flags = 0;
580*433d6423SLionel Sambuc   if (sigaction(SIGPIPE, &act, &oact) != 0) e(1);
581*433d6423SLionel Sambuc #else
582*433d6423SLionel Sambuc   oldfunc = signal(SIGPIPE, setsignumber);
583*433d6423SLionel Sambuc #endif
584*433d6423SLionel Sambuc 
585*433d6423SLionel Sambuc   /* Non valid file descriptors should be an error. */
586*433d6423SLionel Sambuc   for (fd = -111; fd < 0; fd++) {
587*433d6423SLionel Sambuc 	errno = 0;
588*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != -1) e(2);
589*433d6423SLionel Sambuc 	if (errno != EBADF) e(3);
590*433d6423SLionel Sambuc   }
591*433d6423SLionel Sambuc   for (fd = 3; fd < 111; fd++) {
592*433d6423SLionel Sambuc 	errno = 0;
593*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != -1) e(4);
594*433d6423SLionel Sambuc 	if (errno != EBADF) e(5);
595*433d6423SLionel Sambuc   }
596*433d6423SLionel Sambuc   for (fd = -111; fd < 0; fd++) {
597*433d6423SLionel Sambuc 	errno = 0;
598*433d6423SLionel Sambuc 	if (write(fd, buf, BUF_SIZE) != -1) e(6);
599*433d6423SLionel Sambuc 	if (errno != EBADF) e(7);
600*433d6423SLionel Sambuc   }
601*433d6423SLionel Sambuc   for (fd = 3; fd < 111; fd++) {
602*433d6423SLionel Sambuc 	errno = 0;
603*433d6423SLionel Sambuc 	if (write(fd, buf, BUF_SIZE) != -1) e(8);
604*433d6423SLionel Sambuc 	if (errno != EBADF) e(9);
605*433d6423SLionel Sambuc   }
606*433d6423SLionel Sambuc 
607*433d6423SLionel Sambuc   /* Writing a pipe with no readers should trigger SIGPIPE. */
608*433d6423SLionel Sambuc   if (pipe(tube) != 0) e(10);
609*433d6423SLionel Sambuc   close(tube[0]);
610*433d6423SLionel Sambuc   switch (fork()) {
611*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
612*433d6423SLionel Sambuc       case 0:
613*433d6423SLionel Sambuc 	alarm(20);
614*433d6423SLionel Sambuc 	signumber = 0;
615*433d6423SLionel Sambuc 	if (write(tube[1], buf, BUF_SIZE) != -1) e(11);
616*433d6423SLionel Sambuc 	if (errno != EPIPE) e(12);
617*433d6423SLionel Sambuc 	if (signumber != SIGPIPE) e(13);
618*433d6423SLionel Sambuc 	if (close(tube[1]) != 0) e(14);
619*433d6423SLionel Sambuc 	exit(0);
620*433d6423SLionel Sambuc       default:
621*433d6423SLionel Sambuc 	close(tube[1]);
622*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(15);
623*433d6423SLionel Sambuc 	if (stat_loc != 0) e(16);	/* Alarm? */
624*433d6423SLionel Sambuc   }
625*433d6423SLionel Sambuc 
626*433d6423SLionel Sambuc   /* Writing a fifo with no readers should trigger SIGPIPE. */
627*433d6423SLionel Sambuc   System("> /tmp/sema.38e");
628*433d6423SLionel Sambuc   if (mkfifo("fifo", 0666) != 0) e(17);
629*433d6423SLionel Sambuc   switch (fork()) {
630*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
631*433d6423SLionel Sambuc       case 0:
632*433d6423SLionel Sambuc 	alarm(20);
633*433d6423SLionel Sambuc 	if ((fd = open("fifo", O_WRONLY)) != 3) e(18);
634*433d6423SLionel Sambuc 	system("while test -f /tmp/sema.38e; do sleep 1; done");
635*433d6423SLionel Sambuc 	signumber = 0;
636*433d6423SLionel Sambuc 	if (write(fd, buf, BUF_SIZE) != -1) e(19);
637*433d6423SLionel Sambuc 	if (errno != EPIPE) e(20);
638*433d6423SLionel Sambuc 	if (signumber != SIGPIPE) e(21);
639*433d6423SLionel Sambuc 	if (close(fd) != 0) e(22);
640*433d6423SLionel Sambuc 	exit(0);
641*433d6423SLionel Sambuc       default:
642*433d6423SLionel Sambuc 	if ((fd = open("fifo", O_RDONLY)) != 3) e(23);
643*433d6423SLionel Sambuc 	if (close(fd) != 0) e(24);
644*433d6423SLionel Sambuc 	unlink("/tmp/sema.38e");
645*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(25);
646*433d6423SLionel Sambuc 	if (stat_loc != 0) e(26);	/* Alarm? */
647*433d6423SLionel Sambuc   }
648*433d6423SLionel Sambuc 
649*433d6423SLionel Sambuc #ifdef SIGACTION
650*433d6423SLionel Sambuc   /* Restore normal (re)action to SIGPIPE. */
651*433d6423SLionel Sambuc   if (sigaction(SIGPIPE, &oact, NULL) != 0) e(27);
652*433d6423SLionel Sambuc #else
653*433d6423SLionel Sambuc   signal(SIGPIPE, oldfunc);
654*433d6423SLionel Sambuc #endif
655*433d6423SLionel Sambuc 
656*433d6423SLionel Sambuc   /* Read from fifo should return -1 and set errno to EAGAIN. */
657*433d6423SLionel Sambuc   System("rm -rf /tmp/sema.38[fgh]");
658*433d6423SLionel Sambuc   switch (fork()) {
659*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
660*433d6423SLionel Sambuc       case 0:
661*433d6423SLionel Sambuc 	alarm(20);
662*433d6423SLionel Sambuc 	system("while test ! -f /tmp/sema.38f; do sleep 1; done");
663*433d6423SLionel Sambuc 	System("rm -rf /tmp/sema.38f");
664*433d6423SLionel Sambuc 	if ((fd = open("fifo", O_WRONLY | O_NONBLOCK)) != 3) e(28);
665*433d6423SLionel Sambuc 	close(creat("/tmp/sema.38g", 0666));
666*433d6423SLionel Sambuc 	system("while test ! -f /tmp/sema.38h; do sleep 1; done");
667*433d6423SLionel Sambuc 	if (close(fd) != 0) e(38);
668*433d6423SLionel Sambuc 	System("rm -rf /tmp/sema.38h");
669*433d6423SLionel Sambuc 	exit(0);
670*433d6423SLionel Sambuc       default:
671*433d6423SLionel Sambuc 	if ((fd = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(30);
672*433d6423SLionel Sambuc 	close(creat("/tmp/sema.38f", 0666));
673*433d6423SLionel Sambuc 	system("while test ! -f /tmp/sema.38g; do sleep 1; done");
674*433d6423SLionel Sambuc 	System("rm -rf /tmp/sema.38g");
675*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != -1) e(31);
676*433d6423SLionel Sambuc 	if (errno != EAGAIN) e(32);
677*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != -1) e(33);
678*433d6423SLionel Sambuc 	if (errno != EAGAIN) e(34);
679*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != -1) e(35);
680*433d6423SLionel Sambuc 	if (errno != EAGAIN) e(36);
681*433d6423SLionel Sambuc 	close(creat("/tmp/sema.38h", 0666));
682*433d6423SLionel Sambuc 	while (stat("/tmp/sema.38h", &st) == 0) sleep(1);
683*433d6423SLionel Sambuc 	if (read(fd, buf, BUF_SIZE) != 0) e(37);
684*433d6423SLionel Sambuc 	if (close(fd) != 0) e(38);
685*433d6423SLionel Sambuc 	if (wait(&stat_loc) == -1) e(39);
686*433d6423SLionel Sambuc 	if (stat_loc != 0) e(40);	/* Alarm? */
687*433d6423SLionel Sambuc   }
688*433d6423SLionel Sambuc   System("rm -rf fifo");
689*433d6423SLionel Sambuc 
690*433d6423SLionel Sambuc   /* If a read is interrupted by a SIGNAL. */
691*433d6423SLionel Sambuc   if (pipe(tube) != 0) e(41);
692*433d6423SLionel Sambuc   switch (pid = fork()) {
693*433d6423SLionel Sambuc       case -1:	printf("Can't fork\n");	break;
694*433d6423SLionel Sambuc       case 0:
695*433d6423SLionel Sambuc 	alarm(20);
696*433d6423SLionel Sambuc #ifdef SIGACTION
697*433d6423SLionel Sambuc 	act.sa_handler = setsignumber;
698*433d6423SLionel Sambuc 	sigemptyset(&act.sa_mask);
699*433d6423SLionel Sambuc 	act.sa_flags = 0;
700*433d6423SLionel Sambuc 	if (sigaction(SIGUSR1, &act, &oact) != 0) e(42);
701*433d6423SLionel Sambuc #else
702*433d6423SLionel Sambuc 	oldfunc = signal(SIGUSR1, setsignumber);
703*433d6423SLionel Sambuc #endif
704*433d6423SLionel Sambuc 	if (read(tube[0], buf, BUF_SIZE) != -1) e(43);
705*433d6423SLionel Sambuc 	if (errno != EINTR) e(44);
706*433d6423SLionel Sambuc 	if (signumber != SIGUSR1) e(45);
707*433d6423SLionel Sambuc #ifdef SIGACTION
708*433d6423SLionel Sambuc 	/* Restore normal (re)action to SIGPIPE. */
709*433d6423SLionel Sambuc 	if (sigaction(SIGUSR1, &oact, NULL) != 0) e(46);
710*433d6423SLionel Sambuc #else
711*433d6423SLionel Sambuc 	signal(SIGUSR1, oldfunc);
712*433d6423SLionel Sambuc #endif
713*433d6423SLionel Sambuc 	close(tube[0]);
714*433d6423SLionel Sambuc 	close(tube[1]);
715*433d6423SLionel Sambuc 	exit(0);
716*433d6423SLionel Sambuc       default:
717*433d6423SLionel Sambuc 	/* The sleep 1 should give the child time to start the read. */
718*433d6423SLionel Sambuc 	sleep(1);
719*433d6423SLionel Sambuc 	close(tube[0]);
720*433d6423SLionel Sambuc 	kill(pid, SIGUSR1);
721*433d6423SLionel Sambuc 	wait(&stat_loc);
722*433d6423SLionel Sambuc 	if (stat_loc != 0) e(47);	/* Alarm? */
723*433d6423SLionel Sambuc 	close(tube[1]);
724*433d6423SLionel Sambuc   }
725*433d6423SLionel Sambuc }
726*433d6423SLionel Sambuc 
setsignumber(signum)727*433d6423SLionel Sambuc void setsignumber(signum)
728*433d6423SLionel Sambuc int signum;
729*433d6423SLionel Sambuc {
730*433d6423SLionel Sambuc   signumber = signum;
731*433d6423SLionel Sambuc }
732*433d6423SLionel Sambuc 
733