"Fossies" - the Fresh Open Source Software Archive

Member "CSSC-1.4.1/gl/lib/opendir.c" (7 Feb 2016, 3745 Bytes) of package /linux/privat/CSSC-1.4.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "opendir.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.4.0_vs_1.4.1.

    1 /* Start reading the entries of a directory.
    2    Copyright (C) 2006-2016 Free Software Foundation, Inc.
    3 
    4    This program is free software: you can redistribute it and/or modify
    5    it under the terms of the GNU General Public License as published by
    6    the Free Software Foundation; either version 3 of the License, or
    7    (at your option) any later version.
    8 
    9    This program is distributed in the hope that it will be useful,
   10    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12    GNU General Public License for more details.
   13 
   14    You should have received a copy of the GNU General Public License
   15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   16 
   17 #include <config.h>
   18 
   19 /* Specification.  */
   20 #include <dirent.h>
   21 
   22 #include <errno.h>
   23 #include <stddef.h>
   24 
   25 #if HAVE_OPENDIR
   26 
   27 /* Override opendir(), to keep track of the open file descriptors.
   28    Needed because there is a function dirfd().  */
   29 
   30 #else
   31 
   32 # include <stdlib.h>
   33 
   34 # include "dirent-private.h"
   35 # include "filename.h"
   36 
   37 #endif
   38 
   39 #if REPLACE_FCHDIR
   40 # include <unistd.h>
   41 #endif
   42 
   43 #ifdef __KLIBC__
   44 # include <io.h>
   45 # include <fcntl.h>
   46 #endif
   47 
   48 DIR *
   49 opendir (const char *dir_name)
   50 {
   51 #if HAVE_OPENDIR
   52 # undef opendir
   53   DIR *dirp;
   54 
   55   dirp = opendir (dir_name);
   56   if (dirp == NULL)
   57     return NULL;
   58 
   59 # ifdef __KLIBC__
   60   {
   61     int fd = open (dir_name, O_RDONLY);
   62     if (fd == -1 || _gl_register_dirp_fd (fd, dirp))
   63       {
   64         int saved_errno = errno;
   65 
   66         close (fd);
   67         closedir (dirp);
   68 
   69         errno = saved_errno;
   70 
   71         return NULL;
   72       }
   73   }
   74 # endif
   75 #else
   76 
   77   char dir_name_mask[MAX_PATH + 1 + 1 + 1];
   78   int status;
   79   HANDLE current;
   80   WIN32_FIND_DATA entry;
   81   struct gl_directory *dirp;
   82 
   83   if (dir_name[0] == '\0')
   84     {
   85       errno = ENOENT;
   86       return NULL;
   87     }
   88 
   89   /* Make the dir_name absolute, so that we continue reading the same
   90      directory if the current directory changed between this opendir()
   91      call and a subsequent rewinddir() call.  */
   92   if (!GetFullPathName (dir_name, MAX_PATH, dir_name_mask, NULL))
   93     {
   94       errno = EINVAL;
   95       return NULL;
   96     }
   97 
   98   /* Append the mask.
   99      "*" and "*.*" appear to be equivalent.  */
  100   {
  101     char *p;
  102 
  103     p = dir_name_mask + strlen (dir_name_mask);
  104     if (p > dir_name_mask && !ISSLASH (p[-1]))
  105       *p++ = '\\';
  106     *p++ = '*';
  107     *p = '\0';
  108   }
  109 
  110   /* Start searching the directory.  */
  111   status = -1;
  112   current = FindFirstFile (dir_name_mask, &entry);
  113   if (current == INVALID_HANDLE_VALUE)
  114     {
  115       switch (GetLastError ())
  116         {
  117         case ERROR_FILE_NOT_FOUND:
  118           status = -2;
  119           break;
  120         case ERROR_PATH_NOT_FOUND:
  121           errno = ENOENT;
  122           return NULL;
  123         case ERROR_DIRECTORY:
  124           errno = ENOTDIR;
  125           return NULL;
  126         case ERROR_ACCESS_DENIED:
  127           errno = EACCES;
  128           return NULL;
  129         default:
  130           errno = EIO;
  131           return NULL;
  132         }
  133     }
  134 
  135   /* Allocate the result.  */
  136   dirp =
  137     (struct gl_directory *)
  138     malloc (offsetof (struct gl_directory, dir_name_mask[0])
  139             + strlen (dir_name_mask) + 1);
  140   if (dirp == NULL)
  141     {
  142       if (current != INVALID_HANDLE_VALUE)
  143         FindClose (current);
  144       errno = ENOMEM;
  145       return NULL;
  146     }
  147   dirp->status = status;
  148   dirp->current = current;
  149   if (status == -1)
  150     memcpy (&dirp->entry, &entry, sizeof (WIN32_FIND_DATA));
  151   strcpy (dirp->dir_name_mask, dir_name_mask);
  152 
  153 #endif
  154 
  155 #if REPLACE_FCHDIR
  156   {
  157     int fd = dirfd (dirp);
  158     if (0 <= fd && _gl_register_fd (fd, dir_name) != fd)
  159       {
  160         int saved_errno = errno;
  161         closedir (dirp);
  162         errno = saved_errno;
  163         return NULL;
  164       }
  165   }
  166 #endif
  167 
  168   return dirp;
  169 }