This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: close-on-exec internal file descriptors


Tom> I'll give it a try.  If it works I suppose we'll need a new plan.
Tom> One idea would be to see which file descriptors are open when gdb
Tom> starts, and then preserve just those.

Here's the implementation of this idea.

Built and regtested on x86-64 Fedora 16.

Tom

2013-01-03  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 (trace_save): 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.

2012-12-18  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.

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index b065d41..9c8d96b 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -755,7 +755,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	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
+	common/format.c common/filestuff.c
 
 LINTFILES = $(SFILES) $(YYFILES) $(CONFIG_SRCS) init.c
 
@@ -875,6 +875,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	expprint.o environ.o stack.o thread.o \
 	exceptions.o \
 	filesystem.o \
+	filestuff.o \
 	inf-child.o \
 	interps.o \
 	minidebug.o \
@@ -1930,6 +1931,10 @@ buffer.o: ${srcdir}/common/buffer.c
 	$(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)
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index 850c704..f4f9367 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -38,6 +38,7 @@
 #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.  */
@@ -739,7 +740,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
 
   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"),
@@ -771,7 +772,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
 	  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"),
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 3a63a65..879d7e1 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -26,6 +26,7 @@
 #include "gdb_assert.h"
 #include "gdbcore.h"
 #include "observer.h"
+#include "filestuff.h"
 
 #include "auxv.h"
 #include "elf/common.h"
@@ -48,7 +49,7 @@ procfs_xfer_auxv (gdb_byte *readbuf,
   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;
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 3a58c1b..3ead1b1 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -39,6 +39,7 @@
 #include "source.h"
 #include "disasm.h"
 #include "tracepoint.h"
+#include "filestuff.h"
 
 #include "ui-out.h"
 
@@ -728,6 +729,8 @@ shell_escape (char *arg, int from_tty)
     {
       const char *p, *user_shell;
 
+      close_most_fds ();
+
       if ((user_shell = (char *) getenv ("SHELL")) == NULL)
 	user_shell = "/bin/sh";
 
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index 1e59464..4a1f561 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -33,6 +33,7 @@
 #include "gdbcore.h"
 #include "cli/cli-utils.h"
 #include "gdb_bfd.h"
+#include "filestuff.h"
 
 #define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
 
@@ -99,7 +100,7 @@ scan_filename_with_cleanup (char **cmd, const char *defname)
 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);
diff --git a/gdb/common/agent.c b/gdb/common/agent.c
index 632310d..f37aae3 100644
--- a/gdb/common/agent.c
+++ b/gdb/common/agent.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <unistd.h>
 #include "agent.h"
+#include "filestuff.h"
 
 int debug_agent = 0;
 
@@ -168,7 +169,7 @@ gdb_connect_sync_socket (int pid)
   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));
diff --git a/gdb/common/filestuff.c b/gdb/common/filestuff.c
new file mode 100644
index 0000000..29efc10
--- /dev/null
+++ b/gdb/common/filestuff.c
@@ -0,0 +1,354 @@
+/* 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
+
+
+
+#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 */
+
+
+
+/* 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);
+}
+
+
+
+/* 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);
+}
+
+
+
+/* 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;
+  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;
+}
diff --git a/gdb/common/filestuff.h b/gdb/common/filestuff.h
new file mode 100644
index 0000000..747bff2
--- /dev/null
+++ b/gdb/common/filestuff.h
@@ -0,0 +1,59 @@
+/* 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 */
diff --git a/gdb/common/linux-osdata.c b/gdb/common/linux-osdata.c
index d55470b..9723839 100644
--- a/gdb/common/linux-osdata.c
+++ b/gdb/common/linux-osdata.c
@@ -44,6 +44,7 @@
 #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
@@ -76,7 +77,7 @@ linux_common_core_of_thread (ptid_t ptid)
 
   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;
 
@@ -125,7 +126,7 @@ static void
 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';
  
