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