root/maint/gnulib/tests/test-passfd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   1 /* Test of passing file descriptors.
   2    Copyright (C) 2011-2021 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 <https://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 ()
     /* [previous][next][first][last][top][bottom][index][help] */
  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   int alarm_value = 5;
  49   signal (SIGALRM, SIG_DFL);
  50   alarm (alarm_value);
  51 # endif
  52 
  53   fdnull = open ("/dev/null", O_RDWR);
  54   if (fdnull < 0)
  55     {
  56       perror ("Could not open /dev/null");
  57       return 1;
  58     }
  59 
  60   ret = socketpair (AF_UNIX, SOCK_STREAM, 0, pair);
  61   if (ret < 0)
  62     {
  63       perror ("socket pair failed");
  64       return 2;
  65     }
  66 
  67   pid = fork ();
  68   if (pid == -1)
  69     {
  70       perror ("fork");
  71       return 3;
  72     }
  73   if (pid == 0)
  74     {
  75       ret = sendfd (pair[1], fdnull);
  76       if (ret == -1)
  77         {
  78           perror ("sendfd");
  79           return 64;
  80         }
  81       return 0;
  82     }
  83   /* father */
  84   else
  85     {
  86       ASSERT (close (pair[1]) == 0);
  87       fd = recvfd (pair[0], 0);
  88       if (fd == -1)
  89         {
  90           perror ("recvfd");
  91           return 16;
  92         }
  93       ret = waitpid (pid, &status, 0);
  94       if (ret == -1)
  95         {
  96           perror ("waitpid");
  97           return 17;
  98         }
  99       ASSERT (ret == pid);
 100 
 101       if (!WIFEXITED (status))
 102         {
 103           fprintf (stderr, "Child does not normally exit\n");
 104           return 65;
 105         }
 106       ret = WEXITSTATUS (status);
 107       if (ret != 0)
 108         {
 109           fprintf (stderr, "Send fd fail\n");
 110           return ret;
 111         }
 112 
 113       /* try to stat new fd */
 114       ret = fstat (fd, &st);
 115       if (ret < 0)
 116         {
 117           perror ("fstat");
 118           return 80;
 119         }
 120 
 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);
 126 
 127       return 0;
 128     }
 129 #else
 130   errno = 0;
 131   ASSERT(sendfd (0, 0) == -1);
 132   ASSERT(errno == ENOSYS);
 133 
 134   errno = 0;
 135   ASSERT(recvfd (0, 0) == -1);
 136   ASSERT(errno == ENOSYS);
 137 
 138   fputs ("skipping test: socketpair not supported on this system\n",
 139          stderr);
 140   return 77;
 141 #endif
 142 }

/* [previous][next][first][last][top][bottom][index][help] */