f1d3f0f9ceb5ce3404448514248c4a0dc630986e
[pspp] / tests / test-spawn-pipe-child.c
1 /* Child program invoked by test-spawn-pipe..
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 read
49 #undef write
50
51 /* Return non-zero if FD is open.  */
52 static int
53 is_open (int fd)
54 {
55 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
56   /* On Win32, the initial state of unassigned standard file
57      descriptors is that they are open but point to an
58      INVALID_HANDLE_VALUE, and there is no fcntl.  */
59   return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
60 #else
61 # ifndef F_GETFL
62 #  error Please port fcntl to your platform
63 # endif
64   return 0 <= fcntl (fd, F_GETFL);
65 #endif
66 }
67
68 int
69 main (int argc, char *argv[])
70 {
71   char buffer[2] = { 's', 't' };
72   int fd;
73
74   /* fd 2 might be closed, but fd BACKUP_STDERR_FILENO is the original
75      stderr.  */
76   myerr = fdopen (BACKUP_STDERR_FILENO, "w");
77   if (!myerr)
78     return 2;
79
80   ASSERT (argc == 2);
81
82   /* Read one byte from fd 0, and write its value plus one to fd 1.
83      fd 2 should be closed iff the argument is 1.  Check that no other file
84      descriptors leaked.  */
85
86   ASSERT (read (STDIN_FILENO, buffer, 2) == 1);
87
88   buffer[0]++;
89   ASSERT (write (STDOUT_FILENO, buffer, 1) == 1);
90
91   switch (atoi (argv[1]))
92     {
93     case 0:
94       /* Expect fd 2 is open.  */
95       ASSERT (is_open (STDERR_FILENO));
96       break;
97     case 1:
98       /* Expect fd 2 is closed.  */
99       ASSERT (! is_open (STDERR_FILENO));
100       break;
101     default:
102       ASSERT (0);
103     }
104
105   for (fd = 3; fd < 7; fd++)
106     {
107       errno = 0;
108       ASSERT (close (fd) == -1);
109       ASSERT (errno == EBADF);
110     }
111
112   return 0;
113 }