X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fcommon%2Ffilestuff.c;h=c7b8c694055138cea1c66c89154f5251a70d2d50;hb=5b0e2db4fa08b43e9ff78d6e9a45d496522bd241;hp=fa10165a7cac8739964cb953dc433f896e684c4c;hpb=3c025cfe5efc44eb4dfb03b53dca28e75096dd1e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/common/filestuff.c b/gdb/common/filestuff.c index fa10165a7c..c7b8c69405 100644 --- a/gdb/common/filestuff.c +++ b/gdb/common/filestuff.c @@ -1,5 +1,5 @@ /* Low-level file-handling. - Copyright (C) 2012-2018 Free Software Foundation, Inc. + Copyright (C) 2012-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -36,6 +36,11 @@ #define HAVE_SOCKETS 1 #endif +#ifdef HAVE_KINFO_GETFILE +#include +#include +#endif + #ifdef HAVE_SYS_RESOURCE_H #include #endif /* HAVE_SYS_RESOURCE_H */ @@ -44,6 +49,10 @@ #define O_CLOEXEC 0 #endif +#ifndef O_NOINHERIT +#define O_NOINHERIT 0 +#endif + #ifndef SOCK_CLOEXEC #define SOCK_CLOEXEC 0 #endif @@ -80,7 +89,6 @@ fdwalk (int (*func) (void *, int), void *arg) { long fd; char *tail; - int result; errno = 0; fd = strtol (entry->d_name, &tail, 10); @@ -105,6 +113,25 @@ fdwalk (int (*func) (void *, int), void *arg) } /* We may fall through to the next case. */ #endif +#ifdef HAVE_KINFO_GETFILE + int nfd; + gdb::unique_xmalloc_ptr fdtbl + (kinfo_getfile (getpid (), &nfd)); + if (fdtbl != NULL) + { + for (int i = 0; i < nfd; i++) + { + if (fdtbl[i].kf_fd >= 0) + { + int result = func (arg, fdtbl[i].kf_fd); + if (result != 0) + return result; + } + } + return 0; + } + /* We may fall through to the next case. */ +#endif { int max, fd; @@ -301,8 +328,10 @@ gdb_fopen_cloexec (const char *filename, const char *opentype) skip it. E.g., the Windows runtime issues an "Invalid parameter passed to C runtime function" OutputDebugString warning for unknown modes. Assume that if O_CLOEXEC is zero, then "e" isn't - supported. */ - static int fopen_e_ever_failed_einval = O_CLOEXEC == 0; + supported. On MinGW, O_CLOEXEC is an alias of O_NOINHERIT, and + "e" isn't supported. */ + static int fopen_e_ever_failed_einval = + O_CLOEXEC == 0 || O_CLOEXEC == O_NOINHERIT; if (!fopen_e_ever_failed_einval) { @@ -397,27 +426,6 @@ gdb_pipe_cloexec (int filedes[2]) return result; } -/* Helper function which does the work for make_cleanup_close. */ - -static void -do_close_cleanup (void *arg) -{ - int *fd = (int *) arg; - - close (*fd); -} - -/* See filestuff.h. */ - -struct cleanup * -make_cleanup_close (int fd) -{ - int *saved_fd = XNEW (int); - - *saved_fd = fd; - return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree); -} - /* See common/filestuff.h. */ bool @@ -448,3 +456,48 @@ is_regular_file (const char *name, int *errno_ptr) *errno_ptr = EINVAL; return false; } + +/* See common/filestuff.h. */ + +bool +mkdir_recursive (const char *dir) +{ + auto holder = make_unique_xstrdup (dir); + char * const start = holder.get (); + char *component_start = start; + char *component_end = start; + + while (1) + { + /* Find the beginning of the next component. */ + while (*component_start == '/') + component_start++; + + /* Are we done? */ + if (*component_start == '\0') + return true; + + /* Find the slash or null-terminator after this component. */ + component_end = component_start; + while (*component_end != '/' && *component_end != '\0') + component_end++; + + /* Temporarily replace the slash with a null terminator, so we can create + the directory up to this component. */ + char saved_char = *component_end; + *component_end = '\0'; + + /* If we get EEXIST and the existing path is a directory, then we're + happy. If it exists, but it's a regular file and this is not the last + component, we'll fail at the next component. If this is the last + component, the caller will fail with ENOTDIR when trying to + open/create a file under that path. */ + if (mkdir (start, 0700) != 0) + if (errno != EEXIST) + return false; + + /* Restore the overwritten char. */ + *component_end = saved_char; + component_start = component_end; + } +}