filestuff.cc revision 1.1.1.4 1 /* Low-level file-handling.
2 Copyright (C) 2012-2024 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program 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 This program 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 #include "filestuff.h"
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <algorithm>
25
26 #ifdef USE_WIN32API
27 #include <winsock2.h>
28 #include <windows.h>
29 #define HAVE_SOCKETS 1
30 #elif defined HAVE_SYS_SOCKET_H
31 #include <sys/socket.h>
32 /* Define HAVE_F_GETFD if we plan to use F_GETFD. */
33 #define HAVE_F_GETFD F_GETFD
34 #define HAVE_SOCKETS 1
35 #endif
36
37 #ifdef HAVE_KINFO_GETFILE
38 #include <sys/user.h>
39 #include <libutil.h>
40 #endif
41
42 #ifdef HAVE_SYS_RESOURCE_H
43 #include <sys/resource.h>
44 #endif /* HAVE_SYS_RESOURCE_H */
45
46 #ifndef O_CLOEXEC
47 #define O_CLOEXEC 0
48 #endif
49
50 #ifndef O_NOINHERIT
51 #define O_NOINHERIT 0
52 #endif
53
54 #ifndef SOCK_CLOEXEC
55 #define SOCK_CLOEXEC 0
56 #endif
57
58
59
61 #ifndef HAVE_FDWALK
62
63 #include <dirent.h>
64
65 /* Replacement for fdwalk, if the system doesn't define it. Walks all
66 open file descriptors (though this implementation may walk closed
67 ones as well, depending on the host platform's capabilities) and
68 call FUNC with ARG. If FUNC returns non-zero, stops immediately
69 and returns the same value. Otherwise, returns zero when
70 finished. */
71
72 static int
73 fdwalk (int (*func) (void *, int), void *arg)
74 {
75 /* Checking __linux__ isn't great but it isn't clear what would be
76 better. There doesn't seem to be a good way to check for this in
77 configure. */
78 #ifdef __linux__
79 DIR *dir;
80
81 dir = opendir ("/proc/self/fd");
82 if (dir != NULL)
83 {
84 struct dirent *entry;
85 int result = 0;
86
87 for (entry = readdir (dir); entry != NULL; entry = readdir (dir))
88 {
89 long fd;
90 char *tail;
91
92 errno = 0;
93 fd = strtol (entry->d_name, &tail, 10);
94 if (*tail != '\0' || errno != 0)
95 continue;
96 if ((int) fd != fd)
97 {
98 /* What can we do here really? */
99 continue;
100 }
101
102 if (fd == dirfd (dir))
103 continue;
104
105 result = func (arg, fd);
106 if (result != 0)
107 break;
108 }
109
110 closedir (dir);
111 return result;
112 }
113 /* We may fall through to the next case. */
114 #endif
115 #ifdef HAVE_KINFO_GETFILE
116 int nfd;
117 gdb::unique_xmalloc_ptr<struct kinfo_file[]> fdtbl
118 (kinfo_getfile (getpid (), &nfd));
119 if (fdtbl != NULL)
120 {
121 for (int i = 0; i < nfd; i++)
122 {
123 if (fdtbl[i].kf_fd >= 0)
124 {
125 int result = func (arg, fdtbl[i].kf_fd);
126 if (result != 0)
127 return result;
128 }
129 }
130 return 0;
131 }
132 /* We may fall through to the next case. */
133 #endif
134
135 {
136 int max, fd;
137
138 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
139 struct rlimit rlim;
140
141 if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 && rlim.rlim_max != RLIM_INFINITY)
142 max = rlim.rlim_max;
143 else
144 #endif
145 {
146 #ifdef _SC_OPEN_MAX
147 max = sysconf (_SC_OPEN_MAX);
148 #else
149 /* Whoops. */
150 return 0;
151 #endif /* _SC_OPEN_MAX */
152 }
153
154 for (fd = 0; fd < max; ++fd)
155 {
156 struct stat sb;
157 int result;
158
159 /* Only call FUNC for open fds. */
160 if (fstat (fd, &sb) == -1)
161 continue;
162
163 result = func (arg, fd);
164 if (result != 0)
165 return result;
166 }
167
168 return 0;
169 }
170 }
171
172 #endif /* HAVE_FDWALK */
173
174
175
177 /* A vector holding all the fds open when notice_open_fds was called. We
178 don't use a hashtab because we don't expect there to be many open fds. */
179
180 static std::vector<int> open_fds;
181
182 /* An fdwalk callback function used by notice_open_fds. It puts the
183 given file descriptor into the vec. */
184
185 static int
186 do_mark_open_fd (void *ignore, int fd)
187 {
188 open_fds.push_back (fd);
189 return 0;
190 }
191
192 /* See filestuff.h. */
193
194 void
195 notice_open_fds (void)
196 {
197 fdwalk (do_mark_open_fd, NULL);
198 }
199
200 /* See filestuff.h. */
201
202 void
203 mark_fd_no_cloexec (int fd)
204 {
205 do_mark_open_fd (NULL, fd);
206 }
207
208 /* See filestuff.h. */
209
210 void
211 unmark_fd_no_cloexec (int fd)
212 {
213 auto it = std::remove (open_fds.begin (), open_fds.end (), fd);
214
215 if (it != open_fds.end ())
216 open_fds.erase (it);
217 else
218 gdb_assert_not_reached ("fd not found in open_fds");
219 }
220
221 /* Helper function for close_most_fds that closes the file descriptor
222 if appropriate. */
223
224 static int
225 do_close (void *ignore, int fd)
226 {
227 for (int val : open_fds)
228 {
229 if (fd == val)
230 {
231 /* Keep this one open. */
232 return 0;
233 }
234 }
235
236 close (fd);
237 return 0;
238 }
239
240 /* See filestuff.h. */
241
242 void
243 close_most_fds (void)
244 {
245 fdwalk (do_close, NULL);
246 }
247
248
249
251 /* This is a tri-state flag. When zero it means we haven't yet tried
252 O_CLOEXEC. When positive it means that O_CLOEXEC works on this
253 host. When negative, it means that O_CLOEXEC doesn't work. We
254 track this state because, while gdb might have been compiled
255 against a libc that supplies O_CLOEXEC, there is no guarantee that
256 the kernel supports it. */
257
258 static int trust_o_cloexec;
259
260 /* Mark FD as close-on-exec, ignoring errors. Update
261 TRUST_O_CLOEXEC. */
262
263 static void
264 mark_cloexec (int fd)
265 {
266 #ifdef HAVE_F_GETFD
267 int old = fcntl (fd, F_GETFD, 0);
268
269 if (old != -1)
270 {
271 fcntl (fd, F_SETFD, old | FD_CLOEXEC);
272
273 if (trust_o_cloexec == 0)
274 {
275 if ((old & FD_CLOEXEC) != 0)
276 trust_o_cloexec = 1;
277 else
278 trust_o_cloexec = -1;
279 }
280 }
281 #endif /* HAVE_F_GETFD */
282 }
283
284 /* Depending on TRUST_O_CLOEXEC, mark FD as close-on-exec. */
285
286 static void
287 maybe_mark_cloexec (int fd)
288 {
289 if (trust_o_cloexec <= 0)
290 mark_cloexec (fd);
291 }
292
293 #ifdef HAVE_SOCKETS
294
295 /* Like maybe_mark_cloexec, but for callers that use SOCK_CLOEXEC. */
296
297 static void
298 socket_mark_cloexec (int fd)
299 {
300 if (SOCK_CLOEXEC == 0 || trust_o_cloexec <= 0)
301 mark_cloexec (fd);
302 }
303
304 #endif
305
306
307
309 /* See filestuff.h. */
310
311 scoped_fd
312 gdb_open_cloexec (const char *filename, int flags, unsigned long mode)
313 {
314 scoped_fd fd (open (filename, flags | O_CLOEXEC, mode));
315
316 if (fd.get () >= 0)
317 maybe_mark_cloexec (fd.get ());
318
319 return fd;
320 }
321
322 /* See filestuff.h. */
323
324 gdb_file_up
325 gdb_fopen_cloexec (const char *filename, const char *opentype)
326 {
327 FILE *result;
328 /* Probe for "e" support once. But, if we can tell the operating
329 system doesn't know about close on exec mode "e" without probing,
330 skip it. E.g., the Windows runtime issues an "Invalid parameter
331 passed to C runtime function" OutputDebugString warning for
332 unknown modes. Assume that if O_CLOEXEC is zero, then "e" isn't
333 supported. On MinGW, O_CLOEXEC is an alias of O_NOINHERIT, and
334 "e" isn't supported. */
335 static int fopen_e_ever_failed_einval =
336 O_CLOEXEC == 0 || O_CLOEXEC == O_NOINHERIT;
337
338 if (!fopen_e_ever_failed_einval)
339 {
340 char *copy;
341
342 copy = (char *) alloca (strlen (opentype) + 2);
343 strcpy (copy, opentype);
344 /* This is a glibc extension but we try it unconditionally on
345 this path. */
346 strcat (copy, "e");
347 result = fopen (filename, copy);
348
349 if (result == NULL && errno == EINVAL)
350 {
351 result = fopen (filename, opentype);
352 if (result != NULL)
353 fopen_e_ever_failed_einval = 1;
354 }
355 }
356 else
357 result = fopen (filename, opentype);
358
359 if (result != NULL)
360 maybe_mark_cloexec (fileno (result));
361
362 return gdb_file_up (result);
363 }
364
365 #ifdef HAVE_SOCKETS
366 /* See filestuff.h. */
367
368 int
369 gdb_socketpair_cloexec (int domain, int style, int protocol,
370 int filedes[2])
371 {
372 #ifdef HAVE_SOCKETPAIR
373 int result = socketpair (domain, style | SOCK_CLOEXEC, protocol, filedes);
374
375 if (result != -1)
376 {
377 socket_mark_cloexec (filedes[0]);
378 socket_mark_cloexec (filedes[1]);
379 }
380
381 return result;
382 #else
383 gdb_assert_not_reached ("socketpair not available on this host");
384 #endif
385 }
386
387 /* See filestuff.h. */
388
389 int
390 gdb_socket_cloexec (int domain, int style, int protocol)
391 {
392 int result = socket (domain, style | SOCK_CLOEXEC, protocol);
393
394 if (result != -1)
395 socket_mark_cloexec (result);
396
397 return result;
398 }
399 #endif
400
401 /* See filestuff.h. */
402
403 int
404 gdb_pipe_cloexec (int filedes[2])
405 {
406 int result;
407
408 #ifdef HAVE_PIPE2
409 result = pipe2 (filedes, O_CLOEXEC);
410 if (result != -1)
411 {
412 maybe_mark_cloexec (filedes[0]);
413 maybe_mark_cloexec (filedes[1]);
414 }
415 #else
416 #ifdef HAVE_PIPE
417 result = pipe (filedes);
418 if (result != -1)
419 {
420 mark_cloexec (filedes[0]);
421 mark_cloexec (filedes[1]);
422 }
423 #else /* HAVE_PIPE */
424 gdb_assert_not_reached ("pipe not available on this host");
425 #endif /* HAVE_PIPE */
426 #endif /* HAVE_PIPE2 */
427
428 return result;
429 }
430
431 /* See gdbsupport/filestuff.h. */
432
433 bool
434 is_regular_file (const char *name, int *errno_ptr)
435 {
436 struct stat st;
437 const int status = stat (name, &st);
438
439 /* Stat should never fail except when the file does not exist.
440 If stat fails, analyze the source of error and return true
441 unless the file does not exist, to avoid returning false results
442 on obscure systems where stat does not work as expected. */
443
444 if (status != 0)
445 {
446 if (errno != ENOENT)
447 return true;
448 *errno_ptr = ENOENT;
449 return false;
450 }
451
452 if (S_ISREG (st.st_mode))
453 return true;
454
455 if (S_ISDIR (st.st_mode))
456 *errno_ptr = EISDIR;
457 else
458 *errno_ptr = EINVAL;
459 return false;
460 }
461
462 /* See gdbsupport/filestuff.h. */
463
464 bool
465 mkdir_recursive (const char *dir)
466 {
467 auto holder = make_unique_xstrdup (dir);
468 char * const start = holder.get ();
469 char *component_start = start;
470 char *component_end = start;
471
472 while (1)
473 {
474 /* Find the beginning of the next component. */
475 while (*component_start == '/')
476 component_start++;
477
478 /* Are we done? */
479 if (*component_start == '\0')
480 return true;
481
482 /* Find the slash or null-terminator after this component. */
483 component_end = component_start;
484 while (*component_end != '/' && *component_end != '\0')
485 component_end++;
486
487 /* Temporarily replace the slash with a null terminator, so we can create
488 the directory up to this component. */
489 char saved_char = *component_end;
490 *component_end = '\0';
491
492 /* If we get EEXIST and the existing path is a directory, then we're
493 happy. If it exists, but it's a regular file and this is not the last
494 component, we'll fail at the next component. If this is the last
495 component, the caller will fail with ENOTDIR when trying to
496 open/create a file under that path. */
497 if (mkdir (start, 0700) != 0)
498 if (errno != EEXIST)
499 return false;
500
501 /* Restore the overwritten char. */
502 *component_end = saved_char;
503 component_start = component_end;
504 }
505 }
506
507 /* See gdbsupport/filestuff.h. */
508
509 std::string
510 read_remainder_of_file (FILE *file)
511 {
512 std::string res;
513 for (;;)
514 {
515 std::string::size_type start_size = res.size ();
516 constexpr int chunk_size = 1024;
517
518 /* Resize to accommodate CHUNK_SIZE bytes. */
519 res.resize (start_size + chunk_size);
520
521 int n = fread (&res[start_size], 1, chunk_size, file);
522 if (n == chunk_size)
523 continue;
524
525 gdb_assert (n < chunk_size);
526
527 /* Less than CHUNK means EOF or error. If it's an error, return
528 no value. */
529 if (ferror (file))
530 return {};
531
532 /* Resize the string according to the data we read. */
533 res.resize (start_size + n);
534 break;
535 }
536
537 return res;
538 }
539
540 /* See gdbsupport/filestuff.h. */
541
542 std::optional<std::string>
543 read_text_file_to_string (const char *path)
544 {
545 gdb_file_up file = gdb_fopen_cloexec (path, "r");
546 if (file == nullptr)
547 return {};
548
549 return read_remainder_of_file (file.get ());
550 }
551