GDB (API)
|
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 }