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