+2017-08-03 Tom Tromey <tom@tromey.com>
+
+ * xml-support.c (xml_fetch_content_from_file): Update.
+ * ui-file.c (stdio_file::open): Update.
+ * tracefile-tfile.c (tfile_start): Update.
+ * remote.c (remote_file_put, remote_file_get): Update.
+ * nat/linux-procfs.c (linux_proc_get_int)
+ (linux_proc_pid_get_state, linux_proc_tid_get_name): Update.
+ * nat/linux-osdata.c (linux_common_core_of_thread): Update.
+ (command_from_pid, commandline_from_pid, linux_xfer_osdata_cpus)
+ (print_sockets, linux_xfer_osdata_shm, linux_xfer_osdata_sem)
+ (linux_xfer_osdata_msg, linux_xfer_osdata_modules): Update.
+ * nat/linux-btrace.c (linux_determine_kernel_start): Update.
+ * linux-nat.c (linux_proc_pending_signals): Update.
+ * dwarf2read.c (write_psymtabs_to_index): Use gdb_file_up.
+ (file_closer): Remove.
+ * compile/compile.c (compile_to_object): Update.
+ * common/filestuff.h (struct gdb_file_deleter): New.
+ (gdb_file_up): New typedef.
+ (gdb_fopen_cloexec): Change return type.
+ * common/filestuff.c (gdb_fopen_cloexec): Return gdb_file_up.
+ * cli/cli-dump.c (fopen_with_cleanup): Remove.
+ (dump_binary_file, restore_binary_file): Update.
+ * auto-load.c (auto_load_objfile_script_1): Update.
+
2017-08-03 Tom Tromey <tom@tromey.com>
* tracepoint.c (tvariables_info_1): Use ui_out_emit_table.
{
char *filename, *debugfile;
int len, retval;
- FILE *input;
struct cleanup *cleanups;
const char *suffix = ext_lang_auto_load_suffix (language);
cleanups = make_cleanup (xfree, filename);
- input = gdb_fopen_cloexec (filename, "r");
+ gdb_file_up input = gdb_fopen_cloexec (filename, "r");
debugfile = filename;
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file \"%s\" %s.\n"),
int is_safe;
struct auto_load_pspace_info *pspace_info;
- make_cleanup_fclose (input);
-
is_safe
= file_is_auto_load_safe (debugfile,
_("auto-load: Loading %s script \"%s\""
compiled in. And the extension language is required to implement
this function. */
gdb_assert (sourcer != NULL);
- sourcer (language, objfile, input, debugfile);
+ sourcer (language, objfile, input.get (), debugfile);
}
retval = 1;
return fullname;
}
-static FILE *
-fopen_with_cleanup (const char *filename, const char *mode)
-{
- FILE *file = gdb_fopen_cloexec (filename, mode);
-
- if (file == NULL)
- perror_with_name (filename);
- make_cleanup_fclose (file);
- return file;
-}
-
static gdb_bfd_ref_ptr
bfd_openr_or_error (const char *filename, const char *target)
{
dump_binary_file (const char *filename, const char *mode,
const bfd_byte *buf, ULONGEST len)
{
- FILE *file;
int status;
- file = fopen_with_cleanup (filename, mode);
- status = fwrite (buf, len, 1, file);
+ gdb_file_up file = gdb_fopen_cloexec (filename, mode);
+ status = fwrite (buf, len, 1, file.get ());
if (status != 1)
perror_with_name (filename);
}
static void
restore_binary_file (const char *filename, struct callback_data *data)
{
- struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
- FILE *file = fopen_with_cleanup (filename, FOPEN_RB);
+ gdb_file_up file = gdb_fopen_cloexec (filename, FOPEN_RB);
long len;
/* Get the file size for reading. */
- if (fseek (file, 0, SEEK_END) == 0)
+ if (fseek (file.get (), 0, SEEK_END) == 0)
{
- len = ftell (file);
+ len = ftell (file.get ());
if (len < 0)
perror_with_name (filename);
}
(unsigned long) (data->load_start + data->load_offset + len));
/* Now set the file pos to the requested load start pos. */
- if (fseek (file, data->load_start, SEEK_SET) != 0)
+ if (fseek (file.get (), data->load_start, SEEK_SET) != 0)
perror_with_name (filename);
/* Now allocate a buffer and read the file contents. */
gdb::byte_vector buf (len);
- if (fread (buf.data (), 1, len, file) != len)
+ if (fread (buf.data (), 1, len, file.get ()) != len)
perror_with_name (filename);
/* Now write the buffer into target memory. */
buf.data (), len);
if (len != 0)
warning (_("restore: memory write failed (%s)."), safe_strerror (len));
- do_cleanups (cleanup);
}
static void
/* 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
extern int gdb_open_cloexec (const char *filename, int flags,
/* mode_t */ unsigned long mode);
+struct gdb_file_deleter
+{
+ void operator() (FILE *file) const
+ {
+ fclose (file);
+ }
+};
+
+/* A unique pointer to a FILE. */
+
+typedef std::unique_ptr<FILE, gdb_file_deleter> gdb_file_up;
+
/* Like 'fopen', but ensures that the returned file descriptor has the
close-on-exec flag set. */
-extern FILE *gdb_fopen_cloexec (const char *filename, const char *opentype);
+extern gdb_file_up gdb_fopen_cloexec (const char *filename,
+ const char *opentype);
/* Like 'socketpair', but ensures that the returned file descriptors
have the close-on-exec flag set. */
compile_file_names fnames = get_new_file_names ();
- src = gdb_fopen_cloexec (fnames.source_file (), "w");
- if (src == NULL)
- perror_with_name (_("Could not open source file for writing"));
- inner_cleanup = make_cleanup (cleanup_unlink_file,
- (void *) fnames.source_file ());
- if (fputs (code.c_str (), src) == EOF)
- perror_with_name (_("Could not write to source file"));
- fclose (src);
+ {
+ gdb_file_up src = gdb_fopen_cloexec (fnames.source_file (), "w");
+ if (src == NULL)
+ perror_with_name (_("Could not open source file for writing"));
+ inner_cleanup = make_cleanup (cleanup_unlink_file,
+ (void *) fnames.source_file ());
+ if (fputs (code.c_str (), src.get ()) == EOF)
+ perror_with_name (_("Could not write to source file"));
+ }
if (compile_debug)
fprintf_unfiltered (gdb_stdlog, "source file produced: %s\n\n",
1);
}
-/* Closes FILE on scope exit. */
-struct file_closer
-{
- explicit file_closer (FILE *file)
- : m_file (file)
- {}
-
- ~file_closer ()
- { fclose (m_file); }
-
-private:
- FILE *m_file;
-};
-
/* Create an index file for OBJFILE in the directory DIR. */
static void
std::string filename (std::string (dir) + SLASH_STRING
+ lbasename (objfile_name (objfile)) + INDEX_SUFFIX);
- FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb");
+ FILE *out_file = gdb_fopen_cloexec (filename.c_str (), "wb").release ();
if (!out_file)
error (_("Can't open `%s' for writing"), filename.c_str ());
still open. (Don't call anything here that might throw until
file_closer is created.) */
gdb::unlinker unlink_file (filename.c_str ());
- file_closer close_out_file (out_file);
+ gdb_file_up close_out_file (out_file);
mapped_symtab symtab;
data_buf cu_list;
linux_proc_pending_signals (int pid, sigset_t *pending,
sigset_t *blocked, sigset_t *ignored)
{
- FILE *procfile;
char buffer[PATH_MAX], fname[PATH_MAX];
- struct cleanup *cleanup;
sigemptyset (pending);
sigemptyset (blocked);
sigemptyset (ignored);
xsnprintf (fname, sizeof fname, "/proc/%d/status", pid);
- procfile = gdb_fopen_cloexec (fname, "r");
+ gdb_file_up procfile = gdb_fopen_cloexec (fname, "r");
if (procfile == NULL)
error (_("Could not open %s"), fname);
- cleanup = make_cleanup_fclose (procfile);
- while (fgets (buffer, PATH_MAX, procfile) != NULL)
+ while (fgets (buffer, PATH_MAX, procfile.get ()) != NULL)
{
/* Normal queued signals are on the SigPnd line in the status
file. However, 2.6 kernels also have a "shared" pending
else if (startswith (buffer, "SigIgn:\t"))
add_line_to_sigset (buffer + 8, ignored);
}
-
- do_cleanups (cleanup);
}
static enum target_xfer_status
{
static uint64_t kernel_start;
static int cached;
- FILE *file;
if (cached != 0)
return kernel_start;
cached = 1;
- file = gdb_fopen_cloexec ("/proc/kallsyms", "r");
+ gdb_file_up file = gdb_fopen_cloexec ("/proc/kallsyms", "r");
if (file == NULL)
return kernel_start;
- while (!feof (file))
+ while (!feof (file.get ()))
{
char buffer[1024], symbol[8], *line;
uint64_t addr;
int match;
- line = fgets (buffer, sizeof (buffer), file);
+ line = fgets (buffer, sizeof (buffer), file.get ());
if (line == NULL)
break;
}
}
- fclose (file);
-
return kernel_start;
}
linux_common_core_of_thread (ptid_t ptid)
{
char filename[sizeof ("/proc//task//stat") + 2 * MAX_PID_T_STRLEN];
- FILE *f;
char *content = NULL;
char *p;
char *ts = 0;
sprintf (filename, "/proc/%lld/task/%lld/stat",
(PID_T) ptid_get_pid (ptid), (PID_T) ptid_get_lwp (ptid));
- f = gdb_fopen_cloexec (filename, "r");
+ gdb_file_up f = gdb_fopen_cloexec (filename, "r");
if (!f)
return -1;
{
int n;
content = (char *) xrealloc (content, content_read + 1024);
- n = fread (content + content_read, 1, 1024, f);
+ n = fread (content + content_read, 1, 1024, f.get ());
content_read += n;
if (n < 1024)
{
core = -1;
xfree (content);
- fclose (f);
return core;
}
command_from_pid (char *command, int maxlen, PID_T pid)
{
char *stat_path = xstrprintf ("/proc/%lld/stat", pid);
- FILE *fp = gdb_fopen_cloexec (stat_path, "r");
+ gdb_file_up fp = gdb_fopen_cloexec (stat_path, "r");
command[0] = '\0';
(for the brackets). */
char cmd[18];
PID_T stat_pid;
- int items_read = fscanf (fp, "%lld %17s", &stat_pid, cmd);
+ int items_read = fscanf (fp.get (), "%lld %17s", &stat_pid, cmd);
if (items_read == 2 && pid == stat_pid)
{
cmd[strlen (cmd) - 1] = '\0'; /* Remove trailing parenthesis. */
strncpy (command, cmd + 1, maxlen); /* Ignore leading parenthesis. */
}
-
- fclose (fp);
}
else
{
{
char *pathname = xstrprintf ("/proc/%lld/cmdline", pid);
char *commandline = NULL;
- FILE *f = gdb_fopen_cloexec (pathname, "r");
+ gdb_file_up f = gdb_fopen_cloexec (pathname, "r");
if (f)
{
size_t len = 0;
- while (!feof (f))
+ while (!feof (f.get ()))
{
char buf[1024];
- size_t read_bytes = fread (buf, 1, sizeof (buf), f);
+ size_t read_bytes = fread (buf, 1, sizeof (buf), f.get ());
if (read_bytes)
{
}
}
- fclose (f);
-
if (commandline)
{
size_t i;
if (offset == 0)
{
- FILE *fp;
int first_item = 1;
if (len_avail != -1 && len_avail != 0)
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"cpus\">\n");
- fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
if (fp != NULL)
{
char buf[8192];
do
{
- if (fgets (buf, sizeof (buf), fp))
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
char *key, *value;
int i = 0;
value);
}
}
- while (!feof (fp));
+ while (!feof (fp.get ()));
if (first_item == 0)
buffer_grow_str (&buffer, "</item>");
-
- fclose (fp);
}
buffer_grow_str0 (&buffer, "</osdata>\n");
print_sockets (unsigned short family, int tcp, struct buffer *buffer)
{
const char *proc_file;
- FILE *fp;
if (family == AF_INET)
proc_file = tcp ? "/proc/net/tcp" : "/proc/net/udp";
else
return;
- fp = gdb_fopen_cloexec (proc_file, "r");
+ gdb_file_up fp = gdb_fopen_cloexec (proc_file, "r");
if (fp)
{
char buf[8192];
do
{
- if (fgets (buf, sizeof (buf), fp))
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
uid_t uid;
unsigned int local_port, remote_port, state;
}
}
}
- while (!feof (fp));
-
- fclose (fp);
+ while (!feof (fp.get ()));
}
}
if (offset == 0)
{
- FILE *fp;
-
if (len_avail != -1 && len_avail != 0)
buffer_free (&buffer);
len_avail = 0;
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");
- fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
if (fp)
{
char buf[8192];
do
{
- if (fgets (buf, sizeof (buf), fp))
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
key_t key;
uid_t uid, cuid;
}
}
}
- while (!feof (fp));
-
- fclose (fp);
+ while (!feof (fp.get ()));
}
buffer_grow_str0 (&buffer, "</osdata>\n");
if (offset == 0)
{
- FILE *fp;
-
if (len_avail != -1 && len_avail != 0)
buffer_free (&buffer);
len_avail = 0;
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");
- fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
if (fp)
{
char buf[8192];
do
{
- if (fgets (buf, sizeof (buf), fp))
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
key_t key;
uid_t uid, cuid;
}
}
}
- while (!feof (fp));
-
- fclose (fp);
+ while (!feof (fp.get ()));
}
buffer_grow_str0 (&buffer, "</osdata>\n");
if (offset == 0)
{
- FILE *fp;
-
if (len_avail != -1 && len_avail != 0)
buffer_free (&buffer);
len_avail = 0;
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
- fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
if (fp)
{
char buf[8192];
do
{
- if (fgets (buf, sizeof (buf), fp))
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
key_t key;
PID_T lspid, lrpid;
}
}
}
- while (!feof (fp));
-
- fclose (fp);
+ while (!feof (fp.get ()));
}
buffer_grow_str0 (&buffer, "</osdata>\n");
if (offset == 0)
{
- FILE *fp;
-
if (len_avail != -1 && len_avail != 0)
buffer_free (&buffer);
len_avail = 0;
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"modules\">\n");
- fp = gdb_fopen_cloexec ("/proc/modules", "r");
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/modules", "r");
if (fp)
{
char buf[8192];
do
{
- if (fgets (buf, sizeof (buf), fp))
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
char *name, *dependencies, *status, *tmp;
unsigned int size;
address);
}
}
- while (!feof (fp));
-
- fclose (fp);
+ while (!feof (fp.get ()));
}
buffer_grow_str0 (&buffer, "</osdata>\n");
linux_proc_get_int (pid_t lwpid, const char *field, int warn)
{
size_t field_len = strlen (field);
- FILE *status_file;
char buf[100];
int retval = -1;
snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid);
- status_file = gdb_fopen_cloexec (buf, "r");
+ gdb_file_up status_file = gdb_fopen_cloexec (buf, "r");
if (status_file == NULL)
{
if (warn)
return -1;
}
- while (fgets (buf, sizeof (buf), status_file))
+ while (fgets (buf, sizeof (buf), status_file.get ()))
if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':')
{
retval = strtol (&buf[field_len + 1], NULL, 10);
break;
}
- fclose (status_file);
return retval;
}
static int
linux_proc_pid_get_state (pid_t pid, int warn, enum proc_state *state)
{
- FILE *procfile;
int have_state;
char buffer[100];
xsnprintf (buffer, sizeof (buffer), "/proc/%d/status", (int) pid);
- procfile = gdb_fopen_cloexec (buffer, "r");
+ gdb_file_up procfile = gdb_fopen_cloexec (buffer, "r");
if (procfile == NULL)
{
if (warn)
}
have_state = 0;
- while (fgets (buffer, sizeof (buffer), procfile) != NULL)
+ while (fgets (buffer, sizeof (buffer), procfile.get ()) != NULL)
if (startswith (buffer, "State:"))
{
have_state = 1;
*state = parse_proc_status_state (buffer + sizeof ("State:") - 1);
break;
}
- fclose (procfile);
return have_state;
}
static char comm_buf[TASK_COMM_LEN];
char comm_path[100];
- FILE *comm_file;
const char *comm_val;
pid_t pid = ptid_get_pid (ptid);
pid_t tid = ptid_lwp_p (ptid) ? ptid_get_lwp (ptid) : ptid_get_pid (ptid);
xsnprintf (comm_path, sizeof (comm_path),
"/proc/%ld/task/%ld/comm", (long) pid, (long) tid);
- comm_file = gdb_fopen_cloexec (comm_path, "r");
+ gdb_file_up comm_file = gdb_fopen_cloexec (comm_path, "r");
if (comm_file == NULL)
return NULL;
- comm_val = fgets (comm_buf, sizeof (comm_buf), comm_file);
- fclose (comm_file);
+ comm_val = fgets (comm_buf, sizeof (comm_buf), comm_file.get ());
if (comm_val != NULL)
{
{
struct cleanup *back_to, *close_cleanup;
int retcode, fd, remote_errno, bytes, io_size;
- FILE *file;
gdb_byte *buffer;
int bytes_in_buffer;
int saw_eof;
if (!rs->remote_desc)
error (_("command can only be used with remote target"));
- file = gdb_fopen_cloexec (local_file, "rb");
+ gdb_file_up file = gdb_fopen_cloexec (local_file, "rb");
if (file == NULL)
perror_with_name (local_file);
- back_to = make_cleanup_fclose (file);
fd = remote_hostio_open (find_target_at (process_stratum), NULL,
remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
remote packet limit, so we'll transfer slightly fewer. */
io_size = get_remote_packet_size ();
buffer = (gdb_byte *) xmalloc (io_size);
- make_cleanup (xfree, buffer);
+ back_to = make_cleanup (xfree, buffer);
close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
{
bytes = fread (buffer + bytes_in_buffer, 1,
io_size - bytes_in_buffer,
- file);
+ file.get ());
if (bytes == 0)
{
- if (ferror (file))
+ if (ferror (file.get ()))
error (_("Error reading %s."), local_file);
else
{
{
struct cleanup *back_to, *close_cleanup;
int fd, remote_errno, bytes, io_size;
- FILE *file;
gdb_byte *buffer;
ULONGEST offset;
struct remote_state *rs = get_remote_state ();
if (fd == -1)
remote_hostio_error (remote_errno);
- file = gdb_fopen_cloexec (local_file, "wb");
+ gdb_file_up file = gdb_fopen_cloexec (local_file, "wb");
if (file == NULL)
perror_with_name (local_file);
- back_to = make_cleanup_fclose (file);
/* Send up to this many bytes at once. They won't all fit in the
remote packet limit, so we'll transfer slightly fewer. */
io_size = get_remote_packet_size ();
buffer = (gdb_byte *) xmalloc (io_size);
- make_cleanup (xfree, buffer);
+ back_to = make_cleanup (xfree, buffer);
close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
offset += bytes;
- bytes = fwrite (buffer, 1, bytes, file);
+ bytes = fwrite (buffer, 1, bytes, file.get ());
if (bytes == 0)
perror_with_name (local_file);
}
= (struct tfile_trace_file_writer *) self;
writer->pathname = tilde_expand (filename);
- writer->fp = gdb_fopen_cloexec (writer->pathname, "wb");
+ writer->fp = gdb_fopen_cloexec (writer->pathname, "wb").release ();
if (writer->fp == NULL)
error (_("Unable to open file '%s' for saving trace data (%s)"),
writer->pathname, safe_strerror (errno));
m_close_p = false;
}
- FILE *f = gdb_fopen_cloexec (name, mode);
+ gdb_file_up f = gdb_fopen_cloexec (name, mode);
if (f == NULL)
return false;
- set_stream (f);
+ set_stream (f.release ());
m_close_p = true;
return true;
xml_fetch_content_from_file (const char *filename, void *baton)
{
const char *dirname = (const char *) baton;
- FILE *file;
+ gdb_file_up file;
struct cleanup *back_to;
char *text;
size_t len, offset;
if (file == NULL)
return NULL;
- back_to = make_cleanup_fclose (file);
-
/* Read in the whole file, one chunk at a time. */
len = 4096;
offset = 0;
text = (char *) xmalloc (len);
- make_cleanup (free_current_contents, &text);
+ back_to = make_cleanup (free_current_contents, &text);
while (1)
{
size_t bytes_read;
/* Continue reading where the last read left off. Leave at least
one byte so that we can NUL-terminate the result. */
- bytes_read = fread (text + offset, 1, len - offset - 1, file);
- if (ferror (file))
+ bytes_read = fread (text + offset, 1, len - offset - 1, file.get ());
+ if (ferror (file.get ()))
{
warning (_("Read error from \"%s\""), filename);
do_cleanups (back_to);
offset += bytes_read;
- if (feof (file))
+ if (feof (file.get ()))
break;
len = len * 2;
text = (char *) xrealloc (text, len);
}
- fclose (file);
discard_cleanups (back_to);
text[offset] = '\0';