wctype-h: Fix last change.
[gnulib.git] / tests / test-spawn-pipe-child.c
1 /* Child program invoked by test-spawn-pipe-main.
2    Copyright (C) 2009-2011 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, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 #include <config.h>
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25
26 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
27 /* Get declarations of the Win32 API functions.  */
28 # define WIN32_LEAN_AND_MEAN
29 # include <windows.h>
30 #endif
31
32 /* Depending on arguments, this test intentionally closes stderr or
33    starts life with stderr closed.  So, we arrange to have fd 10
34    (outside the range of interesting fd's during the test) set up to
35    duplicate the original stderr.  */
36
37 #define BACKUP_STDERR_FILENO 10
38 #define ASSERT_STREAM myerr
39 #include "macros.h"
40
41 static FILE *myerr;
42
43 /* In this file, we use only system functions, no overrides from gnulib.  */
44 #undef atoi
45 #undef close
46 #undef fcntl
47 #undef fdopen
48 #undef fflush
49 #undef fprintf
50 #undef read
51 #undef write
52
53 /* Return non-zero if FD is open.  */
54 static int
55 is_open (int fd)
56 {
57 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
58   /* On Win32, the initial state of unassigned standard file
59      descriptors is that they are open but point to an
60      INVALID_HANDLE_VALUE, and there is no fcntl.  */
61   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
62 #else
63 # ifndef F_GETFL
64 #  error Please port fcntl to your platform
65 # endif
66   return 0 <= fcntl (fd, F_GETFL);
67 #endif
68 }
69
70 int
71 main (int argc, char *argv[])
72 {
73   char buffer[2] = { 's', 't' };
74   int fd;
75
76   /* fd 2 might be closed, but fd BACKUP_STDERR_FILENO is the original
77      stderr.  */
78   myerr = fdopen (BACKUP_STDERR_FILENO, "w");
79   if (!myerr)
80     return 2;
81
82   ASSERT (argc == 2);
83
84   /* Read one byte from fd 0, and write its value plus one to fd 1.
85      fd 2 should be closed iff the argument is 1.  Check that no other file
86      descriptors leaked.  */
87
88   ASSERT (read (STDIN_FILENO, buffer, 2) == 1);
89
90   buffer[0]++;
91   ASSERT (write (STDOUT_FILENO, buffer, 1) == 1);
92
93   switch (atoi (argv[1]))
94     {
95     case 0:
96       /* Expect fd 2 is open.  */
97       ASSERT (is_open (STDERR_FILENO));
98       break;
99     case 1:
100       /* Expect fd 2 is closed.
101          But on HP-UX 11, fd 2 gets automatically re-opened to /dev/null if it
102          was closed. Future POSIX will allow this, see
103          <http://austingroupbugs.net/view.php?id=173>.  */
104 #if !defined __hpux
105       ASSERT (! is_open (STDERR_FILENO));
106 #endif
107       break;
108     default:
109       ASSERT (0);
110     }
111
112   for (fd = 3; fd < 7; fd++)
113     {
114       errno = 0;
115       ASSERT (close (fd) == -1);
116       ASSERT (errno == EBADF);
117     }
118
119   return 0;
120 }