root/maint/gnulib/tests/test-spawn-pipe-child.c

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

DEFINITIONS

This source file includes following definitions.
  1. gl_msvc_invalid_parameter_handler
  2. is_open
  3. main

   1 /* Child program invoked by test-spawn-pipe-main.
   2    Copyright (C) 2009-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, or (at your option)
   7    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 <errno.h>
  20 #include <fcntl.h>
  21 #include <stdbool.h>
  22 #include <stdint.h>
  23 #include <stdio.h>
  24 #include <stdlib.h>
  25 #include <string.h>
  26 #include <unistd.h>
  27 
  28 #if defined _WIN32 && ! defined __CYGWIN__
  29 /* Get declarations of the native Windows API functions.  */
  30 # define WIN32_LEAN_AND_MEAN
  31 # include <windows.h>
  32 #endif
  33 
  34 /* Depending on arguments, this test intentionally closes stderr or
  35    starts life with stderr closed.  So, we arrange to have fd 10
  36    (outside the range of interesting fd's during the test) set up to
  37    duplicate the original stderr.  */
  38 
  39 #define BACKUP_STDERR_FILENO 10
  40 #define ASSERT_STREAM myerr
  41 #include "macros.h"
  42 
  43 static FILE *myerr;
  44 
  45 /* In this file, we use only system functions, no overrides from gnulib.  */
  46 #undef atoi
  47 #undef close
  48 #undef fcntl
  49 #undef fdopen
  50 #undef fflush
  51 #undef fprintf
  52 #undef open
  53 #undef read
  54 #undef strcasestr
  55 #undef strstr
  56 #undef write
  57 #if defined _WIN32 && !defined __CYGWIN__
  58 # define fdopen _fdopen
  59 #endif
  60 
  61 #include "qemu.h"
  62 
  63 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  64 static void __cdecl
  65 gl_msvc_invalid_parameter_handler (const wchar_t *expression,
     /* [previous][next][first][last][top][bottom][index][help] */
  66                                    const wchar_t *function,
  67                                    const wchar_t *file,
  68                                    unsigned int line,
  69                                    uintptr_t dummy)
  70 {
  71 }
  72 #endif
  73 
  74 /* Return non-zero if FD is open.  */
  75 static int
  76 is_open (int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78 #if defined _WIN32 && ! defined __CYGWIN__
  79   /* On native Windows, the initial state of unassigned standard file
  80      descriptors is that they are open but point to an
  81      INVALID_HANDLE_VALUE, and there is no fcntl.  */
  82   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
  83 #else
  84 # ifndef F_GETFL
  85 #  error Please port fcntl to your platform
  86 # endif
  87   return 0 <= fcntl (fd, F_GETFL);
  88 #endif
  89 }
  90 
  91 int
  92 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94   /* fd 2 might be closed, but fd BACKUP_STDERR_FILENO is the original
  95      stderr.  */
  96   myerr = fdopen (BACKUP_STDERR_FILENO, "w");
  97   if (!myerr)
  98     return 2;
  99 
 100   ASSERT (argc == 2);
 101 
 102 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
 103   /* Avoid exceptions from within _get_osfhandle.  */
 104   _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler);
 105 #endif
 106 
 107   /* QEMU 6.1 in user-mode passes an open fd, usually = 3, that references
 108      /dev/urandom.  We need to ignore this fd.  */
 109   bool is_qemu = is_running_under_qemu_user ();
 110 
 111   /* Read one byte from fd 0, and write its value plus one to fd 1.
 112      fd 2 should be closed iff the argument is 1.  Check that no other file
 113      descriptors leaked.  */
 114 
 115   char buffer[2] = { 's', 't' };
 116 
 117   ASSERT (read (STDIN_FILENO, buffer, 2) == 1);
 118 
 119   buffer[0]++;
 120   ASSERT (write (STDOUT_FILENO, buffer, 1) == 1);
 121 
 122   switch (atoi (argv[1]))
 123     {
 124     case 0:
 125       /* Expect fd 2 is open.  */
 126       ASSERT (is_open (STDERR_FILENO));
 127       break;
 128     case 1:
 129       /* Expect fd 2 is closed.
 130          But on HP-UX 11, fd 2 gets automatically re-opened to /dev/null if it
 131          was closed.  Similarly on native Windows.  Future POSIX will allow
 132          this, see <http://austingroupbugs.net/view.php?id=173>.  */
 133 #if !(defined __hpux || (defined _WIN32 && ! defined __CYGWIN__))
 134       if (!is_qemu)
 135         ASSERT (! is_open (STDERR_FILENO));
 136 #endif
 137       break;
 138     default:
 139       ASSERT (0);
 140     }
 141 
 142   int fd;
 143   for (fd = 3; fd < 7; fd++)
 144     if (!(is_qemu && fd == 3))
 145       {
 146         errno = 0;
 147         ASSERT (close (fd) == -1);
 148         ASSERT (errno == EBADF);
 149       }
 150 
 151   return 0;
 152 }

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