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