1 /*	$OpenBSD: sigio_socket.c,v 1.1 2020/09/16 14:02:23 mpi Exp $	*/
2 
3 /*
4  * Copyright (c) 2018 Visa Hankala
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <netinet/tcp.h>
22 #include <assert.h>
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include "common.h"
29 
30 int
test_socket_badpgid(void)31 test_socket_badpgid(void)
32 {
33 	int fds[2];
34 
35 	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
36 	return test_common_badpgid(fds[0]);
37 }
38 
39 int
test_socket_badsession(void)40 test_socket_badsession(void)
41 {
42 	int fds[2];
43 
44 	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
45 	return test_common_badsession(fds[0]);
46 }
47 
48 int
test_socket_cansigio(void)49 test_socket_cansigio(void)
50 {
51 	int fds[2];
52 
53 	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
54 	return test_common_cansigio(fds);
55 }
56 
57 int
test_socket_getown(void)58 test_socket_getown(void)
59 {
60 	int fds[2];
61 
62 	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
63 	return test_common_getown(fds[0]);
64 }
65 
66 /*
67  * Test that the parent socket's signal target gets assigned to the socket
68  * of an accepted connection.
69  */
70 int
test_socket_inherit(void)71 test_socket_inherit(void)
72 {
73 	struct sockaddr_in inaddr;
74 	socklen_t inaddrlen;
75 	pid_t pid;
76 	int cli, flags, sfd, sock;
77 
78 	sock = socket(AF_INET, SOCK_STREAM, 0);
79 	assert(sock != -1);
80 
81 	memset(&inaddr, 0, sizeof(inaddr));
82 	inaddr.sin_len = sizeof(inaddr);
83 	inaddr.sin_family = AF_INET;
84 	inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
85 	assert(bind(sock, (struct sockaddr *)&inaddr, sizeof(inaddr)) == 0);
86 	assert(listen(sock, 1) == 0);
87 
88 	flags = fcntl(sock, F_GETFL);
89 	assert(fcntl(sock, F_SETFL, flags | O_ASYNC) == 0);
90 
91 	if (test_fork(&pid, &sfd) == PARENT) {
92 		inaddrlen = sizeof(inaddr);
93 		cli = accept(sock, (struct sockaddr *)&inaddr, &inaddrlen);
94 		assert(cli != -1);
95 		assert(fcntl(cli, F_GETOWN) == 0);
96 		close(cli);
97 
98 		assert(fcntl(sock, F_SETOWN, getpid()) == 0);
99 		test_barrier(sfd);
100 
101 		inaddrlen = sizeof(inaddr);
102 		cli = accept(sock, (struct sockaddr *)&inaddr, &inaddrlen);
103 		assert(cli != -1);
104 		assert(fcntl(cli, F_GETOWN) == getpid());
105 		close(cli);
106 	} else {
107 		inaddrlen = sizeof(inaddr);
108 		assert(getsockname(sock, (struct sockaddr *)&inaddr,
109 		    &inaddrlen) == 0);
110 
111 		cli = socket(AF_INET, SOCK_STREAM, 0);
112 		assert(cli != -1);
113 		assert(connect(cli, (struct sockaddr *)&inaddr, sizeof(inaddr))
114 		    == 0);
115 		close(cli);
116 
117 		test_barrier(sfd);
118 
119 		cli = socket(AF_INET, SOCK_STREAM, 0);
120 		assert(cli != -1);
121 		assert(connect(cli, (struct sockaddr *)&inaddr, sizeof(inaddr))
122 		    == 0);
123 		close(cli);
124 	}
125 	return test_wait(pid, sfd);
126 }
127 
128 int
test_socket_read(void)129 test_socket_read(void)
130 {
131 	int fds[2];
132 
133 	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
134 	return test_common_read(fds);
135 }
136 
137 int
test_socket_write(void)138 test_socket_write(void)
139 {
140 	int fds[2];
141 
142 	assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
143 	return test_common_write(fds);
144 }
145