1311966Sngie/*	$NetBSD: msg.h,v 1.1 2016/12/05 20:10:10 christos Exp $	*/
2311966Sngie
3311966Sngie/*-
4311966Sngie * Copyright (c) 2016 The NetBSD Foundation, Inc.
5311966Sngie * All rights reserved.
6311966Sngie *
7311966Sngie * This code is derived from software contributed to The NetBSD Foundation
8311966Sngie * by Christos Zoulas.
9311966Sngie *
10311966Sngie * Redistribution and use in source and binary forms, with or without
11311966Sngie * modification, are permitted provided that the following conditions
12311966Sngie * are met:
13311966Sngie * 1. Redistributions of source code must retain the above copyright
14311966Sngie *    notice, this list of conditions and the following disclaimer.
15311966Sngie * 2. Redistributions in binary form must reproduce the above copyright
16311966Sngie *    notice, this list of conditions and the following disclaimer in the
17311966Sngie *    documentation and/or other materials provided with the distribution.
18311966Sngie *
19311966Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20311966Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21311966Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22311966Sngie * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23311966Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24311966Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25311966Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26311966Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27311966Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28311966Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29311966Sngie * POSSIBILITY OF SUCH DAMAGE.
30311966Sngie */
31311966Sngie
32311966Sngiestruct msg_fds {
33311966Sngie	int pfd[2];
34311966Sngie	int cfd[2];
35311966Sngie};
36311966Sngie
37311966Sngie#define CLOSEFD(fd) do { \
38311966Sngie	if (fd != -1) { \
39311966Sngie		close(fd); \
40311966Sngie		fd = -1; \
41311966Sngie	} \
42311966Sngie} while (/*CONSTCOND*/ 0)
43311966Sngie
44311966Sngiestatic int
45311966Sngiemsg_open(struct msg_fds *fds)
46311966Sngie{
47311966Sngie	if (pipe(fds->pfd) == -1)
48311966Sngie		return -1;
49311966Sngie	if (pipe(fds->cfd) == -1) {
50311966Sngie		close(fds->pfd[0]);
51311966Sngie		close(fds->pfd[1]);
52311966Sngie		return -1;
53311966Sngie	}
54311966Sngie	return 0;
55311966Sngie}
56311966Sngie
57311966Sngiestatic void
58311966Sngiemsg_close(struct msg_fds *fds)
59311966Sngie{
60311966Sngie	CLOSEFD(fds->pfd[0]);
61311966Sngie	CLOSEFD(fds->pfd[1]);
62311966Sngie	CLOSEFD(fds->cfd[0]);
63311966Sngie	CLOSEFD(fds->cfd[1]);
64311966Sngie}
65311966Sngie
66311966Sngiestatic int
67311966Sngiemsg_write_child(const char *info, struct msg_fds *fds, void *msg, size_t len)
68311966Sngie{
69311966Sngie	ssize_t rv;
70311966Sngie	CLOSEFD(fds->cfd[1]);
71311966Sngie	CLOSEFD(fds->pfd[0]);
72311966Sngie
73311966Sngie	printf("Send %s\n", info);
74311966Sngie	rv = write(fds->pfd[1], msg, len);
75311966Sngie	if (rv != (ssize_t)len)
76311966Sngie		return 1;
77311966Sngie//	printf("Wait %s\n", info);
78311966Sngie	rv = read(fds->cfd[0], msg, len);
79311966Sngie	if (rv != (ssize_t)len)
80311966Sngie		return 1;
81311966Sngie	return 0;
82311966Sngie}
83311966Sngie
84311966Sngiestatic int
85311966Sngiemsg_write_parent(const char *info, struct msg_fds *fds, void *msg, size_t len)
86311966Sngie{
87311966Sngie	ssize_t rv;
88311966Sngie	CLOSEFD(fds->pfd[1]);
89311966Sngie	CLOSEFD(fds->cfd[0]);
90311966Sngie
91311966Sngie	printf("Send %s\n", info);
92311966Sngie	rv = write(fds->cfd[1], msg, len);
93311966Sngie	if (rv != (ssize_t)len)
94311966Sngie		return 1;
95311966Sngie//	printf("Wait %s\n", info);
96311966Sngie	rv = read(fds->pfd[0], msg, len);
97311966Sngie	if (rv != (ssize_t)len)
98311966Sngie		return 1;
99311966Sngie	return 0;
100311966Sngie}
101311966Sngie
102311966Sngiestatic int
103311966Sngiemsg_read_parent(const char *info, struct msg_fds *fds, void *msg, size_t len)
104311966Sngie{
105311966Sngie	ssize_t rv;
106311966Sngie	CLOSEFD(fds->pfd[1]);
107311966Sngie	CLOSEFD(fds->cfd[0]);
108311966Sngie
109311966Sngie	printf("Wait %s\n", info);
110311966Sngie	rv = read(fds->pfd[0], msg, len);
111311966Sngie	if (rv != (ssize_t)len)
112311966Sngie		return 1;
113311966Sngie//	printf("Send %s\n", info);
114311966Sngie	rv = write(fds->cfd[1], msg, len);
115311966Sngie	if (rv != (ssize_t)len)
116311966Sngie		return 1;
117311966Sngie	return 0;
118311966Sngie}
119311966Sngie
120311966Sngiestatic int
121311966Sngiemsg_read_child(const char *info, struct msg_fds *fds, void *msg, size_t len)
122311966Sngie{
123311966Sngie	ssize_t rv;
124311966Sngie	CLOSEFD(fds->cfd[1]);
125311966Sngie	CLOSEFD(fds->pfd[0]);
126311966Sngie
127311966Sngie	printf("Wait %s\n", info);
128311966Sngie	rv = read(fds->cfd[0], msg, len);
129311966Sngie	if (rv != (ssize_t)len)
130311966Sngie		return 1;
131311966Sngie//	printf("Send %s\n", info);
132311966Sngie	rv = write(fds->pfd[1], msg, len);
133311966Sngie	if (rv != (ssize_t)len)
134311966Sngie		return 1;
135311966Sngie	return 0;
136311966Sngie}
137