GDB (API)
/home/stan/gdb/src/gdb/common/filestuff.c
Go to the documentation of this file.
00001 /* Low-level file-handling.
00002    Copyright (C) 2012, 2013 Free Software Foundation, Inc.
00003 
00004    This file is part of GDB.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00018 
00019 #ifdef GDBSERVER
00020 #include "server.h"
00021 #else
00022 #include "defs.h"
00023 #include "gdb_string.h"
00024 #endif
00025 #include "filestuff.h"
00026 #include "gdb_vecs.h"
00027 
00028 #include <string.h>
00029 #include <fcntl.h>
00030 #include <unistd.h>
00031 #include <sys/types.h>
00032 #include "gdb_stat.h"
00033 
00034 #ifdef USE_WIN32API
00035 #include <winsock2.h>
00036 #include <windows.h>
00037 #define HAVE_SOCKETS 1
00038 #elif defined HAVE_SYS_SOCKET_H
00039 #include <sys/socket.h>
00040 /* Define HAVE_F_GETFD if we plan to use F_GETFD.  */
00041 #define HAVE_F_GETFD F_GETFD
00042 #define HAVE_SOCKETS 1
00043 #endif
00044 
00045 #ifdef HAVE_SYS_RESOURCE_H
00046 #include <sys/resource.h>
00047 #endif /* HAVE_SYS_RESOURCE_H */
00048 
00049 #ifndef O_CLOEXEC
00050 #define O_CLOEXEC 0
00051 #endif
00052 
00053 #ifndef SOCK_CLOEXEC
00054 #define SOCK_CLOEXEC 0
00055 #endif
00056 
00057 
00058 
00059 #ifndef HAVE_FDWALK
00060 
00061 #include "gdb_dirent.h"
00062 
00063 /* Replacement for fdwalk, if the system doesn't define it.  Walks all
00064    open file descriptors (though this implementation may walk closed
00065    ones as well, depending on the host platform's capabilities) and
00066    call FUNC with ARG.  If FUNC returns non-zero, stops immediately
00067    and returns the same value.  Otherwise, returns zero when
00068    finished.  */
00069 
00070 static int
00071 fdwalk (int (*func) (void *, int), void *arg)
00072 {
00073   /* Checking __linux__ isn't great but it isn't clear what would be
00074      better.  There doesn't seem to be a good way to check for this in
00075      configure.  */
00076 #ifdef __linux__
00077   DIR *dir;
00078 
00079   dir = opendir ("/proc/self/fd");
00080   if (dir != NULL)
00081     {
00082       struct dirent *entry;
00083       int result = 0;
00084 
00085       for (entry = readdir (dir); entry != NULL; entry = readdir (dir))
00086         {
00087           long fd;
00088           char *tail;
00089           int result;
00090 
00091           errno = 0;
00092           fd = strtol (entry->d_name, &tail, 10);
00093           if (*tail != '\0' || errno != 0)
00094             continue;
00095           if ((int) fd != fd)
00096             {
00097               /* What can we do here really?  */
00098               continue;
00099             }
00100 
00101           if (fd == dirfd (dir))
00102             continue;
00103 
00104           result = func (arg, fd);
00105           if (result != 0)
00106             break;
00107         }
00108 
00109       closedir (dir);
00110       return result;
00111     }
00112   /* We may fall through to the next case.  */
00113 #endif
00114 
00115   {
00116     int max, fd;
00117 
00118 #ifdef HAVE_GETRLIMIT
00119     struct rlimit rlim;
00120 
00121     if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 && rlim.rlim_max != RLIM_INFINITY)
00122       max = rlim.rlim_max;
00123     else
00124 #endif
00125       {
00126 #ifdef _SC_OPEN_MAX
00127         max = sysconf (_SC_OPEN_MAX);
00128 #else
00129         /* Whoops.  */
00130         return 0;
00131 #endif /* _SC_OPEN_MAX */
00132       }
00133 
00134     for (fd = 0; fd < max; ++fd)
00135       {
00136         struct stat sb;
00137         int result;
00138 
00139         /* Only call FUNC for open fds.  */
00140         if (fstat (fd, &sb) == -1)
00141           continue;
00142 
00143         result = func (arg, fd);
00144         if (result != 0)
00145           return result;
00146       }
00147 
00148     return 0;
00149   }
00150 }
00151 
00152 #endif /* HAVE_FDWALK */
00153 
00154 
00155 
00156 /* A VEC holding all the fds open when notice_open_fds was called.  We
00157    don't use a hashtab because libiberty isn't linked into gdbserver;
00158    and anyway we don't expect there to be many open fds.  */
00159 
00160 static VEC (int) *open_fds;
00161 
00162 /* An fdwalk callback function used by notice_open_fds.  It puts the
00163    given file descriptor into the vec.  */
00164 
00165 static int
00166 do_mark_open_fd (void *ignore, int fd)
00167 {
00168   VEC_safe_push (int, open_fds, fd);
00169   return 0;
00170 }
00171 
00172 /* See filestuff.h.  */
00173 
00174 void
00175 notice_open_fds (void)
00176 {
00177   fdwalk (do_mark_open_fd, NULL);
00178 }
00179 
00180 /* See filestuff.h.  */
00181 
00182 void
00183 mark_fd_no_cloexec (int fd)
00184 {
00185   do_mark_open_fd (NULL, fd);
00186 }
00187 
00188 /* See filestuff.h.  */
00189 
00190 void
00191 unmark_fd_no_cloexec (int fd)
00192 {
00193   int i, val;
00194 
00195   for (i = 0; VEC_iterate (int, open_fds, i, val); ++i)
00196     {
00197       if (fd == val)
00198         {
00199           VEC_unordered_remove (int, open_fds, i);
00200           return;
00201         }
00202     }
00203 
00204   gdb_assert_not_reached (_("fd not found in open_fds"));
00205 }
00206 
00207 /* Helper function for close_most_fds that closes the file descriptor
00208    if appropriate.  */
00209 
00210 static int
00211 do_close (void *ignore, int fd)
00212 {
00213   int i, val;
00214 
00215   for (i = 0; VEC_iterate (int, open_fds, i, val); ++i)
00216     {
00217       if (fd == val)
00218         {
00219           /* Keep this one open.  */
00220           return 0;
00221         }
00222     }
00223 
00224   close (fd);
00225   return 0;
00226 }
00227 
00228 /* See filestuff.h.  */
00229 
00230 void
00231 close_most_fds (void)
00232 {
00233   fdwalk (do_close, NULL);
00234 }
00235 
00236 
00237 
00238 /* This is a tri-state flag.  When zero it means we haven't yet tried
00239    O_CLOEXEC.  When positive it means that O_CLOEXEC works on this
00240    host.  When negative, it means that O_CLOEXEC doesn't work.  We
00241    track this state because, while gdb might have been compiled
00242    against a libc that supplies O_CLOEXEC, there is no guarantee that
00243    the kernel supports it.  */
00244 
00245 static int trust_o_cloexec;
00246 
00247 /* Mark FD as close-on-exec, ignoring errors.  Update
00248    TRUST_O_CLOEXEC.  */
00249 
00250 static void
00251 mark_cloexec (int fd)
00252 {
00253 #ifdef HAVE_F_GETFD
00254   int old = fcntl (fd, F_GETFD, 0);
00255 
00256   if (old != -1)
00257     {
00258       fcntl (fd, F_SETFD, old | FD_CLOEXEC);
00259 
00260       if (trust_o_cloexec == 0)
00261         {
00262           if ((old & FD_CLOEXEC) != 0)
00263             trust_o_cloexec = 1;
00264           else
00265             trust_o_cloexec = -1;
00266         }
00267     }
00268 #endif /* HAVE_F_GETFD */
00269 }
00270 
00271 /* Depending on TRUST_O_CLOEXEC, mark FD as close-on-exec.  */
00272 
00273 static void
00274 maybe_mark_cloexec (int fd)
00275 {
00276   if (trust_o_cloexec <= 0)
00277     mark_cloexec (fd);
00278 }
00279 
00280 #ifdef HAVE_SOCKETS
00281 
00282 /* Like maybe_mark_cloexec, but for callers that use SOCK_CLOEXEC.  */
00283 
00284 static void
00285 socket_mark_cloexec (int fd)
00286 {
00287   if (SOCK_CLOEXEC == 0 || trust_o_cloexec <= 0)
00288     mark_cloexec (fd);
00289 }
00290 
00291 #endif
00292 
00293 
00294 
00295 /* See filestuff.h.  */
00296 
00297 int
00298 gdb_open_cloexec (const char *filename, int flags, unsigned long mode)
00299 {
00300   int fd = open (filename, flags | O_CLOEXEC, mode);
00301 
00302   if (fd >= 0)
00303     maybe_mark_cloexec (fd);
00304 
00305   return fd;
00306 }
00307 
00308 /* See filestuff.h.  */
00309 
00310 FILE *
00311 gdb_fopen_cloexec (const char *filename, const char *opentype)
00312 {
00313   FILE *result;
00314   /* Probe for "e" support once.  But, if we can tell the operating
00315      system doesn't know about close on exec mode "e" without probing,
00316      skip it.  E.g., the Windows runtime issues an "Invalid parameter
00317      passed to C runtime function" OutputDebugString warning for
00318      unknown modes.  Assume that if O_CLOEXEC is zero, then "e" isn't
00319      supported.  */
00320   static int fopen_e_ever_failed_einval = O_CLOEXEC == 0;
00321 
00322   if (!fopen_e_ever_failed_einval)
00323     {
00324       char *copy;
00325 
00326       copy = alloca (strlen (opentype) + 2);
00327       strcpy (copy, opentype);
00328       /* This is a glibc extension but we try it unconditionally on
00329          this path.  */
00330       strcat (copy, "e");
00331       result = fopen (filename, copy);
00332 
00333       if (result == NULL && errno == EINVAL)
00334         {
00335           result = fopen (filename, opentype);
00336           if (result != NULL)
00337             fopen_e_ever_failed_einval = 1;
00338         }
00339     }
00340   else
00341     result = fopen (filename, opentype);
00342 
00343   if (result != NULL)
00344     maybe_mark_cloexec (fileno (result));
00345 
00346   return result;
00347 }
00348 
00349 #ifdef HAVE_SOCKETS
00350 /* See filestuff.h.  */
00351 
00352 int
00353 gdb_socketpair_cloexec (int namespace, int style, int protocol, int filedes[2])
00354 {
00355 #ifdef HAVE_SOCKETPAIR
00356   int result = socketpair (namespace, style | SOCK_CLOEXEC, protocol, filedes);
00357 
00358   if (result != -1)
00359     {
00360       socket_mark_cloexec (filedes[0]);
00361       socket_mark_cloexec (filedes[1]);
00362     }
00363 
00364   return result;
00365 #else
00366   gdb_assert_not_reached (_("socketpair not available on this host"));
00367 #endif
00368 }
00369 
00370 /* See filestuff.h.  */
00371 
00372 int
00373 gdb_socket_cloexec (int namespace, int style, int protocol)
00374 {
00375   int result = socket (namespace, style | SOCK_CLOEXEC, protocol);
00376 
00377   if (result != -1)
00378     socket_mark_cloexec (result);
00379 
00380   return result;
00381 }
00382 #endif
00383 
00384 /* See filestuff.h.  */
00385 
00386 int
00387 gdb_pipe_cloexec (int filedes[2])
00388 {
00389   int result;
00390 
00391 #ifdef HAVE_PIPE2
00392   result = pipe2 (filedes, O_CLOEXEC);
00393   if (result != -1)
00394     {
00395       maybe_mark_cloexec (filedes[0]);
00396       maybe_mark_cloexec (filedes[1]);
00397     }
00398 #else
00399 #ifdef HAVE_PIPE
00400   result = pipe (filedes);
00401   if (result != -1)
00402     {
00403       mark_cloexec (filedes[0]);
00404       mark_cloexec (filedes[1]);
00405     }
00406 #else /* HAVE_PIPE */
00407   gdb_assert_not_reached (_("pipe not available on this host"));
00408 #endif /* HAVE_PIPE */
00409 #endif /* HAVE_PIPE2 */
00410 
00411   return result;
00412 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines