/* Low-level file-handling.
- Copyright (C) 2012-2015 Free Software Foundation, Inc.
+ Copyright (C) 2012-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <algorithm>
#ifdef USE_WIN32API
#include <winsock2.h>
{
long fd;
char *tail;
- int result;
errno = 0;
fd = strtol (entry->d_name, &tail, 10);
\f
-/* A VEC holding all the fds open when notice_open_fds was called. We
- don't use a hashtab because libiberty isn't linked into gdbserver;
- and anyway we don't expect there to be many open fds. */
+/* A vector holding all the fds open when notice_open_fds was called. We
+ don't use a hashtab because we don't expect there to be many open fds. */
-static VEC (int) *open_fds;
+static std::vector<int> open_fds;
/* An fdwalk callback function used by notice_open_fds. It puts the
given file descriptor into the vec. */
static int
do_mark_open_fd (void *ignore, int fd)
{
- VEC_safe_push (int, open_fds, fd);
+ open_fds.push_back (fd);
return 0;
}
void
unmark_fd_no_cloexec (int fd)
{
- int i, val;
+ auto it = std::remove (open_fds.begin (), open_fds.end (), fd);
- for (i = 0; VEC_iterate (int, open_fds, i, val); ++i)
- {
- if (fd == val)
- {
- VEC_unordered_remove (int, open_fds, i);
- return;
- }
- }
-
- gdb_assert_not_reached (_("fd not found in open_fds"));
+ if (it != open_fds.end ())
+ open_fds.erase (it);
+ else
+ gdb_assert_not_reached (_("fd not found in open_fds"));
}
/* Helper function for close_most_fds that closes the file descriptor
static int
do_close (void *ignore, int fd)
{
- int i, val;
-
- for (i = 0; VEC_iterate (int, open_fds, i, val); ++i)
+ for (int val : open_fds)
{
if (fd == val)
{
/* See filestuff.h. */
-FILE *
+gdb_file_up
gdb_fopen_cloexec (const char *filename, const char *opentype)
{
FILE *result;
if (result != NULL)
maybe_mark_cloexec (fileno (result));
- return result;
+ return gdb_file_up (result);
}
#ifdef HAVE_SOCKETS
close (*fd);
}
-/* See cleanup-utils.h. */
+/* See filestuff.h. */
struct cleanup *
make_cleanup_close (int fd)
*saved_fd = fd;
return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree);
}
+
+/* See common/filestuff.h. */
+
+bool
+is_regular_file (const char *name, int *errno_ptr)
+{
+ struct stat st;
+ const int status = stat (name, &st);
+
+ /* Stat should never fail except when the file does not exist.
+ If stat fails, analyze the source of error and return true
+ unless the file does not exist, to avoid returning false results
+ on obscure systems where stat does not work as expected. */
+
+ if (status != 0)
+ {
+ if (errno != ENOENT)
+ return true;
+ *errno_ptr = ENOENT;
+ return false;
+ }
+
+ if (S_ISREG (st.st_mode))
+ return true;
+
+ if (S_ISDIR (st.st_mode))
+ *errno_ptr = EISDIR;
+ else
+ *errno_ptr = EINVAL;
+ return false;
+}
+
+/* See common/filestuff.h. */
+
+bool
+mkdir_recursive (const char *dir)
+{
+ gdb::unique_xmalloc_ptr<char> holder (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;
+ }
+}