LCOV - code coverage report
Current view: top level - common - closefrom.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core r Lines: 0 23 0.0 %
Date: 2011-08-21 Functions: 0 1 0.0 %
Branches: 0 30 0.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file closefrom.cc
       2                 :            :  * @brief Implementation of closefrom() function.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2010,2011 Olly Betts
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 2 of the License, or
       9                 :            :  * (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This program is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this program; if not, write to the Free Software
      18                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      19                 :            :  */
      20                 :            : 
      21                 :            : #include <config.h>
      22                 :            : 
      23                 :            : // We don't currently need closefrom() on __WIN32__.
      24                 :            : #if !defined HAVE_CLOSEFROM && !defined __WIN32__
      25                 :            : 
      26                 :            : #include "closefrom.h"
      27                 :            : 
      28                 :            : #include "safeerrno.h"
      29                 :            : #include "safefcntl.h"
      30                 :            : #include "safeunistd.h"
      31                 :            : 
      32                 :            : #if defined __linux__ || defined __APPLE__
      33                 :            : # include "safedirent.h"
      34                 :            : # include <cstdlib>
      35                 :            : 
      36                 :            : using namespace std;
      37                 :            : #endif
      38                 :            : 
      39                 :            : void
      40                 :          0 : Xapian::Internal::closefrom(int fd)
      41                 :            : {
      42                 :            : #ifdef F_CLOSEM
      43                 :            :     // Apparently supported by at least NetBSD, AIX, IRIX.
      44                 :            :     if (fcntl(fd, F_CLOSEM, 0) >= 0)
      45                 :            :         return;
      46                 :            : #elif defined __linux__ || defined __APPLE__
      47                 :            :     // The loop might close the fd associated with dir if we don't take
      48                 :            :     // special care to avoid that by either skipping this fd in the closing
      49                 :            :     // loop (if dirfd() is available) or making sure we have a free fd below
      50                 :            :     // the first we close in the loop.
      51                 :            : #if !defined HAVE_DIRFD && !defined dirfd
      52                 :            :     // Make sure that the lowest fd we have been asked to close is closed, and
      53                 :            :     // then raise this lower bound - this should ensure that opendir() gets
      54                 :            :     // an fd below the new lower bound.
      55                 :            :     while (close(fd) < 0 && errno == EINTR) { }
      56                 :            :     ++fd;
      57                 :            : #endif
      58                 :            : #if 0
      59                 :            :     // Some platforms (e.g. AIX) have /proc/<pid>/fd but not /proc/self - if
      60                 :            :     // any such platforms don't have either closefrom() or F_CLOSEM then this
      61                 :            :     // code can be used.
      62                 :            :     string path = "/proc/";
      63                 :            :     path += str(getpid());
      64                 :            :     path += "/fd";
      65                 :            :     DIR * dir = opendir(path.c_str());
      66                 :            : #elif defined __linux__
      67                 :          0 :     DIR * dir = opendir("/proc/self/fd");
      68                 :            : #elif defined __APPLE__ // Mac OS X
      69                 :            :     DIR * dir = opendir("/dev/fd");
      70                 :            : #endif
      71         [ #  # ]:          0 :     if (dir) {
      72                 :          0 :         while (true) {
      73                 :          0 :             errno = 0;
      74                 :          0 :             struct dirent *entry = readdir(dir);
      75         [ #  # ]:          0 :             if (entry == NULL) {
      76                 :          0 :                 closedir(dir);
      77                 :            :                 // Fallback if readdir() or closedir() fails.
      78         [ #  # ]:          0 :                 if (errno) break;
      79                 :          0 :                 return;
      80                 :            :             }
      81                 :            :             char ch;
      82                 :          0 :             ch = entry->d_name[0];
      83 [ #  # ][ #  # ]:          0 :             if (ch < '0' || ch > '9')
      84                 :          0 :                 continue;
      85                 :          0 :             int n = atoi(entry->d_name);
      86         [ #  # ]:          0 :             if (n >= fd) {
      87                 :            : #if defined HAVE_DIRFD || defined dirfd
      88         [ #  # ]:          0 :                 if (n == dirfd(dir)) continue;
      89                 :            : #endif
      90                 :            :                 // Retry on EINTR.
      91 [ #  # ][ #  # ]:          0 :                 while (close(n) < 0 && errno == EINTR) { }
                 [ #  # ]
      92                 :            :             }
      93                 :            :         }
      94                 :            :     }
      95                 :            : #endif
      96                 :          0 :     int maxfd = -1;
      97                 :            : #ifdef F_MAXFD
      98                 :            :     maxfd = fcntl(0, F_MAXFD);
      99                 :            : #endif
     100         [ #  # ]:          0 :     if (maxfd < 0)
     101                 :          0 :         maxfd = static_cast<int>(sysconf(_SC_OPEN_MAX));
     102         [ #  # ]:          0 :     while (fd < maxfd) {
     103                 :            :         // Retry on EINTR; just ignore other errors (we'll get EBADF if fd
     104                 :            :         // isn't open so that's OK).
     105 [ #  # ][ #  # ]:          0 :         while (close(fd) < 0 && errno == EINTR) { }
                 [ #  # ]
     106                 :          0 :         ++fd;
     107                 :            :     }
     108                 :            : }
     109                 :            : 
     110                 :            : #endif

Generated by: LCOV version 1.8