+2013-04-22 Tom Tromey <tromey@redhat.com>
+
+ PR gdb/7912:
+ * Makefile.in (SFILES): Add filestuff.c
+ (COMMON_OBS): Add filestuff.o.
+ (filestuff.o): New target.
+ * auto-load.c (auto_load_objfile_script_1): Use
+ gdb_fopen_cloexec.
+ * auxv.c (procfs_xfer_auxv): Use gdb_open_cloexec.
+ * cli/cli-cmds.c (shell_escape): Call close_most_fds.
+ * cli/cli-dump.c (fopen_with_cleanup): Use gdb_fopen_cloexec.
+ * common/agent.c (gdb_connect_sync_socket): Use
+ gdb_socket_cloexec.
+ * common/filestuff.c: New file.
+ * common/filestuff.h: New file.
+ * common/linux-osdata.c (linux_common_core_of_thread)
+ (command_from_pid, commandline_from_pid, print_source_lines)
+ (linux_xfer_osdata_shm, linux_xfer_osdata_sem)
+ (linux_xfer_osdata_msg, linux_xfer_osdata_modules): Use
+ gdb_fopen_cloexec.
+ * common/linux-procfs.c (linux_proc_get_int)
+ (linux_proc_pid_has_state): Use gdb_fopen_cloexec.
+ * config.in, configure: Rebuild.
+ * configure.ac: Don't check for sys/socket.h. Check for
+ fdwalk, pipe2.
+ * corelow.c (core_open): Use gdb_open_cloexec.
+ * dwarf2read.c (write_psymtabs_to_index): Use gdb_fopen_cloexec.
+ * fork-child.c (fork_inferior): Call close_most_fds.
+ * gdb_bfd.c (gdb_bfd_open): Use gdb_open_cloexec.
+ * inf-child.c (inf_child_fileio_readlink): Use gdb_open_cloexec.
+ * linux-nat.c (linux_nat_thread_name, linux_proc_pending_signals):
+ Use gdb_fopen_cloexec.
+ (linux_proc_xfer_partial, linux_proc_xfer_spu): Use
+ gdb_open_cloexec.
+ (linux_async_pipe): Use gdb_pipe_cloexec.
+ * remote-fileio.c (remote_fileio_func_open): Use
+ gdb_open_cloexec.
+ * remote.c (remote_file_put, remote_file_get): Use
+ gdb_fopen_cloexec.
+ * ser-pipe.c (pipe_open): Use gdb_socketpair_cloexec,
+ close_most_fds.
+ * ser-tcp.c (net_open): Use gdb_socket_cloexec.
+ * ser-unix.c (hardwire_open): Use gdb_open_cloexec.
+ * solib.c (solib_find): Use gdb_open_cloexec.
+ * source.c (openp, find_and_open_source): Use gdb_open_cloexec.
+ * tracepoint.c (tfile_start): Use gdb_fopen_cloexec.
+ (tfile_open): Use gdb_open_cloexec.
+ * tui/tui-io.c (tui_initialize_io): Use gdb_pipe_cloexec.
+ * ui-file.c (gdb_fopen): Use gdb_fopen_cloexec.
+ * xml-support.c (xml_fetch_content_from_file): Use
+ gdb_fopen_cloexec.
+ * main.c (captured_main): Call notice_open_fds.
+
2013-04-22 Edjunior Machado <emachado@linux.vnet.ibm.com>
* remote-sim.c (dump_mem): Change the type of 'buf' parameter from
regset.c sol-thread.c windows-termcap.c \
common/gdb_vecs.c common/common-utils.c common/xml-utils.c \
common/ptid.c common/buffer.c gdb-dlfcn.c common/agent.c \
- common/format.c btrace.c record-btrace.c ctf.c
+ common/format.c common/filestuff.c btrace.c record-btrace.c ctf.c
LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
expprint.o environ.o stack.o thread.o \
exceptions.o \
filesystem.o \
+ filestuff.o \
inf-child.o \
interps.o \
minidebug.o \
$(COMPILE) $(srcdir)/common/buffer.c
$(POSTCOMPILE)
+filestuff.o: $(srcdir)/common/filestuff.c
+ $(COMPILE) $(srcdir)/common/filestuff.c
+ $(POSTCOMPILE)
+
format.o: ${srcdir}/common/format.c
$(COMPILE) $(srcdir)/common/format.c
$(POSTCOMPILE)
#include "observer.h"
#include "fnmatch.h"
#include "top.h"
+#include "filestuff.h"
/* The suffix of per-objfile scripts to auto-load as non-Python command files.
E.g. When the program loads libfoo.so, look for libfoo-gdb.gdb. */
cleanups = make_cleanup (xfree, filename);
- input = fopen (filename, "r");
+ input = gdb_fopen_cloexec (filename, "r");
debugfile = filename;
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file \"%s\" %s.\n"),
strcat (debugfile, filename);
make_cleanup (xfree, debugfile);
- input = fopen (debugfile, "r");
+ input = gdb_fopen_cloexec (debugfile, "r");
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file "
"\"%s\" %s.\n"),
#include "gdb_assert.h"
#include "gdbcore.h"
#include "observer.h"
+#include "filestuff.h"
#include "auxv.h"
#include "elf/common.h"
LONGEST n;
pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
- fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
+ fd = gdb_open_cloexec (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY, 0);
xfree (pathname);
if (fd < 0)
return -1;
#include "source.h"
#include "disasm.h"
#include "tracepoint.h"
+#include "filestuff.h"
#include "ui-out.h"
{
const char *p, *user_shell;
+ close_most_fds ();
+
if ((user_shell = (char *) getenv ("SHELL")) == NULL)
user_shell = "/bin/sh";
#include "gdbcore.h"
#include "cli/cli-utils.h"
#include "gdb_bfd.h"
+#include "filestuff.h"
#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
FILE *
fopen_with_cleanup (const char *filename, const char *mode)
{
- FILE *file = fopen (filename, mode);
+ FILE *file = gdb_fopen_cloexec (filename, mode);
if (file == NULL)
perror_with_name (filename);
#include <string.h>
#include <unistd.h>
#include "agent.h"
+#include "filestuff.h"
int debug_agent = 0;
if (res >= UNIX_PATH_MAX)
return -1;
- res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
+ res = fd = gdb_socket_cloexec (PF_UNIX, SOCK_STREAM, 0);
if (res == -1)
{
warning (_("error opening sync socket: %s"), strerror (errno));
--- /dev/null
+/* Low-level file-handling.
+ Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef GDBSERVER
+#include "server.h"
+#else
+#include "defs.h"
+#include "gdb_string.h"
+#endif
+#include "filestuff.h"
+#include "gdb_vecs.h"
+
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 0
+#endif
+
+\f
+
+#ifndef HAVE_FDWALK
+
+#include <dirent.h>
+
+/* Replacement for fdwalk, if the system doesn't define it. Walks all
+ open file descriptors (though this implementation may walk closed
+ ones as well, depending on the host platform's capabilities) and
+ call FUNC with ARG. If FUNC returns non-zero, stops immediately
+ and returns the same value. Otherwise, returns zero when
+ finished. */
+
+static int
+fdwalk (int (*func) (void *, int), void *arg)
+{
+ /* Checking __linux__ isn't great but it isn't clear what would be
+ better. There doesn't seem to be a good way to check for this in
+ configure. */
+#ifdef __linux__
+ DIR *dir;
+
+ dir = opendir ("/proc/self/fd");
+ if (dir != NULL)
+ {
+ struct dirent *entry;
+ int result = 0;
+
+ for (entry = readdir (dir); entry != NULL; entry = readdir (dir))
+ {
+ long fd;
+ char *tail;
+ int result;
+
+ errno = 0;
+ fd = strtol (entry->d_name, &tail, 10);
+ if (*tail != '\0' || errno != 0)
+ continue;
+ if ((int) fd != fd)
+ {
+ /* What can we do here really? */
+ continue;
+ }
+
+ if (fd == dirfd (dir))
+ continue;
+
+ result = func (arg, fd);
+ if (result != 0)
+ break;
+ }
+
+ closedir (dir);
+ return result;
+ }
+ /* We may fall through to the next case. */
+#endif
+
+ {
+ int max, fd;
+
+#ifdef HAVE_GETRLIMIT
+ struct rlimit rlim;
+
+ if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 && rlim.rlim_max != RLIM_INFINITY)
+ max = rlim.rlim_max;
+ else
+#endif
+ {
+#ifdef _SC_OPEN_MAX
+ max = sysconf (_SC_OPEN_MAX);
+#else
+ /* Whoops. */
+ return 0;
+#endif /* _SC_OPEN_MAX */
+ }
+
+ for (fd = 0; fd < max; ++fd)
+ {
+ struct stat sb;
+ int result;
+
+ /* Only call FUNC for open fds. */
+ if (fstat (fd, &sb) == -1)
+ continue;
+
+ result = func (arg, fd);
+ if (result != 0)
+ return result;
+ }
+
+ return 0;
+ }
+}
+
+#endif /* HAVE_FDWALK */
+
+\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. */
+
+DEF_VEC_I (int);
+
+static VEC (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);
+ return 0;
+}
+
+/* See filestuff.h. */
+
+void
+notice_open_fds (void)
+{
+ fdwalk (do_mark_open_fd, NULL);
+}
+
+/* Helper function for close_most_fds that closes the file descriptor
+ if appropriate. */
+
+static int
+do_close (void *ignore, int fd)
+{
+ int i, val;
+
+ for (i = 0; VEC_iterate (int, open_fds, i, val); ++i)
+ {
+ if (fd == val)
+ {
+ /* Keep this one open. */
+ return 0;
+ }
+ }
+
+ close (fd);
+ return 0;
+}
+
+/* See filestuff.h. */
+
+void
+close_most_fds (void)
+{
+ fdwalk (do_close, NULL);
+}
+
+\f
+
+/* This is a tri-state flag. When zero it means we haven't yet tried
+ O_CLOEXEC. When positive it means that O_CLOEXEC works on this
+ host. When negative, it means that O_CLOEXEC doesn't work. We
+ track this state because, while gdb might have been compiled
+ against a libc that supplies O_CLOEXEC, there is no guarantee that
+ the kernel supports it. */
+
+static int trust_o_cloexec;
+
+/* Mark FD as close-on-exec, ignoring errors. Update
+ TRUST_O_CLOEXEC. */
+
+static void
+mark_cloexec (int fd)
+{
+ int old = fcntl (fd, F_GETFD, 0);
+
+ if (old != -1)
+ {
+ fcntl (fd, F_SETFD, old | FD_CLOEXEC);
+
+ if (trust_o_cloexec == 0)
+ {
+ if ((old & FD_CLOEXEC) != 0)
+ trust_o_cloexec = 1;
+ else
+ trust_o_cloexec = -1;
+ }
+ }
+}
+
+/* Depending on TRUST_O_CLOEXEC, mark FD as close-on-exec. */
+
+static void
+maybe_mark_cloexec (int fd)
+{
+ if (trust_o_cloexec <= 0)
+ mark_cloexec (fd);
+}
+
+/* Like maybe_mark_cloexec, but for callers that use SOCK_CLOEXEC. */
+
+static void
+socket_mark_cloexec (int fd)
+{
+ if (SOCK_CLOEXEC == 0 || trust_o_cloexec <= 0)
+ mark_cloexec (fd);
+}
+
+\f
+
+/* See filestuff.h. */
+
+int
+gdb_open_cloexec (const char *filename, int flags, mode_t mode)
+{
+ int fd = open (filename, flags | O_CLOEXEC, mode);
+
+ if (fd >= 0)
+ maybe_mark_cloexec (fd);
+
+ return fd;
+}
+
+/* See filestuff.h. */
+
+FILE *
+gdb_fopen_cloexec (const char *filename, const char *opentype)
+{
+ FILE *result = NULL;
+ static int fopen_e_ever_failed;
+
+ if (!fopen_e_ever_failed)
+ {
+ char *copy;
+
+ copy = alloca (strlen (opentype) + 2);
+ strcpy (copy, opentype);
+ /* This is a glibc extension but we try it unconditionally on
+ this path. */
+ strcat (copy, "e");
+ result = fopen (filename, copy);
+ }
+
+ if (result == NULL)
+ {
+ /* Fallback. */
+ result = fopen (filename, opentype);
+ if (result != NULL)
+ fopen_e_ever_failed = 1;
+ }
+
+ if (result != NULL)
+ maybe_mark_cloexec (fileno (result));
+
+ return result;
+}
+
+/* See filestuff.h. */
+
+int
+gdb_socketpair_cloexec (int namespace, int style, int protocol, int filedes[2])
+{
+ int result = socketpair (namespace, style | SOCK_CLOEXEC, protocol, filedes);
+
+ if (result != -1)
+ {
+ socket_mark_cloexec (filedes[0]);
+ socket_mark_cloexec (filedes[1]);
+ }
+
+ return result;
+}
+
+/* See filestuff.h. */
+
+int
+gdb_socket_cloexec (int namespace, int style, int protocol)
+{
+ int result = socket (namespace, style | SOCK_CLOEXEC, protocol);
+
+ if (result != -1)
+ socket_mark_cloexec (result);
+
+ return result;
+}
+
+/* See filestuff.h. */
+
+int
+gdb_pipe_cloexec (int filedes[2])
+{
+ int result;
+
+#ifdef HAVE_PIPE2
+ result = pipe2 (filedes, O_CLOEXEC);
+ if (result != -1)
+ {
+ maybe_mark_cloexec (filedes[0]);
+ maybe_mark_cloexec (filedes[1]);
+ }
+#else
+ result = pipe (filedes);
+ if (result != -1)
+ {
+ mark_cloexec (filedes[0]);
+ mark_cloexec (filedes[1]);
+ }
+#endif
+
+ return result;
+}
--- /dev/null
+/* Low-level file-handling.
+ Copyright (C) 2012, 2013 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef FILESTUFF_H
+#define FILESTUFF_H
+
+/* Note all the file descriptors which are open when this is called.
+ These file descriptors will not be closed by close_most_fds. */
+
+extern void notice_open_fds (void);
+
+/* Close all open file descriptors other than those marked by
+ 'notice_open_fds', and stdin, stdout, and stderr. Errors that
+ occur while closing are ignored. */
+
+extern void close_most_fds (void);
+
+/* Like 'open', but ensures that the returned file descriptor has the
+ close-on-exec flag set. */
+
+extern int gdb_open_cloexec (const char *filename, int flags, mode_t mode);
+
+/* 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);
+
+/* Like 'socketpair', but ensures that the returned file descriptors
+ have the close-on-exec flag set. */
+
+extern int gdb_socketpair_cloexec (int namespace, int style, int protocol,
+ int filedes[2]);
+
+/* Like 'socket', but ensures that the returned file descriptor has
+ the close-on-exec flag set. */
+
+extern int gdb_socket_cloexec (int namespace, int style, int protocol);
+
+/* Like 'pipe', but ensures that the returned file descriptors have
+ the close-on-exec flag set. */
+
+extern int gdb_pipe_cloexec (int filedes[2]);
+
+#endif /* FILESTUFF_H */
#include "gdb_assert.h"
#include "gdb_dirent.h"
#include "gdb_stat.h"
+#include "filestuff.h"
/* Define PID_T to be a fixed size that is at least as large as pid_t,
so that reading pid values embedded in /proc works
sprintf (filename, "/proc/%lld/task/%lld/stat",
(PID_T) ptid_get_pid (ptid), (PID_T) ptid_get_lwp (ptid));
- f = fopen (filename, "r");
+ f = gdb_fopen_cloexec (filename, "r");
if (!f)
return -1;
command_from_pid (char *command, int maxlen, PID_T pid)
{
char *stat_path = xstrprintf ("/proc/%lld/stat", pid);
- FILE *fp = fopen (stat_path, "r");
+ FILE *fp = gdb_fopen_cloexec (stat_path, "r");
command[0] = '\0';
{
char *pathname = xstrprintf ("/proc/%lld/cmdline", pid);
char *commandline = NULL;
- FILE *f = fopen (pathname, "r");
+ FILE *f = gdb_fopen_cloexec (pathname, "r");
if (f)
{
else
return;
- fp = fopen (proc_file, "r");
+ fp = gdb_fopen_cloexec (proc_file, "r");
if (fp)
{
char buf[8192];
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");
- fp = fopen ("/proc/sysvipc/shm", "r");
+ fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
if (fp)
{
char buf[8192];
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");
- fp = fopen ("/proc/sysvipc/sem", "r");
+ fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
if (fp)
{
char buf[8192];
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
- fp = fopen ("/proc/sysvipc/msg", "r");
+ fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
if (fp)
{
char buf[8192];
buffer_init (&buffer);
buffer_grow_str (&buffer, "<osdata type=\"modules\">\n");
- fp = fopen ("/proc/modules", "r");
+ fp = gdb_fopen_cloexec ("/proc/modules", "r");
if (fp)
{
char buf[8192];
#endif
#include "linux-procfs.h"
+#include "filestuff.h"
/* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not
found. */
int retval = -1;
snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid);
- status_file = fopen (buf, "r");
+ status_file = gdb_fopen_cloexec (buf, "r");
if (status_file == NULL)
{
warning (_("unable to open /proc file '%s'"), buf);
int have_state;
xsnprintf (buffer, sizeof (buffer), "/proc/%d/status", (int) pid);
- procfile = fopen (buffer, "r");
+ procfile = gdb_fopen_cloexec (buffer, "r");
if (procfile == NULL)
{
warning (_("unable to open /proc file '%s'"), buffer);
/* Define to 1 if your system has the etext variable. */
#undef HAVE_ETEXT
+/* Define to 1 if you have the `fdwalk' function. */
+#undef HAVE_FDWALK
+
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `pipe' function. */
#undef HAVE_PIPE
+/* Define to 1 if you have the `pipe2' function. */
+#undef HAVE_PIPE2
+
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h locale.h \
- dlfcn.h sys/socket.h sys/un.h linux/perf_event.h
+ dlfcn.h sys/un.h linux/perf_event.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
sbrk setpgid setpgrp setsid \
sigaction sigprocmask sigsetmask socketpair syscall \
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
- setrlimit getrlimit posix_madvise waitpid lstat
+ setrlimit getrlimit posix_madvise waitpid lstat \
+ fdwalk pipe2
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
sys/reg.h sys/debugreg.h sys/select.h sys/syscall.h \
sys/types.h sys/wait.h wait.h termios.h termio.h \
sgtty.h unistd.h elf_hp.h locale.h \
- dlfcn.h sys/socket.h sys/un.h linux/perf_event.h])
+ dlfcn.h sys/un.h linux/perf_event.h])
AC_CHECK_HEADERS(link.h, [], [],
[#if HAVE_SYS_TYPES_H
# include <sys/types.h>
sbrk setpgid setpgrp setsid \
sigaction sigprocmask sigsetmask socketpair syscall \
ttrace wborder wresize setlocale iconvlist libiconvlist btowc \
- setrlimit getrlimit posix_madvise waitpid lstat])
+ setrlimit getrlimit posix_madvise waitpid lstat \
+ fdwalk pipe2])
AM_LANGINFO_CODESET
# Check the return and argument types of ptrace. No canned test for
#include "objfiles.h"
#include "gdb_bfd.h"
#include "completer.h"
+#include "filestuff.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
flags |= O_RDWR;
else
flags |= O_RDONLY;
- scratch_chan = open (filename, flags, 0);
+ scratch_chan = gdb_open_cloexec (filename, flags, 0);
if (scratch_chan < 0)
perror_with_name (filename);
#include "gdb_bfd.h"
#include "f-lang.h"
#include "source.h"
+#include "filestuff.h"
#include <fcntl.h>
#include "gdb_string.h"
INDEX_SUFFIX, (char *) NULL);
cleanup = make_cleanup (xfree, filename);
- out_file = fopen (filename, "wb");
+ out_file = gdb_fopen_cloexec (filename, "wb");
if (!out_file)
error (_("Can't open `%s' for writing"), filename);
#include "command.h" /* for dont_repeat () */
#include "gdbcmd.h"
#include "solib.h"
+#include "filestuff.h"
#include <signal.h>
if (pid == 0)
{
+ close_most_fds ();
+
if (debug_fork)
sleep (debug_fork);
#include "ui-out.h"
#include "gdbcmd.h"
#include "hashtab.h"
+#include "filestuff.h"
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
if (fd == -1)
{
- fd = open (name, O_RDONLY | O_BINARY);
+ fd = gdb_open_cloexec (name, O_RDONLY | O_BINARY, 0);
if (fd == -1)
{
bfd_set_error (bfd_error_system_call);
+2013-04-22 Tom Tromey <tromey@redhat.com>
+
+ * Makefile.in (SFILES): Add filestuff.c.
+ (OBS): Add filestuff.o.
+ (filestuff.o): New target.
+ * config.in, configure: Rebuild.
+ * configure.ac: Check for fdwalk, pipe2.
+
2013-04-17 Pedro Alves <palves@redhat.com>
* configure.ac (USE_THREAD_DB): Delete variable.
$(srcdir)/common/vec.c $(srcdir)/common/gdb_vecs.c \
$(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
$(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
- $(srcdir)/common/buffer.c $(srcdir)/common/linux-btrace.c
+ $(srcdir)/common/buffer.c $(srcdir)/common/linux-btrace.c \
+ $(srcdir)/common/filestuff.c
DEPFILES = @GDBSERVER_DEPFILES@
OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
utils.o version.o vec.o gdb_vecs.o \
mem-break.o hostio.o event-loop.o tracepoint.o \
- xml-utils.o common-utils.o ptid.o buffer.o format.o \
+ xml-utils.o common-utils.o ptid.o buffer.o format.o filestuff.o \
dll.o notif.o \
$(XML_BUILTIN) \
$(DEPFILES) $(LIBOBJS)
format.o: ../common/format.c
$(COMPILE) $<
$(POSTCOMPILE)
+filestuff.o: ../common/filestuff.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
agent.o: ../common/agent.c
$(COMPILE) $<
$(POSTCOMPILE)
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
+/* Define to 1 if you have the `fdwalk' function. */
+#undef HAVE_FDWALK
+
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if you support the personality syscall. */
#undef HAVE_PERSONALITY
+/* Define to 1 if you have the `pipe2' function. */
+#undef HAVE_PIPE2
+
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
done
-for ac_func in pread pwrite pread64 readlink
+for ac_func in pread pwrite pread64 readlink fdwalk pipe2
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl
netinet/tcp.h arpa/inet.h sys/wait.h wait.h sys/un.h dnl
linux/perf_event.h)
-AC_CHECK_FUNCS(pread pwrite pread64 readlink)
+AC_CHECK_FUNCS(pread pwrite pread64 readlink fdwalk pipe2)
AC_REPLACE_FUNCS(vasprintf vsnprintf)
# Check for UST
#include "gdb/fileio.h"
#include "agent.h"
#include "gdb_wait.h"
+#include "filestuff.h"
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> /* for MAXPATHLEN */
/* We do not need to convert MODE, since the fileio protocol uses
the standard values. */
- fd = open (filename, nat_flags, mode);
+ fd = gdb_open_cloexec (filename, nat_flags, mode);
if (fd == -1)
*target_errno = inf_child_errno_to_fileio_error (errno);
#include "linux-ptrace.h"
#include "buffer.h"
#include "target-descriptions.h"
+#include "filestuff.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
char *result = NULL;
snprintf (buf, sizeof (buf), FORMAT, pid, lwp);
- comm_file = fopen (buf, "r");
+ comm_file = gdb_fopen_cloexec (buf, "r");
if (comm_file)
{
/* Not exported by the kernel, so we define it here. */
/* We could keep this file open and cache it - possibly one per
thread. That requires some juggling, but is even faster. */
sprintf (filename, "/proc/%d/mem", PIDGET (inferior_ptid));
- fd = open (filename, O_RDONLY | O_LARGEFILE);
+ fd = gdb_open_cloexec (filename, O_RDONLY | O_LARGEFILE, 0);
if (fd == -1)
return 0;
}
xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex);
- fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
+ fd = gdb_open_cloexec (buf, writebuf? O_WRONLY : O_RDONLY, 0);
if (fd <= 0)
return -1;
sigemptyset (blocked);
sigemptyset (ignored);
sprintf (fname, "/proc/%d/status", pid);
- procfile = fopen (fname, "r");
+ procfile = gdb_fopen_cloexec (fname, "r");
if (procfile == NULL)
error (_("Could not open %s"), fname);
cleanup = make_cleanup_fclose (procfile);
if (enable)
{
- if (pipe (linux_nat_event_pipe) == -1)
+ if (gdb_pipe_cloexec (linux_nat_event_pipe) == -1)
internal_error (__FILE__, __LINE__,
"creating event pipe failed.");
#include "maint.h"
#include "filenames.h"
+#include "filestuff.h"
/* The selected interpreter. This will be used as a set command
variable, so it should always be malloc'ed - since
textdomain (PACKAGE);
bfd_init ();
+ notice_open_fds ();
make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
dirsize = 1;
#include "event-loop.h"
#include "target.h"
#include "filenames.h"
+#include "filestuff.h"
#include <fcntl.h>
#include <sys/time.h>
}
remote_fio_no_longjmp = 1;
- fd = open (pathname, flags, mode);
+ fd = gdb_open_cloexec (pathname, flags, mode);
if (fd < 0)
{
remote_fileio_return_errno (-1);
#include "cli/cli-setshow.h"
#include "target-descriptions.h"
#include "gdb_bfd.h"
+#include "filestuff.h"
#include <ctype.h>
#include <sys/time.h>
if (!remote_desc)
error (_("command can only be used with remote target"));
- file = fopen (local_file, "rb");
+ file = gdb_fopen_cloexec (local_file, "rb");
if (file == NULL)
perror_with_name (local_file);
back_to = make_cleanup_fclose (file);
if (fd == -1)
remote_hostio_error (remote_errno);
- file = fopen (local_file, "wb");
+ file = gdb_fopen_cloexec (local_file, "wb");
if (file == NULL)
perror_with_name (local_file);
back_to = make_cleanup_fclose (file);
#include <sys/time.h>
#include <fcntl.h>
#include "gdb_string.h"
+#include "filestuff.h"
#include <signal.h>
int err_pdes[2];
int pid;
- if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
+ if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
return -1;
- if (socketpair (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
+ if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, err_pdes) < 0)
{
close (pdes[0]);
close (pdes[1]);
dup2 (err_pdes[1], STDERR_FILENO);
close (err_pdes[1]);
}
-#if 0
- /* close any stray FD's - FIXME - how? */
- /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
- from previous popen() calls that remain open in the
- parent process are closed in the new child process. */
- for (old = pidlist; old; old = old->next)
- close (fileno (old->fp)); /* Don't allow a flush. */
-#endif
+
+ close_most_fds ();
execl ("/bin/sh", "sh", "-c", name, (char *) 0);
_exit (127);
}
return -1;
#else
- if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
+ if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
return -1;
/* If we don't do this, GDB simply exits when the remote side
#include "gdbcmd.h"
#include "cli/cli-decode.h"
#include "cli/cli-setshow.h"
+#include "filestuff.h"
#include <sys/types.h>
retry:
if (use_udp)
- scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
+ scb->fd = gdb_socket_cloexec (PF_INET, SOCK_DGRAM, 0);
else
- scb->fd = socket (PF_INET, SOCK_STREAM, 0);
+ scb->fd = gdb_socket_cloexec (PF_INET, SOCK_STREAM, 0);
if (scb->fd == -1)
return -1;
#include "gdb_select.h"
#include "gdb_string.h"
#include "gdbcmd.h"
+#include "filestuff.h"
#ifdef HAVE_TERMIOS
static int
hardwire_open (struct serial *scb, const char *name)
{
- scb->fd = open (name, O_RDWR);
+ scb->fd = gdb_open_cloexec (name, O_RDWR, 0);
if (scb->fd < 0)
return -1;
#include "interps.h"
#include "filesystem.h"
#include "gdb_bfd.h"
+#include "filestuff.h"
/* Architecture-specific operations. */
}
/* Now see if we can open it. */
- found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+ found_file = gdb_open_cloexec (temp_pathname, O_RDONLY | O_BINARY, 0);
if (found_file < 0)
xfree (temp_pathname);
in_pathname + 2, (char *) NULL);
xfree (drive);
- found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+ found_file = gdb_open_cloexec (temp_pathname, O_RDONLY | O_BINARY, 0);
if (found_file < 0)
{
xfree (temp_pathname);
need_dir_separator ? SLASH_STRING : "",
in_pathname + 2, (char *) NULL);
- found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
+ found_file = gdb_open_cloexec (temp_pathname, O_RDONLY | O_BINARY, 0);
if (found_file < 0)
xfree (temp_pathname);
}
#include "frame.h"
#include "value.h"
#include "gdb_assert.h"
+#include "filestuff.h"
#include <sys/types.h>
#include "gdb_string.h"
{
filename = alloca (strlen (string) + 1);
strcpy (filename, string);
- fd = open (filename, mode);
+ fd = gdb_open_cloexec (filename, mode, 0);
if (fd >= 0)
goto done;
}
if (is_regular_file (filename))
{
- fd = open (filename, mode);
+ fd = gdb_open_cloexec (filename, mode, 0);
if (fd >= 0)
break;
}
*fullname = rewritten_fullname;
}
- result = open (*fullname, OPEN_MODE);
+ result = gdb_open_cloexec (*fullname, OPEN_MODE, 0);
if (result >= 0)
{
char *lpath = gdb_realpath (*fullname);
#include "probe.h"
#include "ctf.h"
#include "completer.h"
+#include "filestuff.h"
/* readline include files */
#include "readline/readline.h"
= (struct tfile_trace_file_writer *) self;
writer->pathname = tilde_expand (filename);
- writer->fp = fopen (writer->pathname, "wb");
+ writer->fp = gdb_fopen_cloexec (writer->pathname, "wb");
if (writer->fp == NULL)
error (_("Unable to open file '%s' for saving trace data (%s)"),
filename, safe_strerror (errno));
target is losing, we can get out without touching files. */
status = target_get_trace_status (ts);
- writer->ops->start (writer, filename);
-
writer->ops->write_header (writer);
/* Write descriptive info. */
flags = O_BINARY | O_LARGEFILE;
flags |= O_RDONLY;
- scratch_chan = open (filename, flags, 0);
+ scratch_chan = gdb_open_cloexec (filename, flags, 0);
if (scratch_chan < 0)
perror_with_name (filename);
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
+#include "filestuff.h"
#include "gdb_curses.h"
/* Temporary solution for readline writing to stdout: redirect
readline output in a pipe, read that pipe and output the content
in the curses command window. */
- if (pipe (tui_readline_pipe) != 0)
+ if (gdb_pipe_cloexec (tui_readline_pipe) != 0)
{
fprintf_unfiltered (gdb_stderr, "Cannot create pipe for readline");
exit (1);
#include "gdb_obstack.h"
#include "gdb_string.h"
#include "gdb_select.h"
+#include "filestuff.h"
#include <errno.h>
struct ui_file *
gdb_fopen (char *name, char *mode)
{
- FILE *f = fopen (name, mode);
+ FILE *f = gdb_fopen_cloexec (name, mode);
if (f == NULL)
return NULL;
#include "gdbcmd.h"
#include "exceptions.h"
#include "xml-support.h"
+#include "filestuff.h"
#include "gdb_string.h"
#include "safe-ctype.h"
if (fullname == NULL)
malloc_failure (0);
- file = fopen (fullname, FOPEN_RT);
+ file = gdb_fopen_cloexec (fullname, FOPEN_RT);
xfree (fullname);
}
else
- file = fopen (filename, FOPEN_RT);
+ file = gdb_fopen_cloexec (filename, FOPEN_RT);
if (file == NULL)
return NULL;