/* Low-level file-handling.
- Copyright (C) 2012-2020 Free Software Foundation, Inc.
+ Copyright (C) 2012-2023 Free Software Foundation, Inc.
This file is part of GDB.
if (it != open_fds.end ())
open_fds.erase (it);
else
- gdb_assert_not_reached (_("fd not found in open_fds"));
+ gdb_assert_not_reached ("fd not found in open_fds");
}
/* Helper function for close_most_fds that closes the file descriptor
/* See filestuff.h. */
-int
+scoped_fd
gdb_open_cloexec (const char *filename, int flags, unsigned long mode)
{
- int fd = open (filename, flags | O_CLOEXEC, mode);
+ scoped_fd fd (open (filename, flags | O_CLOEXEC, mode));
- if (fd >= 0)
- maybe_mark_cloexec (fd);
+ if (fd.get () >= 0)
+ maybe_mark_cloexec (fd.get ());
return fd;
}
return result;
#else
- gdb_assert_not_reached (_("socketpair not available on this host"));
+ gdb_assert_not_reached ("socketpair not available on this host");
#endif
}
mark_cloexec (filedes[1]);
}
#else /* HAVE_PIPE */
- gdb_assert_not_reached (_("pipe not available on this host"));
+ gdb_assert_not_reached ("pipe not available on this host");
#endif /* HAVE_PIPE */
#endif /* HAVE_PIPE2 */
component_end++;
/* Temporarily replace the slash with a null terminator, so we can create
- the directory up to this component. */
+ 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. */
+ 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;
component_start = component_end;
}
}
+
+/* See gdbsupport/filestuff.h. */
+
+gdb::optional<std::string>
+read_text_file_to_string (const char *path)
+{
+ gdb_file_up file = gdb_fopen_cloexec (path, "r");
+ if (file == nullptr)
+ return {};
+
+ std::string res;
+ for (;;)
+ {
+ std::string::size_type start_size = res.size ();
+ constexpr int chunk_size = 1024;
+
+ /* Resize to accommodate CHUNK_SIZE bytes. */
+ res.resize (start_size + chunk_size);
+
+ int n = fread (&res[start_size], 1, chunk_size, file.get ());
+ if (n == chunk_size)
+ continue;
+
+ gdb_assert (n < chunk_size);
+
+ /* Less than CHUNK means EOF or error. If it's an error, return
+ no value. */
+ if (ferror (file.get ()))
+ return {};
+
+ /* Resize the string according to the data we read. */
+ res.resize (start_size + n);
+ break;
+ }
+
+ return res;
+}