common/iobuf.c: Improve iobuf_peek.
[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 <http://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   for (n=0; array[n] != -1; n++)
39     ;
40   printf ("open file descriptors: %d", n);
41   if (verbose)
42     {
43       putchar (' ');
44       putchar (' ');
45       putchar ('(');
46       for (n=0; array[n] != -1; n++)
47         printf ("%d%s", array[n], array[n+1] == -1?"":" ");
48       putchar (')');
49     }
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   printf ("max. file descriptors: %d\n", max_fd);
88   array = xget_all_open_fds ();
89   print_open_fds (array);
90   for (initial_count=n=0; array[n] != -1; n++)
91     initial_count++;
92   free (array);
93
94   /* Some dups to get more file descriptors and close one. */
95   dup (1);
96   dup (1);
97   fd = dup (1);
98   dup (1);
99   close (fd);
100
101   array = xget_all_open_fds ();
102   if (verbose)
103     print_open_fds (array);
104   for (count=n=0; array[n] != -1; n++)
105     count++;
106   if (count != initial_count+3)
107     {
108       fprintf (stderr, "%s:%d: dup or close failed\n",
109                __FILE__, __LINE__);
110       exit (1);
111     }
112   free (array);
113
114   /* Close the non standard ones.  */
115   close_all_fds (3, NULL);
116
117   /* Get a list to check whether they are all closed.  */
118   array = xget_all_open_fds ();
119   if (verbose)
120     print_open_fds (array);
121   for (count=n=0; array[n] != -1; n++)
122     count++;
123   if (count > initial_count)
124     {
125       fprintf (stderr, "%s:%d: not all files were closed\n",
126                __FILE__, __LINE__);
127       exit (1);
128     }
129   initial_count = count;
130   free (array);
131
132   /* Now let's check the realloc we use.  We do this and the next
133      tests only if we are allowed to open enought descriptors.  */
134   if (get_max_fds () > 32)
135     {
136       int except[] = { 20, 23, 24, -1 };
137
138       for (n=initial_count; n < 31; n++)
139         dup (1);
140       array = xget_all_open_fds ();
141       if (verbose)
142         print_open_fds (array);
143       free (array);
144       for (n=0; n < 5; n++)
145         {
146           dup (1);
147           array = xget_all_open_fds ();
148           if (verbose)
149             print_open_fds (array);
150           free (array);
151         }
152
153       /* Check whether the except list works.  */
154       close_all_fds (3, except);
155       array = xget_all_open_fds ();
156       if (verbose)
157         print_open_fds (array);
158       for (count=n=0; array[n] != -1; n++)
159         count++;
160       free (array);
161
162       if (count != initial_count + DIM(except)-1)
163         {
164           fprintf (stderr, "%s:%d: close_all_fds failed\n",
165                    __FILE__, __LINE__);
166           exit (1);
167         }
168     }
169
170 }
171
172
173 int
174 main (int argc, char **argv)
175 {
176   if (argc)
177     { argc--; argv++; }
178   if (argc && !strcmp (argv[0], "--verbose"))
179     {
180       verbose = 1;
181       argc--; argv++;
182     }
183
184   test_close_all_fds ();
185
186   return 0;
187 }