gpg: Fix build on Windows.
[gnupg.git] / common / t-exechelp.c
1 /* t-exechelp.c - Module test for exechelp.c
2  *      Copyright (C) 2009 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <assert.h>
25 #include <unistd.h>
26
27 #include "util.h"
28 #include "exechelp.h"
29
30 static int verbose;
31
32
33 static void
34 print_open_fds (int *array)
35 {
36   int n;
37
38   if (!verbose)
39     return;
40
41   for (n=0; array[n] != -1; n++)
42     ;
43   printf ("open file descriptors: %d", n);
44   putchar (' ');
45   putchar (' ');
46   putchar ('(');
47   for (n=0; array[n] != -1; n++)
48     printf ("%d%s", array[n], array[n+1] == -1?"":" ");
49   putchar (')');
50   putchar ('\n');
51 }
52
53
54 static int *
55 xget_all_open_fds (void)
56 {
57   int *array;
58
59   array = get_all_open_fds ();
60   if (!array)
61     {
62       fprintf (stderr, "%s:%d: get_all_open_fds failed: %s\n",
63                __FILE__, __LINE__, strerror (errno));
64       exit (1);
65     }
66   return array;
67 }
68
69
70 /* That is a very crude test.  To do a proper test we would need to
71    fork a test process and best return information by some other means
72    than file descriptors. */
73 static void
74 test_close_all_fds (void)
75 {
76   int max_fd = get_max_fds ();
77   int *array;
78   int fd;
79   int initial_count, count, n;
80 #if 0
81   char buffer[100];
82
83   snprintf (buffer, sizeof buffer, "/bin/ls -l /proc/%d/fd", (int)getpid ());
84   system (buffer);
85 #endif
86
87   if (verbose)
88     printf ("max. file descriptors: %d\n", max_fd);
89   array = xget_all_open_fds ();
90   print_open_fds (array);
91   for (initial_count=n=0; array[n] != -1; n++)
92     initial_count++;
93   free (array);
94
95   /* Some dups to get more file descriptors and close one. */
96   dup (1);
97   dup (1);
98   fd = dup (1);
99   dup (1);
100   close (fd);
101
102   array = xget_all_open_fds ();
103   if (verbose)
104     print_open_fds (array);
105   for (count=n=0; array[n] != -1; n++)
106     count++;
107   if (count != initial_count+3)
108     {
109       fprintf (stderr, "%s:%d: dup or close failed\n",
110                __FILE__, __LINE__);
111       exit (1);
112     }
113   free (array);
114
115   /* Close the non standard ones.  */
116   close_all_fds (3, NULL);
117
118   /* Get a list to check whether they are all closed.  */
119   array = xget_all_open_fds ();
120   if (verbose)
121     print_open_fds (array);
122   for (count=n=0; array[n] != -1; n++)
123     count++;
124   if (count > initial_count)
125     {
126       fprintf (stderr, "%s:%d: not all files were closed\n",
127                __FILE__, __LINE__);
128       exit (1);
129     }
130   initial_count = count;
131   free (array);
132
133   /* Now let's check the realloc we use.  We do this and the next
134      tests only if we are allowed to open enought descriptors.  */
135   if (get_max_fds () > 32)
136     {
137       int except[] = { 20, 23, 24, -1 };
138
139       for (n=initial_count; n < 31; n++)
140         dup (1);
141       array = xget_all_open_fds ();
142       if (verbose)
143         print_open_fds (array);
144       free (array);
145       for (n=0; n < 5; n++)
146         {
147           dup (1);
148           array = xget_all_open_fds ();
149           if (verbose)
150             print_open_fds (array);
151           free (array);
152         }
153
154       /* Check whether the except list works.  */
155       close_all_fds (3, except);
156       array = xget_all_open_fds ();
157       if (verbose)
158         print_open_fds (array);
159       for (count=n=0; array[n] != -1; n++)
160         count++;
161       free (array);
162
163       if (count != initial_count + DIM(except)-1)
164         {
165           fprintf (stderr, "%s:%d: close_all_fds failed\n",
166                    __FILE__, __LINE__);
167           exit (1);
168         }
169     }
170
171 }
172
173
174 int
175 main (int argc, char **argv)
176 {
177   if (argc)
178     { argc--; argv++; }
179   if (argc && !strcmp (argv[0], "--verbose"))
180     {
181       verbose = 1;
182       argc--; argv++;
183     }
184
185   test_close_all_fds ();
186
187   return 0;
188 }