Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/fs Add a test for the latest fifofs fix.



details:   https://anonhg.NetBSD.org/src/rev/9ae4fede6998
branches:  trunk
changeset: 772158:9ae4fede6998
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Dec 21 00:17:06 2011 +0000

description:
Add a test for the latest fifofs fix.

diffstat:

 tests/fs/Makefile        |    4 +-
 tests/fs/fifofs/Makefile |    9 +
 tests/fs/fifofs/t_fifo.c |  237 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 248 insertions(+), 2 deletions(-)

diffs (272 lines):

diff -r 757762007764 -r 9ae4fede6998 tests/fs/Makefile
--- a/tests/fs/Makefile Tue Dec 20 23:56:28 2011 +0000
+++ b/tests/fs/Makefile Wed Dec 21 00:17:06 2011 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.21 2011/03/10 20:02:26 pooka Exp $
+# $NetBSD: Makefile,v 1.22 2011/12/21 00:17:06 christos Exp $
 
 .include <bsd.own.mk>
 
@@ -6,7 +6,7 @@
 
 SUBDIR+=       common .WAIT
 
-TESTS_SUBDIRS+=        ffs hfs kernfs lfs msdosfs nfs nullfs psshfs ptyfs puffs
+TESTS_SUBDIRS+=        ffs fifofs hfs kernfs lfs msdosfs nfs nullfs psshfs ptyfs puffs
 TESTS_SUBDIRS+=        tmpfs umapfs union
 TESTS_SUBDIRS+=        vfs
 
