xref: /freebsd/tools/test/stress2/misc/mkfifo6.sh (revision 9768746b)
1#!/bin/sh
2
3#
4# Copyright (c) 2017 Dell EMC Isilon
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# mkfifo(2), select(2) with tmpfs(5) scenario.
30
31. ../default.cfg
32[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
33
34dir=/tmp
35odir=`pwd`
36cd $dir
37sed '1,/^EOF/d' < $odir/$0 > $dir/mkfifo6.c
38mycc -o mkfifo6 -Wall -Wextra -O0 -g mkfifo6.c || exit 1
39rm -f mkfifo6.c
40cd $odir
41
42mount | grep -q "on $mntpoint " && umount -f $mntpoint
43mount -o size=1g -t tmpfs tmpfs $mntpoint
44
45fifo=$mntpoint/fifo.file
46cd $mntpoint
47/tmp/mkfifo6 $fifo
48s=$?
49cd $odir
50
51while mount | grep "on $mntpoint " | grep -q tmpfs; do
52	umount $mntpoint || sleep 1
53done
54rm -rf /tmp/mkfifo6
55exit $s
56
57EOF
58#include <sys/param.h>
59#include <sys/mman.h>
60#include <sys/stat.h>
61#include <sys/wait.h>
62
63#include <err.h>
64#include <errno.h>
65#include <fcntl.h>
66#include <signal.h>
67#include <stdio.h>
68#include <stdlib.h>
69#include <time.h>
70#include <unistd.h>
71
72static char *path;
73
74#define PARALLEL 1
75
76static void
77reader(void)
78{
79	fd_set rset;
80	struct timeval timeout;
81	int fd, n, r;
82	char ch;
83
84	do {
85		if((fd = open(path, O_RDONLY)) == -1)
86			if (errno != EINTR)
87				err(1, "open(%s, O_RDONLY)",
88				    path);
89		if (fd == -1)
90			warn("open(%s) ro", path);
91	} while (fd == -1);
92
93	/* timeout */
94	ch = 'z';
95	FD_ZERO(&rset);
96	FD_SET(fd, &rset);
97	timeout.tv_sec  = 0;
98	timeout.tv_usec = 100000;
99	if ((n = select(fd + 1, &rset, NULL, NULL, &timeout)) < 0)
100		if (errno != EINTR)
101			err(1, "select()");
102	if (n != 0)
103		fprintf(stderr, "FAIL Expected n == 0, got %d\n", n);
104	if (n == 1 && FD_ISSET(fd, &rset)) {
105		r = read(fd, &ch, 1);
106		if (r == -1)
107			err(1, "read");
108		if (r != 0)
109			fprintf(stderr, "read(2): %c\n", ch);
110		else
111			fprintf(stderr, "read(2): EOF\n");
112	}
113
114	sleep(3);
115	if (close(fd) == -1)
116		err(1, "close() in child");
117	_exit(n);
118}
119
120static void
121writer(void)
122{
123	int fd;
124
125	do {
126		if ((fd = open(path, O_WRONLY)) == -1)
127			if (errno != EINTR)
128				err(1, "open(%s, O_WRONLY)",
129				    path);
130		if (fd == -1)
131			warn("open(%s) wr", path);
132	} while (fd == -1);
133	sleep(2);
134	if (write(fd, "a", 1) != 1)
135		err(1, "write one");
136	if (close(fd) == -1)
137		warn("close() in parent");
138}
139
140static void
141test(void)
142{
143	pid_t pid;
144	int status;
145
146	if ((pid = fork()) == 0)
147		reader();
148	writer();
149
150	if (waitpid(pid, &status, 0) != pid)
151		err(1, "waitpid(%d)", pid);
152
153	_exit(status != 0);
154}
155
156int
157main(int argc __unused, char *argv[])
158{
159	int e, i, pids[PARALLEL], status;
160
161	if (argc != 2) {
162		fprintf(stderr, "Usage: %s <fifo file>\n", argv[0]);
163		exit(1);
164	}
165	path = argv[1];
166	e = 0;
167
168	unlink(path);
169	if (mkfifo(path, 0640) == -1)
170		err(1, "mkfifo(%s)", path);
171
172	for (i = 0; i < PARALLEL; i++) {
173		if ((pids[i] = fork()) == 0)
174			test();
175	}
176	for (i = 0; i < PARALLEL; i++) {
177		if (waitpid(pids[i], &status, 0) == -1)
178			err(1, "waitpid(%d)", pids[i]);
179		e += status == 0 ? 0 : 1;
180	}
181
182	return (e);
183}
184