Add a test for the latest fifofs fix.
This commit is contained in:
parent
87d8a6fadb
commit
013de02143
@ -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 @@ TESTSDIR= ${TESTSBASE}/fs
|
||||
|
||||
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
|
||||
|
||||
|
9
tests/fs/fifofs/Makefile
Normal file
9
tests/fs/fifofs/Makefile
Normal file
@ -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>
|
237
tests/fs/fifofs/t_fifo.c
Normal file
237
tests/fs/fifofs/t_fifo.c
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user