c11a82859fdb0d1b159c1cbe8bc87c58c1e4a450
[gnulib.git] / tests / test-passfd.c
1 /* Test of passing file descriptors.
2    Copyright (C) 2011-2013 Free Software Foundation, Inc.
3
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.
8
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.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 #include <config.h>
18
19 #include "passfd.h"
20
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>
31
32 #include "macros.h"
33
34 int
35 main ()
36 {
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;
45
46 # if HAVE_DECL_ALARM
47   /* Avoid hanging on failure.  */
48   signal (SIGALRM, SIG_DFL);
49   alarm (5);
50 # endif
51
52   fdnull = open ("/dev/null", O_RDWR);
53   if (fdnull < 0)
54     {
55       perror ("Could not open /dev/null");
56       return 1;
57     }
58
59   ret = socketpair (AF_UNIX, SOCK_STREAM, 0, pair);
60   if (ret < 0)
61     {
62       perror ("socket pair failed");
63       return 2;
64     }
65
66   pid = fork ();
67   if (pid == -1)
68     {
69       perror ("fork");
70       return 3;
71     }
72   if (pid == 0)
73     {
74       ret = sendfd (pair[1], fdnull);
75       if (ret == -1)
76         {
77           perror ("sendfd");
78           return 64;
79         }
80       return 0;
81     }
82   /* father */
83   else
84     {
85       fd = recvfd (pair[0], 0);
86       if (fd == -1)
87         {
88           perror ("recvfd");
89           return 16;
90         }
91       ret = waitpid (pid, &status, 0);
92       if (ret == -1)
93         {
94           perror ("waitpid");
95           return 17;
96         }
97       ASSERT (ret == pid);
98
99       if (!WIFEXITED (status))
100         {
101           fprintf (stderr, "Child does not normally exit\n");
102           return 65;
103         }
104       ret = WEXITSTATUS (status);
105       if (ret != 0)
106         {
107           fprintf (stderr, "Send fd fail\n");
108           return ret;
109         }
110
111       /* try to stat new fd */
112       ret = fstat (fd, &st);
113       if (ret < 0)
114         {
115           perror ("fstat");
116           return 80;
117         }
118       return 0;
119     }
120 #else
121   errno = 0;
122   ASSERT(sendfd (0, 0) == -1);
123   ASSERT(errno == ENOSYS);
124
125   errno = 0;
126   ASSERT(recvfd (0, 0) == -1);
127   ASSERT(errno == ENOSYS);
128
129   fputs ("skipping test: socketpair not supported on this system\n",
130          stderr);
131   return 77;
132 #endif
133 }