xref: /freebsd/tools/test/stress2/misc/mkfifo7.sh (revision 3f0efe05432b1633991114ca4ca330102a561959)
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), poll(2) with tmpfs(4) 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/mkfifo7.c
38mycc -o mkfifo7 -Wall -Wextra -O0 -g mkfifo7.c || exit 1
39rm -f mkfifo7.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/mkfifo7 $fifo
48s=$?
49cd $odir
50
51while mount | grep "on $mntpoint " | grep -q tmpfs; do
52	umount $mntpoint || sleep 1
53done
54rm -rf /tmp/mkfifo7
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 <poll.h>
67#include <signal.h>
68#include <stdio.h>
69#include <stdlib.h>
70#include <time.h>
71#include <unistd.h>
72
73static char *path;
74
75#define PARALLEL 1
76
77static void
78reader(void)
79{
80	struct pollfd pfd;
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	/* Read one character */
94	pfd.fd = fd;
95	pfd.events = POLLIN;
96	if ((n = poll(&pfd, 1, 0)) == -1)
97		err(1, "poll()");
98	if (n == 1) {
99		r = read(fd, &ch, 1);
100		if (r == -1)
101			err(1, "read");
102		if (r != 0)
103			fprintf(stderr, "read(1): %c\n", ch);
104		else
105			fprintf(stderr, "read(1): EOF\n");
106	}
107
108	/* timeout */
109	ch = 'z';
110	if ((n = poll(&pfd, 1, 7000)) == -1)
111		err(1, "poll()");
112	if (n != 1)
113		fprintf(stderr, "FAIL Expected n == 1, got %d\n", n);
114	if (n == 1) {
115		r = read(fd, &ch, 1);
116		if (r == -1)
117			err(1, "read");
118		if (r == 0)
119			fprintf(stderr, "read(2): EOF\n");
120	}
121
122	/* timeout */
123	ch = 'z';
124	if ((n = poll(&pfd, 1, 7000)) == -1)
125		err(1, "poll()");
126	if (n != 1)
127		fprintf(stderr, "FAIL Expected n == 1, got %d\n", n);
128	if (n == 1) {
129		r = read(fd, &ch, 1);
130		if (r == -1)
131			err(1, "read");
132		if (r != 0)
133			fprintf(stderr, "read(3): %c\n", ch);
134	}
135
136	if (close(fd) == -1)
137		err(1, "close() in child");
138	_exit(n == 1 ? 0 : 1);
139}
140
141static void
142writer(void)
143{
144	int fd;
145
146	do {
147		if ((fd = open(path, O_WRONLY)) == -1)
148			if (errno != EINTR)
149				err(1, "open(%s, O_WRONLY)",
150				    path);
151		if (fd == -1)
152			warn("open(%s) wr", path);
153	} while (fd == -1);
154	if (write(fd, "a", 1) != 1)
155		err(1, "write one");
156	if (close(fd) == -1)
157		warn("close() in parent");
158}
159
160static void
161test(void)
162{
163	pid_t pid;
164	int status;
165
166	if ((pid = fork()) == 0)
167		reader();
168	writer();
169
170	if (waitpid(pid, &status, 0) != pid)
171		err(1, "waitpid(%d)", pid);
172
173	_exit(status != 0);
174}
175
176int
177main(int argc __unused, char *argv[])
178{
179	int e, i, pids[PARALLEL], status;
180
181	if (argc != 2) {
182		fprintf(stderr, "Usage: %s <fifo file>\n", argv[0]);
183		exit(1);
184	}
185	path = argv[1];
186	e = 0;
187
188	unlink(path);
189	if (mkfifo(path, 0640) == -1)
190		err(1, "mkfifo(%s)", path);
191
192	for (i = 0; i < PARALLEL; i++) {
193		if ((pids[i] = fork()) == 0)
194			test();
195	}
196	for (i = 0; i < PARALLEL; i++) {
197		if (waitpid(pids[i], &status, 0) == -1)
198			err(1, "waitpid(%d)", pids[i]);
199		e += status == 0 ? 0 : 1;
200	}
201
202	return (e);
203}
204