Line data Source code
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 1 : print_open_fds (int *array)
35 : {
36 : int n;
37 :
38 1 : for (n=0; array[n] != -1; n++)
39 : ;
40 1 : printf ("open file descriptors: %d", n);
41 1 : if (verbose)
42 : {
43 0 : putchar (' ');
44 0 : putchar (' ');
45 0 : putchar ('(');
46 0 : for (n=0; array[n] != -1; n++)
47 0 : printf ("%d%s", array[n], array[n+1] == -1?"":" ");
48 0 : putchar (')');
49 : }
50 1 : putchar ('\n');
51 1 : }
52 :
53 :
54 : static int *
55 10 : xget_all_open_fds (void)
56 : {
57 : int *array;
58 :
59 10 : array = get_all_open_fds ();
60 10 : if (!array)
61 : {
62 0 : fprintf (stderr, "%s:%d: get_all_open_fds failed: %s\n",
63 0 : __FILE__, __LINE__, strerror (errno));
64 0 : exit (1);
65 : }
66 10 : 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 1 : test_close_all_fds (void)
75 : {
76 1 : 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 1 : printf ("max. file descriptors: %d\n", max_fd);
88 1 : array = xget_all_open_fds ();
89 1 : print_open_fds (array);
90 4 : for (initial_count=n=0; array[n] != -1; n++)
91 3 : initial_count++;
92 1 : free (array);
93 :
94 : /* Some dups to get more file descriptors and close one. */
95 1 : dup (1);
96 1 : dup (1);
97 1 : fd = dup (1);
98 1 : dup (1);
99 1 : close (fd);
100 :
101 1 : array = xget_all_open_fds ();
102 1 : if (verbose)
103 0 : print_open_fds (array);
104 7 : for (count=n=0; array[n] != -1; n++)
105 6 : count++;
106 1 : if (count != initial_count+3)
107 : {
108 0 : fprintf (stderr, "%s:%d: dup or close failed\n",
109 : __FILE__, __LINE__);
110 0 : exit (1);
111 : }
112 1 : free (array);
113 :
114 : /* Close the non standard ones. */
115 1 : close_all_fds (3, NULL);
116 :
117 : /* Get a list to check whether they are all closed. */
118 1 : array = xget_all_open_fds ();
119 1 : if (verbose)
120 0 : print_open_fds (array);
121 4 : for (count=n=0; array[n] != -1; n++)
122 3 : count++;
123 1 : if (count > initial_count)
124 : {
125 0 : fprintf (stderr, "%s:%d: not all files were closed\n",
126 : __FILE__, __LINE__);
127 0 : exit (1);
128 : }
129 1 : initial_count = count;
130 1 : 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 1 : if (get_max_fds () > 32)
135 : {
136 1 : int except[] = { 20, 23, 24, -1 };
137 :
138 29 : for (n=initial_count; n < 31; n++)
139 28 : dup (1);
140 1 : array = xget_all_open_fds ();
141 1 : if (verbose)
142 0 : print_open_fds (array);
143 1 : free (array);
144 6 : for (n=0; n < 5; n++)
145 : {
146 5 : dup (1);
147 5 : array = xget_all_open_fds ();
148 5 : if (verbose)
149 0 : print_open_fds (array);
150 5 : free (array);
151 : }
152 :
153 : /* Check whether the except list works. */
154 1 : close_all_fds (3, except);
155 1 : array = xget_all_open_fds ();
156 1 : if (verbose)
157 0 : print_open_fds (array);
158 7 : for (count=n=0; array[n] != -1; n++)
159 6 : count++;
160 1 : free (array);
161 :
162 1 : if (count != initial_count + DIM(except)-1)
163 : {
164 0 : fprintf (stderr, "%s:%d: close_all_fds failed\n",
165 : __FILE__, __LINE__);
166 0 : exit (1);
167 : }
168 : }
169 :
170 1 : }
171 :
172 :
173 : int
174 1 : main (int argc, char **argv)
175 : {
176 1 : if (argc)
177 1 : { argc--; argv++; }
178 1 : if (argc && !strcmp (argv[0], "--verbose"))
179 : {
180 0 : verbose = 1;
181 0 : argc--; argv++;
182 : }
183 :
184 1 : test_close_all_fds ();
185 :
186 1 : return 0;
187 : }
|