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