@@ -165,7 +166,7 @@ commandline_from_pid (PID_T pid)
 {
   char *pathname = xstrprintf ("/proc/%lld/cmdline", pid);
   char *commandline = NULL;
-  FILE *f = fopen (pathname, "r");
+  FILE *f = gdb_fopen_cloexec (pathname, "r");
 
   if (f)
     {
@@ -860,7 +861,7 @@ print_sockets (unsigned short family, int tcp, struct buffer *buffer)
   else
     return;
 
-  fp = fopen (proc_file, "r");
+  fp = gdb_fopen_cloexec (proc_file, "r");
   if (fp)
     {
       char buf[8192];
@@ -1088,7 +1089,7 @@ linux_xfer_osdata_shm (gdb_byte *readbuf,
       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];
@@ -1216,7 +1217,7 @@ linux_xfer_osdata_sem (gdb_byte *readbuf,
       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];
@@ -1328,7 +1329,7 @@ linux_xfer_osdata_msg (gdb_byte *readbuf,
       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];
@@ -1454,7 +1455,7 @@ linux_xfer_osdata_modules (gdb_byte *readbuf,
       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];
diff --git a/gdb/common/linux-procfs.c b/gdb/common/linux-procfs.c
index f5dccfd..583ec98 100644
--- a/gdb/common/linux-procfs.c
+++ b/gdb/common/linux-procfs.c
@@ -24,6 +24,7 @@
 #endif
 
 #include "linux-procfs.h"
+#include "filestuff.h"
 
 /* Return the TGID of LWPID from /proc/pid/status.  Returns -1 if not
    found.  */
@@ -37,7 +38,7 @@ linux_proc_get_int (pid_t lwpid, const char *field)
   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);
@@ -83,7 +84,7 @@ linux_proc_pid_has_state (pid_t pid, const char *state)
   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);
diff --git a/gdb/config.in b/gdb/config.in
index 9e21325..bda940e 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -141,6 +141,9 @@
 /* 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
 
@@ -267,6 +270,9 @@
 /* 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
 
@@ -500,9 +506,6 @@
 /* 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
 
diff --git a/gdb/configure b/gdb/configure
index 6273193..061fb39 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -8893,7 +8893,7 @@ for ac_header in nlist.h machine/reg.h poll.h sys/poll.h proc_service.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"
@@ -10151,7 +10151,8 @@ for ac_func in canonicalize_file_name realpath getrusage getuid getgid \
 		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"
diff --git a/gdb/configure.ac b/gdb/configure.ac
index de096b8..9344c7e 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1082,7 +1082,7 @@ AC_CHECK_HEADERS([nlist.h machine/reg.h poll.h sys/poll.h proc_service.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])
 AC_CHECK_HEADERS(link.h, [], [],
 [#if HAVE_SYS_TYPES_H
 # include <sys/types.h>
@@ -1164,7 +1164,8 @@ AC_CHECK_FUNCS([canonicalize_file_name realpath getrusage getuid getgid \
 		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
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 121c846..fa244a5 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -46,6 +46,7 @@
 #include "progspace.h"
 #include "objfiles.h"
 #include "gdb_bfd.h"
+#include "filestuff.h"
 
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
@@ -313,7 +314,7 @@ core_open (char *filename, int from_tty)
     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);
 
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 5a061f5..1f103810 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -67,6 +67,7 @@
 #include <ctype.h>
 #include "gdb_bfd.h"
 #include "f-lang.h"
+#include "filestuff.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -20274,7 +20275,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
 		     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);
 
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
index 69a59cc..6820872 100644
--- a/gdb/fork-child.c
+++ b/gdb/fork-child.c
@@ -32,6 +32,7 @@
 #include "command.h" /* for dont_repeat () */
 #include "gdbcmd.h"
 #include "solib.h"
+#include "filestuff.h"
 
 #include <signal.h>
 
@@ -313,6 +314,8 @@ fork_inferior (char *exec_file_arg, char *allargs, char **env,
 
   if (pid == 0)
     {
+      close_most_fds ();
+
       if (debug_fork)
 	sleep (debug_fork);
 
diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index ae561d3..ebd9279 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -24,6 +24,7 @@
 #include "ui-out.h"
 #include "gdbcmd.h"
 #include "hashtab.h"
+#include "filestuff.h"
 #ifdef HAVE_ZLIB_H
 #include <zlib.h>
 #endif
@@ -152,7 +153,7 @@ gdb_bfd_open (const char *name, const char *target, int fd)
 
   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);
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index f8b1794..24c5a1b 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -155,7 +155,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \
 	$(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/buffer.c $(srcdir)/common/filestuff.c
 
 DEPFILES = @GDBSERVER_DEPFILES@
 
@@ -167,7 +167,7 @@ TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
 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)
@@ -538,6 +538,9 @@ buffer.o: ../common/buffer.c
 format.o: ../common/format.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+filestuff.o: ../common/filestuff.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 agent.o: ../common/agent.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index b791b89..59c2bd4 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -67,6 +67,9 @@
 /* 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
 
@@ -109,6 +112,9 @@
 /* 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
 
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index 9ec9340..730a01f 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -4596,7 +4596,7 @@ fi
 
 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"
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index 55fb461..0e892f7 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -69,7 +69,7 @@ AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl
 		 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
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 5f34922..15d8613 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -30,6 +30,7 @@
 #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 */
@@ -245,7 +246,7 @@ inf_child_fileio_open (const char *filename, int flags, int mode,
 
   /* 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);
 
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index e9438b5..d74025d 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -67,6 +67,7 @@
 #include "linux-ptrace.h"
 #include "buffer.h"
 #include "target-descriptions.h"
+#include "filestuff.h"
 
 #ifndef SPUFS_MAGIC
 #define SPUFS_MAGIC 0x23c9b64e
@@ -4278,7 +4279,7 @@ linux_nat_thread_name (struct thread_info *thr)
   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.  */
@@ -4405,7 +4406,7 @@ linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
   /* 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;
 
@@ -4499,7 +4500,7 @@ linux_proc_xfer_spu (struct target_ops *ops, enum target_object object,
     }
 
   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;
 
@@ -4575,7 +4576,7 @@ linux_proc_pending_signals (int pid, sigset_t *pending,
   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);
@@ -4918,7 +4919,7 @@ linux_async_pipe (int enable)
 
       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.");
 
diff --git a/gdb/main.c b/gdb/main.c
index 14893bd..a5f8007 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -42,6 +42,7 @@
 #include "python/python.h"
 #include "objfiles.h"
 #include "auto-load.h"
+#include "filestuff.h"
 
 /* The selected interpreter.  This will be used as a set command
    variable, so it should always be malloc'ed - since
@@ -357,6 +358,8 @@ captured_main (void *data)
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 
+  notice_open_fds ();
+
   make_cleanup (VEC_cleanup (cmdarg_s), &cmdarg_vec);
   dirsize = 1;
   dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
diff --git a/gdb/remote-fileio.c b/gdb/remote-fileio.c
index 2f9d644..cc39bdf 100644
--- a/gdb/remote-fileio.c
+++ b/gdb/remote-fileio.c
@@ -31,6 +31,7 @@
 #include "event-loop.h"
 #include "target.h"
 #include "filenames.h"
+#include "filestuff.h"
 
 #include <fcntl.h>
 #include <sys/time.h>
@@ -639,7 +640,7 @@ remote_fileio_func_open (char *buf)
     }
 
   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);
diff --git a/gdb/remote.c b/gdb/remote.c
index 59b2eb6..730211f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -44,6 +44,7 @@
 #include "cli/cli-setshow.h"
 #include "target-descriptions.h"
 #include "gdb_bfd.h"
+#include "filestuff.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -9899,7 +9900,7 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
   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);
@@ -9991,7 +9992,7 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty)
   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);
diff --git a/gdb/ser-pipe.c b/gdb/ser-pipe.c
index 9a98923..1b30f78 100644
--- a/gdb/ser-pipe.c
+++ b/gdb/ser-pipe.c
@@ -30,6 +30,7 @@
 #include <sys/time.h>
 #include <fcntl.h>
 #include "gdb_string.h"
+#include "filestuff.h"
 
 #include <signal.h>
 
@@ -63,9 +64,9 @@ pipe_open (struct serial *scb, const char *name)
   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]);
@@ -122,14 +123,8 @@ pipe_open (struct serial *scb, const char *name)
 	  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);
     }
@@ -201,7 +196,7 @@ gdb_pipe (int pdes[2])
   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
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index f9615d5..e621a3c 100644
--- a/gdb/ser-tcp.c
+++ b/gdb/ser-tcp.c
@@ -24,6 +24,7 @@
 #include "gdbcmd.h"
 #include "cli/cli-decode.h"
 #include "cli/cli-setshow.h"
+#include "filestuff.h"
 
 #include <sys/types.h>
 
@@ -207,9 +208,9 @@ net_open (struct serial *scb, const char *name)
  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;
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c
index 9ec8bb1..cd1d9a9 100644
--- a/gdb/ser-unix.c
+++ b/gdb/ser-unix.c
@@ -31,6 +31,7 @@
 #include "gdb_select.h"
 #include "gdb_string.h"
 #include "gdbcmd.h"
+#include "filestuff.h"
 
 #ifdef HAVE_TERMIOS
 
@@ -107,7 +108,7 @@ void _initialize_ser_hardwire (void);
 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;
 
diff --git a/gdb/solib.c b/gdb/solib.c
index 8129c0f..21919c2 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -47,6 +47,7 @@
 #include "interps.h"
 #include "filesystem.h"
 #include "gdb_bfd.h"
+#include "filestuff.h"
 
 /* Architecture-specific operations.  */
 
@@ -246,7 +247,7 @@ solib_find (char *in_pathname, int *fd)
     }
 
   /* 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);
 
@@ -269,7 +270,7 @@ solib_find (char *in_pathname, int *fd)
 			      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);
@@ -284,7 +285,7 @@ solib_find (char *in_pathname, int *fd)
 				  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);
 	}
diff --git a/gdb/source.c b/gdb/source.c
index 6e12896..3e6aaa3 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -27,6 +27,7 @@
 #include "frame.h"
 #include "value.h"
 #include "gdb_assert.h"
+#include "filestuff.h"
 
 #include <sys/types.h>
 #include "gdb_string.h"
@@ -716,7 +717,7 @@ openp (const char *path, int opts, const char *string,
 	{
 	  filename = alloca (strlen (string) + 1);
 	  strcpy (filename, string);
-	  fd = open (filename, mode);
+	  fd = gdb_open_cloexec (filename, mode, 0);
 	  if (fd >= 0)
 	    goto done;
 	}
@@ -814,7 +815,7 @@ openp (const char *path, int opts, const char *string,
 
       if (is_regular_file (filename))
 	{
-	  fd = open (filename, mode);
+	  fd = gdb_open_cloexec (filename, mode, 0);
 	  if (fd >= 0)
 	    break;
 	}
@@ -983,7 +984,7 @@ find_and_open_source (const char *filename,
           *fullname = rewritten_fullname;
         }
 
-      result = open (*fullname, OPEN_MODE);
+      result = gdb_open_cloexec (*fullname, OPEN_MODE, 0);
       if (result >= 0)
 	{
 	  /* Call xfullpath here to be consistent with openp
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 53a4988..0254da1 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -53,6 +53,7 @@
 #include "exceptions.h"
 #include "cli/cli-utils.h"
 #include "probe.h"
+#include "filestuff.h"
 
 /* readline include files */
 #include "readline/readline.h"
@@ -2999,7 +3000,7 @@ trace_save (const char *filename, int target_does_save)
   pathname = tilde_expand (filename);
   cleanup = make_cleanup (xfree, pathname);
 
-  fp = fopen (pathname, "wb");
+  fp = gdb_fopen_cloexec (pathname, "wb");
   if (!fp)
     error (_("Unable to open file '%s' for saving trace data (%s)"),
 	   filename, safe_strerror (errno));
@@ -3720,7 +3721,7 @@ tfile_open (char *filename, int from_tty)
 
   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);
 
diff --git a/gdb/tui/tui-io.c b/gdb/tui/tui-io.c
index ef658f5..f255fdf 100644
--- a/gdb/tui/tui-io.c
+++ b/gdb/tui/tui-io.c
@@ -37,6 +37,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <stdio.h>
+#include "filestuff.h"
 
 #include "gdb_curses.h"
 
@@ -616,7 +617,7 @@ tui_initialize_io (void)
   /* 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);
diff --git a/gdb/ui-file.c b/gdb/ui-file.c
index bb904c9..5671abd 100644
--- a/gdb/ui-file.c
+++ b/gdb/ui-file.c
@@ -24,6 +24,7 @@
 #include "gdb_obstack.h"
 #include "gdb_string.h"
 #include "gdb_select.h"
+#include "filestuff.h"
 
 #include <errno.h>
 
@@ -664,7 +665,7 @@ stdio_fileopen (FILE *file)
 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;
diff --git a/gdb/xml-support.c b/gdb/xml-support.c
index 7ace5b9..b777814 100644
--- a/gdb/xml-support.c
+++ b/gdb/xml-support.c
@@ -21,6 +21,7 @@
 #include "gdbcmd.h"
 #include "exceptions.h"
 #include "xml-support.h"
+#include "filestuff.h"
 
 #include "gdb_string.h"
 #include "safe-ctype.h"
@@ -1044,11 +1045,11 @@ xml_fetch_content_from_file (const char *filename, void *baton)
 
       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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]