Boot-to-ramdisk image generation scripts
[minix3.git] / tests / fs / fifofs / t_fifo.c
blobc4a2060a6ebcaa17da454f05ebfdb2dde2a09964
1 /* Test case written by Bharat Joshi */
2 #include <sys/cdefs.h>
3 __RCSID("$NetBSD: t_fifo.c,v 1.1 2011/12/21 00:17:07 christos Exp $");
5 #include <sys/types.h>
6 #include <sys/wait.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 #include <string.h>
14 #include <err.h>
15 #include <signal.h>
17 #ifndef STANDALONE
18 #include <atf-c.h>
19 #endif
21 #define FIFO_FILE_PATH "./fifo_file"
22 #define NUM_MESSAGES 20
23 #define MSG_SIZE 240
24 #define MESSAGE "I am fine"
26 static int verbose = 0;
29 * child_writer
31 * Function that runs in child context and opens and write to the FIFO.
33 static void
34 child_writer(void)
36 ssize_t rv;
37 int fd;
38 size_t count;
39 char message[MSG_SIZE] = MESSAGE;
40 static const struct timespec ts = { 0, 10000 };
42 /* Open the fifo in write-mode */
43 for (;;) {
44 fd = open(FIFO_FILE_PATH, O_WRONLY, 0);
45 if (fd == -1) {
46 if (errno == EINTR)
47 continue;
48 err(1, "Child: can't open fifo in write mode");
50 break;
53 for (count = 0; count < NUM_MESSAGES; count++) {
54 rv = write(fd, message, MSG_SIZE);
55 if (rv == -1) {
56 warn("Child: Failed to write");
57 break;
59 if (rv != MSG_SIZE)
60 warnx("Child: wrote only %zd", rv);
61 nanosleep(&ts, NULL);
64 close(fd);
65 if (verbose) {
66 printf("Child: Closed the fifo file\n");
67 fflush(stdout);
72 * _sigchild_handler
74 * Called when a sigchild is delivered
76 static void
77 sigchild_handler(int signo)
79 if (verbose) {
80 if (signo == SIGCHLD) {
81 printf("Got sigchild\n");
82 } else {
83 printf("Got %d signal\n", signo);
85 fflush(stdout);
90 static int
91 run(void)
93 pid_t pid;
94 ssize_t rv;
95 int fd, status;
96 size_t buf_size = MSG_SIZE;
97 char buf[MSG_SIZE];
98 struct sigaction action;
99 static const struct timespec ts = { 0, 500000000 };
101 /* Catch sigchild Signal */
102 memset(&action, 0, sizeof(action));
103 action.sa_handler = sigchild_handler;
104 sigemptyset(&action.sa_mask);
106 if (sigaction(SIGCHLD, &action, NULL) == -1)
107 err(1, "sigaction");
109 (void)unlink(FIFO_FILE_PATH);
110 /* First create a fifo */
111 if (mkfifo(FIFO_FILE_PATH, S_IRUSR | S_IWUSR) == -1)
112 err(1, "mkfifo");
114 switch ((pid = fork())) {
115 case -1:
116 err(1, "fork");
117 case 0:
118 /* Open the file in write mode so that subsequent read
119 * from parent side does not block the parent..
121 if ((fd = open(FIFO_FILE_PATH, O_WRONLY, 0)) == -1)
122 err(1, "failed to open fifo");
124 /* In child */
125 child_writer();
126 return 0;
128 default:
129 break;
132 if (verbose) {
133 printf("Child pid is %d\n", pid );
134 fflush(stdout);
137 /* In parent */
138 for (;;) {
139 if ((fd = open(FIFO_FILE_PATH, O_RDONLY, 0)) == -1) {
140 if (errno == EINTR)
141 continue;
142 else
143 err(1, "Failed to open the fifo in read mode");
145 /* Read mode is opened */
146 break;
150 nanosleep(&ts, NULL);
151 if (verbose) {
152 printf("Was sleeping...\n");
153 fflush(stdout);
156 for (;;) {
157 rv = read(fd, buf, buf_size);
159 if (rv == -1) {
160 warn("Failed to read");
161 if (errno == EINTR) {
162 if (verbose) {
163 printf("Parent interrupted, "
164 "continuing...\n");
165 fflush(stdout);
167 continue;
170 break;
173 if (rv == 0) {
174 if (verbose) {
175 printf("Writers have closed, looks like we "
176 "are done\n");
177 fflush(stdout);
179 break;
182 if (verbose) {
183 printf("Received %zd bytes message '%s'\n", rv, buf);
184 fflush(stdout);
188 close(fd);
190 if (verbose) {
191 printf("We are done.. now reap the child");
192 fflush(stdout);
195 // Read the child...
196 while (waitpid(pid, &status, 0) == -1)
197 if (errno != EINTR) {
198 warn("Failed to reap the child");
199 return 1;
202 if (verbose) {
203 printf("We are done completely\n");
204 fflush(stdout);
206 return 0;
209 #ifndef STANDALONE
210 ATF_TC(parent_child);
212 ATF_TC_HEAD(parent_child, tc)
214 atf_tc_set_md_var(tc, "descr", "Checks that when a fifo is shared "
215 "between a reader parent and a writer child, that read will "
216 "return EOF, and not get stuck after the child exits");
219 ATF_TC_BODY(parent_child, tc)
221 ATF_REQUIRE(run() == 0);
224 ATF_TP_ADD_TCS(tp)
226 ATF_TP_ADD_TC(tp, parent_child);
228 return atf_no_error();
230 #else
232 main(void)
234 verbose = 1;
235 return run();
237 #endif