1 /*
2 * Copyright (c) 2013-2016 Dmitry V. Levin <ldv@strace.io>
3 * Copyright (c) 2013-2021 The strace developers.
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "tests.h"
10 #include <assert.h>
11 #include <stddef.h>
12 #include <string.h>
13 #include <signal.h>
14 #include <unistd.h>
15 #include <sys/wait.h>
16 #include <sys/socket.h>
17 #include <sys/un.h>
18
19 static void
20 handler(int sig)
21 {
22 assert(close(1) == 0);
23 _exit(0);
24 }
25
26 int
27 main(int ac, const char **av)
28 {
29 struct sockaddr_un addr = {
30 .sun_family = AF_UNIX,
31 };
32
33 assert(ac == 2);
34 socklen_t len = strlen(av[1]);
35 assert(len > 0 && len <= sizeof(addr.sun_path));
36
37 if (++len > sizeof(addr.sun_path))
38 len = sizeof(addr.sun_path);
39
40 memcpy(addr.sun_path, av[1], len);
41 len += offsetof(struct sockaddr_un, sun_path);
42
43 unlink(av[1]);
44 close(0);
45 close(1);
46
47 if (socket(AF_UNIX, SOCK_STREAM, 0))
48 perror_msg_and_skip("socket");
49 if (bind(0, (struct sockaddr *) &addr, len))
50 perror_msg_and_skip("bind");
51 if (listen(0, 5))
52 perror_msg_and_skip("listen");
53
54 memset(&addr, 0, sizeof(addr));
55 assert(getsockname(0, (struct sockaddr *) &addr, &len) == 0);
56 if (len > sizeof(addr))
57 len = sizeof(addr);
58
59 pid_t pid = fork();
60 if (pid < 0)
61 perror_msg_and_fail("fork");
62
63 if (pid) {
64 assert(accept(0, (struct sockaddr *) &addr, &len) == 1);
65 assert(close(0) == 0);
66 assert(kill(pid, SIGUSR1) == 0);
67 int status;
68 assert(waitpid(pid, &status, 0) == pid);
69 assert(status == 0);
70 assert(close(1) == 0);
71 } else {
72 sigset_t set;
73 sigemptyset(&set);
74 sigaddset(&set, SIGUSR1);
75
76 assert(sigprocmask(SIG_BLOCK, &set, NULL) == 0);
77 assert(signal(SIGUSR1, handler) != SIG_ERR);
78 assert(socket(AF_UNIX, SOCK_STREAM, 0) == 1);
79 assert(close(0) == 0);
80 assert(connect(1, (struct sockaddr *) &addr, len) == 0);
81 assert(sigprocmask(SIG_UNBLOCK, &set, NULL) == 0);
82 assert(pause() == 99);
83 return 1;
84 }
85
86 unlink(av[1]);
87 return 0;
88 }