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