xref: /netbsd-src/tests/lib/libc/sys/msg.h (revision efc93621854937223ed99328dcb1a3804171147e)
1*efc93621Skamil /*	$NetBSD: msg.h,v 1.3 2020/03/06 14:06:56 kamil Exp $	*/
224e714f4Skamil 
324e714f4Skamil /*-
424e714f4Skamil  * Copyright (c) 2016 The NetBSD Foundation, Inc.
524e714f4Skamil  * All rights reserved.
624e714f4Skamil  *
724e714f4Skamil  * This code is derived from software contributed to The NetBSD Foundation
824e714f4Skamil  * by Christos Zoulas.
924e714f4Skamil  *
1024e714f4Skamil  * Redistribution and use in source and binary forms, with or without
1124e714f4Skamil  * modification, are permitted provided that the following conditions
1224e714f4Skamil  * are met:
1324e714f4Skamil  * 1. Redistributions of source code must retain the above copyright
1424e714f4Skamil  *    notice, this list of conditions and the following disclaimer.
1524e714f4Skamil  * 2. Redistributions in binary form must reproduce the above copyright
1624e714f4Skamil  *    notice, this list of conditions and the following disclaimer in the
1724e714f4Skamil  *    documentation and/or other materials provided with the distribution.
1824e714f4Skamil  *
1924e714f4Skamil  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2024e714f4Skamil  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2124e714f4Skamil  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2224e714f4Skamil  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2324e714f4Skamil  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2424e714f4Skamil  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2524e714f4Skamil  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2624e714f4Skamil  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2724e714f4Skamil  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2824e714f4Skamil  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2924e714f4Skamil  * POSSIBILITY OF SUCH DAMAGE.
3024e714f4Skamil  */
3124e714f4Skamil 
3224e714f4Skamil struct msg_fds {
3324e714f4Skamil 	int pfd[2];
3424e714f4Skamil 	int cfd[2];
3524e714f4Skamil };
3624e714f4Skamil 
3724e714f4Skamil #define CLOSEFD(fd) do { \
3824e714f4Skamil 	if (fd != -1) { \
3924e714f4Skamil 		close(fd); \
4024e714f4Skamil 		fd = -1; \
4124e714f4Skamil 	} \
4224e714f4Skamil } while (/*CONSTCOND*/ 0)
4324e714f4Skamil 
44*efc93621Skamil static int __used
msg_open(struct msg_fds * fds)4524e714f4Skamil msg_open(struct msg_fds *fds)
4624e714f4Skamil {
4724e714f4Skamil 	if (pipe(fds->pfd) == -1)
4824e714f4Skamil 		return -1;
4924e714f4Skamil 	if (pipe(fds->cfd) == -1) {
5024e714f4Skamil 		close(fds->pfd[0]);
5124e714f4Skamil 		close(fds->pfd[1]);
5224e714f4Skamil 		return -1;
5324e714f4Skamil 	}
5424e714f4Skamil 	return 0;
5524e714f4Skamil }
5624e714f4Skamil 
57*efc93621Skamil static void __used
msg_close(struct msg_fds * fds)5824e714f4Skamil msg_close(struct msg_fds *fds)
5924e714f4Skamil {
6024e714f4Skamil 	CLOSEFD(fds->pfd[0]);
6124e714f4Skamil 	CLOSEFD(fds->pfd[1]);
6224e714f4Skamil 	CLOSEFD(fds->cfd[0]);
6324e714f4Skamil 	CLOSEFD(fds->cfd[1]);
6424e714f4Skamil }
6524e714f4Skamil 
66*efc93621Skamil static int __used
msg_write_child(const char * info,struct msg_fds * fds,void * msg,size_t len)6724e714f4Skamil msg_write_child(const char *info, struct msg_fds *fds, void *msg, size_t len)
6824e714f4Skamil {
6924e714f4Skamil 	ssize_t rv;
7024e714f4Skamil 	CLOSEFD(fds->cfd[1]);
7124e714f4Skamil 	CLOSEFD(fds->pfd[0]);
7224e714f4Skamil 
73c6513ba7Skamil //	printf("Send %s\n", info);
7424e714f4Skamil 	rv = write(fds->pfd[1], msg, len);
7524e714f4Skamil 	if (rv != (ssize_t)len)
7624e714f4Skamil 		return 1;
7724e714f4Skamil //	printf("Wait %s\n", info);
7824e714f4Skamil 	rv = read(fds->cfd[0], msg, len);
7924e714f4Skamil 	if (rv != (ssize_t)len)
8024e714f4Skamil 		return 1;
8124e714f4Skamil 	return 0;
8224e714f4Skamil }
8324e714f4Skamil 
84*efc93621Skamil static int __used
msg_write_parent(const char * info,struct msg_fds * fds,void * msg,size_t len)8524e714f4Skamil msg_write_parent(const char *info, struct msg_fds *fds, void *msg, size_t len)
8624e714f4Skamil {
8724e714f4Skamil 	ssize_t rv;
8824e714f4Skamil 	CLOSEFD(fds->pfd[1]);
8924e714f4Skamil 	CLOSEFD(fds->cfd[0]);
9024e714f4Skamil 
91c6513ba7Skamil //	printf("Send %s\n", info);
9224e714f4Skamil 	rv = write(fds->cfd[1], msg, len);
9324e714f4Skamil 	if (rv != (ssize_t)len)
9424e714f4Skamil 		return 1;
9524e714f4Skamil //	printf("Wait %s\n", info);
9624e714f4Skamil 	rv = read(fds->pfd[0], msg, len);
9724e714f4Skamil 	if (rv != (ssize_t)len)
9824e714f4Skamil 		return 1;
9924e714f4Skamil 	return 0;
10024e714f4Skamil }
10124e714f4Skamil 
102*efc93621Skamil static int __used
msg_read_parent(const char * info,struct msg_fds * fds,void * msg,size_t len)10324e714f4Skamil msg_read_parent(const char *info, struct msg_fds *fds, void *msg, size_t len)
10424e714f4Skamil {
10524e714f4Skamil 	ssize_t rv;
10624e714f4Skamil 	CLOSEFD(fds->pfd[1]);
10724e714f4Skamil 	CLOSEFD(fds->cfd[0]);
10824e714f4Skamil 
109c6513ba7Skamil //	printf("Wait %s\n", info);
11024e714f4Skamil 	rv = read(fds->pfd[0], msg, len);
11124e714f4Skamil 	if (rv != (ssize_t)len)
11224e714f4Skamil 		return 1;
11324e714f4Skamil //	printf("Send %s\n", info);
11424e714f4Skamil 	rv = write(fds->cfd[1], msg, len);
11524e714f4Skamil 	if (rv != (ssize_t)len)
11624e714f4Skamil 		return 1;
11724e714f4Skamil 	return 0;
11824e714f4Skamil }
11924e714f4Skamil 
120*efc93621Skamil static int __used
msg_read_child(const char * info,struct msg_fds * fds,void * msg,size_t len)12124e714f4Skamil msg_read_child(const char *info, struct msg_fds *fds, void *msg, size_t len)
12224e714f4Skamil {
12324e714f4Skamil 	ssize_t rv;
12424e714f4Skamil 	CLOSEFD(fds->cfd[1]);
12524e714f4Skamil 	CLOSEFD(fds->pfd[0]);
12624e714f4Skamil 
127c6513ba7Skamil //	printf("Wait %s\n", info);
12824e714f4Skamil 	rv = read(fds->cfd[0], msg, len);
12924e714f4Skamil 	if (rv != (ssize_t)len)
13024e714f4Skamil 		return 1;
13124e714f4Skamil //	printf("Send %s\n", info);
13224e714f4Skamil 	rv = write(fds->pfd[1], msg, len);
13324e714f4Skamil 	if (rv != (ssize_t)len)
13424e714f4Skamil 		return 1;
13524e714f4Skamil 	return 0;
13624e714f4Skamil }
137*efc93621Skamil 
138*efc93621Skamil #define PARENT_TO_CHILD(info, fds, msg) \
139*efc93621Skamil     SYSCALL_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, \
140*efc93621Skamil 	sizeof(msg)) == 0)
141*efc93621Skamil 
142*efc93621Skamil #define CHILD_FROM_PARENT(info, fds, msg) \
143*efc93621Skamil     FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, \
144*efc93621Skamil 	sizeof(msg)) == 0)
145*efc93621Skamil 
146*efc93621Skamil #define CHILD_TO_PARENT(info, fds, msg) \
147*efc93621Skamil     FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, \
148*efc93621Skamil 	sizeof(msg)) == 0)
149*efc93621Skamil 
150*efc93621Skamil #define PARENT_FROM_CHILD(info, fds, msg) \
151*efc93621Skamil     SYSCALL_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, \
152*efc93621Skamil 	sizeof(msg)) == 0)
153