root/maint/gnulib/tests/test-execute-child.c

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

DEFINITIONS

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

   1 /* Child program invoked by test-execute-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 /* If the user's config.h happens to include <sys/stat.h>, let it include only
  18    the system's <sys/stat.h> here.  */
  19 #define __need_system_sys_stat_h
  20 #include <config.h>
  21 
  22 /* Get the original definition of fstat.  It might be defined as a macro.
  23    Also, 'stat' might be defined as a macro.  */
  24 #include <sys/types.h>
  25 #include <sys/stat.h>
  26 #undef __need_system_sys_stat_h
  27 
  28 /* Return non-zero if FD is opened to a device.  */
  29 static int
  30 is_device (int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32 #if defined _WIN32 && ! defined __CYGWIN__
  33   struct _stat st;
  34   return _fstat (fd, &st) >= 0 && !((st.st_mode & S_IFMT) == S_IFREG);
  35 #else
  36   struct stat st;
  37   return fstat (fd, &st) >= 0 && !S_ISREG (st.st_mode);
  38 #endif
  39 }
  40 
  41 /* Now include the other header files.  */
  42 #include <fcntl.h>
  43 #include <signal.h>
  44 #include <stdbool.h>
  45 #include <stdint.h>
  46 #include <stdio.h>
  47 #include <stdlib.h>
  48 #include <string.h>
  49 #include <unistd.h>
  50 
  51 #if defined _WIN32 && ! defined __CYGWIN__
  52 /* Get declarations of the native Windows API functions.  */
  53 # define WIN32_LEAN_AND_MEAN
  54 # include <windows.h>
  55 /* Get _get_osfhandle, _isatty, _chdir, _getcwd.  */
  56 # include <io.h>
  57 #endif
  58 
  59 /* In this file, we use only system functions, no overrides from gnulib.  */
  60 #undef atoi
  61 #undef close
  62 #undef fcntl
  63 #undef fflush
  64 #undef fgetc
  65 #undef fprintf
  66 #undef fputs
  67 #undef getcwd
  68 #undef isatty
  69 #undef open
  70 #undef raise
  71 #undef read
  72 #undef sprintf
  73 #undef strcasestr
  74 #undef strcmp
  75 #undef strlen
  76 #undef strstr
  77 #undef write
  78 
  79 #include "qemu.h"
  80 
  81 #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
  82 static void __cdecl
  83 gl_msvc_invalid_parameter_handler (const wchar_t *expression,
     /* [previous][next][first][last][top][bottom][index][help] */
  84                                    const wchar_t *function,
  85                                    const wchar_t *file,
  86                                    unsigned int line,
  87                                    uintptr_t dummy)
  88 {
  89 }
  90 #endif
  91 
  92 /* Return non-zero if FD is open.  */
  93 static int
  94 is_open (int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96 #if defined _WIN32 && ! defined __CYGWIN__
  97   /* On native Windows, the initial state of unassigned standard file
  98      descriptors is that they are open but point to an
  99      INVALID_HANDLE_VALUE, and there is no fcntl.  */
 100   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
 101 #else
 102 # ifndef F_GETFL
 103 #  error Please port fcntl to your platform
 104 # endif
 105   return 0 <= fcntl (fd, F_GETFL);
 106 #endif
 107 }
 108 
 109 int
 110 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112   if (argc == 1)
 113     /* Check an invocation without arguments.  Check the exit code.  */
 114     return 40;
 115 
 116   int test = atoi (argv[1]);
 117   switch (test)
 118     {
 119     case 2:
 120       /* Check argument passing.  */
 121       return !(argc == 12
 122                && strcmp (argv[2], "abc def") == 0
 123                && strcmp (argv[3], "abc\"def\"ghi") == 0
 124                && strcmp (argv[4], "xyz\"") == 0
 125                && strcmp (argv[5], "abc\\def\\ghi") == 0
 126                && strcmp (argv[6], "xyz\\") == 0
 127                && strcmp (argv[7], "???") == 0
 128                && strcmp (argv[8], "***") == 0
 129                && strcmp (argv[9], "") == 0
 130                && strcmp (argv[10], "foo") == 0
 131                && strcmp (argv[11], "") == 0);
 132     #if !(defined _WIN32 && !defined __CYGWIN__)
 133     case 3:
 134       /* Check SIGPIPE handling with ignore_sigpipe = false.  */
 135     case 4:
 136       /* Check SIGPIPE handling with ignore_sigpipe = true.  */
 137       raise (SIGPIPE);
 138       return 71;
 139     #endif
 140     case 5:
 141       /* Check other signal.  */
 142       raise (SIGINT);
 143       return 71;
 144     case 6:
 145       /* Check stdin is inherited.  */
 146       return !(fgetc (stdin) == 'F' && fgetc (stdin) == 'o');
 147     case 7:
 148       /* Check null_stdin = true.  */
 149       return !(fgetc (stdin) == EOF);
 150     case 8:
 151       /* Check stdout is inherited, part 1 (regular file).  */
 152       return !(fputs ("bar", stdout) != EOF && fflush (stdout) == 0);
 153     case 9:
 154       /* Check stdout is inherited, part 2 (device).  */
 155     case 10:
 156       /* Check null_stdout = true.  */
 157       return !is_device (STDOUT_FILENO);
 158     case 11:
 159       /* Check stderr is inherited, part 1 (regular file).  */
 160       return !(fputs ("bar", stderr) != EOF && fflush (stderr) == 0);
 161     case 12:
 162       /* Check stderr is inherited, part 2 (device).  */
 163     case 13:
 164       /* Check null_stderr = true.  */
 165       return !is_device (STDERR_FILENO);
 166     case 14:
 167     case 15:
 168       /* Check file descriptors >= 3 can be inherited.  */
 169     case 16:
 170       /* Check file descriptors >= 3 with O_CLOEXEC bit are not inherited.  */
 171       #if HAVE_MSVC_INVALID_PARAMETER_HANDLER
 172       /* Avoid exceptions from within _get_osfhandle.  */
 173       _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler);
 174       #endif
 175       {
 176         /* QEMU 6.1 in user-mode passes an open fd = 3, that references
 177            /dev/urandom.  We need to ignore this fd.  */
 178         bool is_qemu = is_running_under_qemu_user ();
 179         char buf[300];
 180         buf[0] = '\0';
 181         char *p = buf;
 182         int fd;
 183         for (fd = 0; fd < 20; fd++)
 184           if (is_open (fd) && !(is_qemu && fd == 3))
 185             {
 186               sprintf (p, "%d ", fd);
 187               p += strlen (p);
 188             }
 189         const char *expected = (test < 16 ? "0 1 2 10 " : "0 1 2 ");
 190         if (strcmp (buf, expected) == 0)
 191           return 0;
 192         else
 193           {
 194             fprintf (stderr, "Test case %d: %s\n", test, buf); fflush (stderr);
 195             return 1;
 196           }
 197       }
 198     case 17:
 199       /* Check that file descriptors >= 3, open for reading, can be inherited,
 200          including the file position.  */
 201       {
 202         char buf[6];
 203         int n = read (10, buf, sizeof (buf));
 204         return !(n == 4 && memcmp (buf, "obar", 4) == 0);
 205       }
 206     case 18:
 207       /* Check that file descriptors >= 3, open for writing, can be inherited,
 208          including the file position.  */
 209       {
 210         int n = write (10, "bar", 3);
 211         return !(n == 3);
 212       }
 213     case 19:
 214       /* Check that file descriptors >= 3, when inherited, preserve their
 215          isatty() property, part 1 (regular file).  */
 216     case 20:
 217       /* Check that file descriptors >= 3, when inherited, preserve their
 218          isatty() property, part 2 (character devices).  */
 219       {
 220         #if defined _WIN32 && ! defined __CYGWIN__
 221         return 4 + 2 * (_isatty (10) != 0) + (_isatty (11) != 0);
 222         #else
 223         return 4 + 2 * (isatty (10) != 0) + (isatty (11) != 0);
 224         #endif
 225       }
 226     case 21:
 227       /* Check execution in a different directory.  */
 228       {
 229         char cwd[1024];
 230         #if defined _WIN32 && ! defined __CYGWIN__
 231         if (_chdir ("..") != 0)
 232           return 1;
 233         if (_getcwd (cwd, sizeof (cwd)) == NULL)
 234           return 2;
 235         #else
 236         if (chdir ("..") != 0)
 237           return 1;
 238         if (getcwd (cwd, sizeof (cwd)) == NULL)
 239           return 2;
 240         #endif
 241         return (argc == 3 && strcmp (argv[2], cwd) == 0 ? 0 : 3);
 242       }
 243     default:
 244       abort ();
 245     }
 246 }

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