1/*	$NetBSD: t_fifos.c,v 1.6 2017/01/13 21:30:39 christos Exp $	*/
2
3#include <sys/types.h>
4#include <sys/mount.h>
5
6#include <atf-c.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <pthread.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14
15#include <rump/rump.h>
16#include <rump/rump_syscalls.h>
17
18#include <ufs/ufs/ufsmount.h>
19
20#include "h_macros.h"
21
22ATF_TC_WITH_CLEANUP(fifos);
23ATF_TC_HEAD(fifos, tc)
24{
25	atf_tc_set_md_var(tc, "descr", "test fifo support in ffs");
26	atf_tc_set_md_var(tc, "timeout", "5");
27}
28
29#define teststr1 "raving & drooling"
30#define teststr2 "haha, charade"
31
32static void *
33w1(void *arg)
34{
35	int fd;
36
37	fd = rump_sys_open("sheep", O_WRONLY);
38	if (fd == -1)
39		atf_tc_fail_errno("w1 open");
40	if (rump_sys_write(fd, teststr1, sizeof(teststr1)) != sizeof(teststr1))
41		atf_tc_fail_errno("w1 write");
42	rump_sys_close(fd);
43
44	return NULL;
45}
46
47static void *
48w2(void *arg)
49{
50	int fd;
51
52	fd = rump_sys_open("pigs", O_WRONLY);
53	if (fd == -1)
54		atf_tc_fail_errno("w2 open");
55	if (rump_sys_write(fd, teststr2, sizeof(teststr2)) != sizeof(teststr2))
56		atf_tc_fail_errno("w2 write");
57	rump_sys_close(fd);
58
59	return NULL;
60}
61
62static void *
63r1(void *arg)
64{
65	char buf[32];
66	int fd;
67
68	fd = rump_sys_open("sheep", O_RDONLY);
69	if (fd == -1)
70		atf_tc_fail_errno("r1 open");
71	if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(teststr1))
72		atf_tc_fail_errno("r1 read");
73	rump_sys_close(fd);
74
75	if (strcmp(teststr1, buf) != 0)
76		atf_tc_fail("got invalid str, %s vs. %s", buf, teststr1);
77
78	return NULL;
79}
80
81static void *
82r2(void *arg)
83{
84	char buf[32];
85	int fd;
86
87	fd = rump_sys_open("pigs", O_RDONLY);
88	if (fd == -1)
89		atf_tc_fail_errno("r2 open");
90	if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(teststr2))
91		atf_tc_fail_errno("r2 read");
92	rump_sys_close(fd);
93
94	if (strcmp(teststr2, buf) != 0)
95		atf_tc_fail("got invalid str, %s vs. %s", buf, teststr2);
96
97	return NULL;
98}
99
100#define IMGNAME "atf.img"
101
102const char *newfs = "newfs -F -s 10000 " IMGNAME;
103#define FAKEBLK "/dev/sp00ka"
104
105ATF_TC_BODY(fifos, tc)
106{
107	struct ufs_args args;
108	pthread_t ptw1, ptw2, ptr1, ptr2;
109
110	if (system(newfs) == -1)
111		atf_tc_fail_errno("newfs failed");
112
113	memset(&args, 0, sizeof(args));
114	args.fspec = __UNCONST(FAKEBLK);
115
116	rump_init();
117	if (rump_sys_mkdir("/animals", 0777) == -1)
118		atf_tc_fail_errno("cannot create mountpoint");
119	rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK);
120	if (rump_sys_mount(MOUNT_FFS, "/animals", 0, &args, sizeof(args))==-1)
121		atf_tc_fail_errno("rump_sys_mount failed");
122
123	/* create fifos */
124	if (rump_sys_chdir("/animals") == 1)
125		atf_tc_fail_errno("chdir");
126	if (rump_sys_mkfifo("pigs", S_IFIFO | 0777) == -1)
127		atf_tc_fail_errno("mknod1");
128	if (rump_sys_mkfifo("sheep", S_IFIFO | 0777) == -1)
129		atf_tc_fail_errno("mknod2");
130
131	pthread_create(&ptw1, NULL, w1, NULL);
132	pthread_create(&ptw2, NULL, w2, NULL);
133	pthread_create(&ptr1, NULL, r1, NULL);
134	pthread_create(&ptr2, NULL, r2, NULL);
135
136	pthread_join(ptw1, NULL);
137	pthread_join(ptw2, NULL);
138	pthread_join(ptr1, NULL);
139	pthread_join(ptr2, NULL);
140
141	if (rump_sys_chdir("/") == 1)
142		atf_tc_fail_errno("chdir");
143
144	if (rump_sys_unmount("/animals", 0) == -1)
145		atf_tc_fail_errno("unmount failed");
146}
147
148ATF_TC_CLEANUP(fifos, tc)
149{
150
151	unlink(IMGNAME);
152}
153
154ATF_TP_ADD_TCS(tp)
155{
156	ATF_TP_ADD_TC(tp, fifos);
157	return 0;
158}
159