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>
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ TESTSDIR= ${TESTSBASE}/fs
|
|||||||
|
|
||||||
SUBDIR+= common .WAIT
|
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+= tmpfs umapfs union
|
||||||
TESTS_SUBDIRS+= vfs
|
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