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