Add test case from a recent glibc bug.
[gnulib.git] / tests / test-passfd.c
blob0e40a6508019236d6cdffa1236a3f88fa9d84da2
1 /* Test of passing file descriptors.
2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include "passfd.h"
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/stat.h>
30 #include <sys/wait.h>
32 #include "macros.h"
34 int
35 main ()
37 #if HAVE_SOCKETPAIR
38 int pair[2];
39 int ret;
40 pid_t pid;
41 int status;
42 int fdnull;
43 int fd;
44 struct stat st;
46 # if HAVE_DECL_ALARM
47 /* Avoid hanging on failure. */
48 int alarm_value = 5;
49 signal (SIGALRM, SIG_DFL);
50 alarm (alarm_value);
51 # endif
53 fdnull = open ("/dev/null", O_RDWR);
54 if (fdnull < 0)
56 perror ("Could not open /dev/null");
57 return 1;
60 ret = socketpair (AF_UNIX, SOCK_STREAM, 0, pair);
61 if (ret < 0)
63 perror ("socket pair failed");
64 return 2;
67 pid = fork ();
68 if (pid == -1)
70 perror ("fork");
71 return 3;
73 if (pid == 0)
75 ret = sendfd (pair[1], fdnull);
76 if (ret == -1)
78 perror ("sendfd");
79 return 64;
81 return 0;
83 /* father */
84 else
86 ASSERT (close (pair[1]) == 0);
87 fd = recvfd (pair[0], 0);
88 if (fd == -1)
90 perror ("recvfd");
91 return 16;
93 ret = waitpid (pid, &status, 0);
94 if (ret == -1)
96 perror ("waitpid");
97 return 17;
99 ASSERT (ret == pid);
101 if (!WIFEXITED (status))
103 fprintf (stderr, "Child does not normally exit\n");
104 return 65;
106 ret = WEXITSTATUS (status);
107 if (ret != 0)
109 fprintf (stderr, "Send fd fail\n");
110 return ret;
113 /* try to stat new fd */
114 ret = fstat (fd, &st);
115 if (ret < 0)
117 perror ("fstat");
118 return 80;
121 /* Check behavior when sender no longer around */
122 errno = 0;
123 fd = recvfd (pair[0], 0);
124 ASSERT (fd == -1);
125 ASSERT (errno == ENOTCONN);
127 return 0;
129 #else
130 errno = 0;
131 ASSERT(sendfd (0, 0) == -1);
132 ASSERT(errno == ENOSYS);
134 errno = 0;
135 ASSERT(recvfd (0, 0) == -1);
136 ASSERT(errno == ENOSYS);
138 fputs ("skipping test: socketpair not supported on this system\n",
139 stderr);
140 return 77;
141 #endif