diff -r 757762007764 -r 9ae4fede6998 tests/fs/fifofs/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fs/fifofs/Makefile  Wed Dec 21 00:17:06 2011 +0000
@@ -0,0 +1,9 @@
+#      $NetBSD: Makefile,v 1.1 2011/12/21 00:17:07 christos Exp $
+#
+
+TESTSDIR=      ${TESTSBASE}/fs/fifo
+WARNS=         4
+
+TESTS_C=       t_fifo
+
+.include <bsd.test.mk>
diff -r 757762007764 -r 9ae4fede6998 tests/fs/fifofs/t_fifo.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fs/fifofs/t_fifo.c  Wed Dec 21 00:17:06 2011 +0000
@@ -0,0 +1,237 @@
+/* Test case written by Bharat Joshi */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_fifo.c,v 1.1 2011/12/21 00:17:07 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <err.h>
+#include <signal.h>
+
+#ifndef STANDALONE
+#include <atf-c.h>
+#endif
+
+#define FIFO_FILE_PATH       "./fifo_file"
+#define NUM_MESSAGES         20
+#define MSG_SIZE             240
+#define MESSAGE              "I am fine"
+
+static int verbose = 0;
+
+/*
+ * child_writer
+ *
+ * Function that runs in child context and opens and write to the FIFO.
+ */
+static void
+child_writer(void)
+{
+       ssize_t rv;
+       int fd;
+       size_t count;
+       char message[MSG_SIZE] = MESSAGE;
+       static const struct timespec ts = { 0, 10000 };
+
+       /* Open the fifo in write-mode */
+       for (;;) {
+               fd = open(FIFO_FILE_PATH, O_WRONLY, 0);
+               if (fd == -1) {
+                       if (errno == EINTR)
+                               continue;
+                       err(1, "Child: can't open fifo in write mode");
+               }
+               break;
+       }
+
+       for (count = 0; count < NUM_MESSAGES; count++) {
+               rv = write(fd, message, MSG_SIZE);
+               if (rv == -1) {
+                       warn("Child: Failed to write");
+                       break;
+               }
+               if (rv != MSG_SIZE)
+                       warnx("Child: wrote only %zd", rv);
+               nanosleep(&ts, NULL);
+       }
+
+       close(fd);
+       if (verbose) {
+               printf("Child: Closed the fifo file\n");
+               fflush(stdout);
+       }
+}
+
+/*
+ * _sigchild_handler
+ *
+ * Called when a sigchild is delivered
+ */
+static void
+sigchild_handler(int signo)
+{
+       if (verbose) {
+               if (signo == SIGCHLD) {
+                       printf("Got sigchild\n");
+               } else {
+                       printf("Got %d signal\n", signo);
+               }
+               fflush(stdout);
+       }
+
+}
+
+static int
+run(void)
+{
+       pid_t pid;
+       ssize_t rv;
+       int fd, status;
+       size_t buf_size = MSG_SIZE;
+       char buf[MSG_SIZE];
+       struct sigaction action;
+       static const struct timespec ts = { 0, 500000000 };
+
+       /* Catch sigchild Signal */
+       memset(&action, 0, sizeof(action));
+       action.sa_handler = sigchild_handler;
+       sigemptyset(&action.sa_mask);
+
+       if (sigaction(SIGCHLD, &action, NULL) == -1)
+               err(1, "sigaction");
+
+       (void)unlink(FIFO_FILE_PATH);
+       /* First create a fifo */
+       if (mkfifo(FIFO_FILE_PATH, S_IRUSR | S_IWUSR) == -1)
+               err(1, "mkfifo");
+
+       switch ((pid = fork())) {
+       case -1:
+               err(1, "fork");
+       case 0:
+               /* Open the file in write mode so that subsequent read 
+                * from parent side does not block the parent..
+                */
+               if ((fd = open(FIFO_FILE_PATH, O_WRONLY, 0)) == -1)
+                       err(1, "failed to open fifo");
+
+               /* In child */
+               child_writer();
+               return 0;
+
+       default:
+               break;
+       }
+
+       if (verbose) {
+               printf("Child pid is %d\n", pid );
+               fflush(stdout);
+       }
+
+       /* In parent */
+       for (;;) {
+               if ((fd = open(FIFO_FILE_PATH, O_RDONLY, 0)) == -1) {
+                       if (errno == EINTR)
+                               continue;
+                       else
+                               err(1, "Failed to open the fifo in read mode");
+               }
+               /* Read mode is opened */
+               break;
+
+       }
+
+       nanosleep(&ts, NULL);
+       if (verbose) {
+               printf("Was sleeping...\n");
+               fflush(stdout);
+       }
+
+       for (;;) {
+               rv = read(fd, buf, buf_size);
+
+               if (rv == -1) {
+                       warn("Failed to read");
+                       if (errno == EINTR) {
+                               if (verbose) {
+                                       printf("Parent interrupted, "
+                                           "continuing...\n");
+                                       fflush(stdout);
+                               }
+                               continue;
+                       }
+
+                       break;
+               }
+
+               if (rv == 0) {
+                       if (verbose) {
+                               printf("Writers have closed, looks like we "
+                                   "are done\n");
+                               fflush(stdout);
+                       }
+                       break;
+               }
+
+               if (verbose) {
+                       printf("Received %zd bytes message '%s'\n", rv, buf);
+                       fflush(stdout);
+               }
+       }
+
+       close(fd);
+
+       if (verbose) {
+               printf("We are done.. now reap the child");
+               fflush(stdout);
+       }
+
+       // Read the child...
+       while (waitpid(pid, &status, 0) == -1)
+               if (errno != EINTR) {
+                       warn("Failed to reap the child");
+                       return 1;
+               }
+
+       if (verbose) {
+               printf("We are done completely\n");
+               fflush(stdout);
+       }
+       return 0;
+}
+
+#ifndef STANDALONE
+ATF_TC(parent_child);      
+
+ATF_TC_HEAD(parent_child, tc)
+{
+        atf_tc_set_md_var(tc, "descr", "Checks that when a fifo is shared "
+           "between a reader parent and a writer child, that read will "
+           "return EOF, and not get stuck after the child exits");
+}
+ 
+ATF_TC_BODY(parent_child, tc)
+{       
+        ATF_REQUIRE(run() == 0);
+}       
+
+ATF_TP_ADD_TCS(tp)
+{       
+        ATF_TP_ADD_TC(tp, parent_child);
+        
+        return atf_no_error();
+}       
+#else
+int
+main(void)
+{
+       verbose = 1;
+       return run();
+}
+#endif



Home | Main Index | Thread Index | Old Index