Home | History | Annotate | Line # | Download | only in import
      1      1.1  christos /* Read the next entry of a directory.
      2  1.1.1.2  christos    Copyright (C) 2011-2022 Free Software Foundation, Inc.
      3      1.1  christos 
      4  1.1.1.2  christos    This file is free software: you can redistribute it and/or modify
      5  1.1.1.2  christos    it under the terms of the GNU Lesser General Public License as
      6  1.1.1.2  christos    published by the Free Software Foundation; either version 2.1 of the
      7  1.1.1.2  christos    License, or (at your option) any later version.
      8      1.1  christos 
      9  1.1.1.2  christos    This file is distributed in the hope that it will be useful,
     10      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     11      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  1.1.1.2  christos    GNU Lesser General Public License for more details.
     13      1.1  christos 
     14  1.1.1.2  christos    You should have received a copy of the GNU Lesser General Public License
     15      1.1  christos    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
     16      1.1  christos 
     17      1.1  christos #include <config.h>
     18      1.1  christos 
     19      1.1  christos /* Specification.  */
     20      1.1  christos #include <dirent.h>
     21      1.1  christos 
     22      1.1  christos #include <errno.h>
     23      1.1  christos #include <stddef.h>
     24      1.1  christos 
     25      1.1  christos #include "dirent-private.h"
     26      1.1  christos 
     27      1.1  christos /* Don't assume that UNICODE is not defined.  */
     28      1.1  christos #undef FindNextFile
     29      1.1  christos #define FindNextFile FindNextFileA
     30      1.1  christos 
     31      1.1  christos struct dirent *
     32      1.1  christos readdir (DIR *dirp)
     33      1.1  christos {
     34      1.1  christos   char type;
     35      1.1  christos   struct dirent *result;
     36      1.1  christos 
     37      1.1  christos   /* There is no need to add code to produce entries for "." and "..".
     38      1.1  christos      According to the POSIX:2008 section "4.12 Pathname Resolution"
     39      1.1  christos      <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html>
     40      1.1  christos      "." and ".." are syntactic entities.
     41      1.1  christos      POSIX also says:
     42      1.1  christos        "If entries for dot or dot-dot exist, one entry shall be returned
     43      1.1  christos         for dot and one entry shall be returned for dot-dot; otherwise,
     44      1.1  christos         they shall not be returned."  */
     45      1.1  christos 
     46      1.1  christos   switch (dirp->status)
     47      1.1  christos     {
     48      1.1  christos     case -2:
     49      1.1  christos       /* End of directory already reached.  */
     50      1.1  christos       return NULL;
     51      1.1  christos     case -1:
     52      1.1  christos       break;
     53      1.1  christos     case 0:
     54      1.1  christos       if (!FindNextFile (dirp->current, &dirp->entry))
     55      1.1  christos         {
     56      1.1  christos           switch (GetLastError ())
     57      1.1  christos             {
     58      1.1  christos             case ERROR_NO_MORE_FILES:
     59      1.1  christos               dirp->status = -2;
     60      1.1  christos               return NULL;
     61      1.1  christos             default:
     62      1.1  christos               errno = EIO;
     63      1.1  christos               return NULL;
     64      1.1  christos             }
     65      1.1  christos         }
     66      1.1  christos       break;
     67      1.1  christos     default:
     68      1.1  christos       errno = dirp->status;
     69      1.1  christos       return NULL;
     70      1.1  christos     }
     71      1.1  christos 
     72      1.1  christos   dirp->status = 0;
     73      1.1  christos 
     74      1.1  christos   if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     75      1.1  christos     type = DT_DIR;
     76      1.1  christos   else if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
     77      1.1  christos     type = DT_LNK;
     78      1.1  christos   else if ((dirp->entry.dwFileAttributes
     79      1.1  christos             & ~(FILE_ATTRIBUTE_READONLY
     80      1.1  christos                 | FILE_ATTRIBUTE_HIDDEN
     81      1.1  christos                 | FILE_ATTRIBUTE_SYSTEM
     82      1.1  christos                 | FILE_ATTRIBUTE_ARCHIVE
     83      1.1  christos                 | FILE_ATTRIBUTE_NORMAL
     84      1.1  christos                 | FILE_ATTRIBUTE_TEMPORARY
     85      1.1  christos                 | FILE_ATTRIBUTE_SPARSE_FILE
     86      1.1  christos                 | FILE_ATTRIBUTE_COMPRESSED
     87      1.1  christos                 | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
     88      1.1  christos                 | FILE_ATTRIBUTE_ENCRYPTED)) == 0)
     89      1.1  christos     /* Devices like COM1, LPT1, NUL would also have the attributes 0x20 but
     90      1.1  christos        they cannot occur here.  */
     91      1.1  christos     type = DT_REG;
     92      1.1  christos   else
     93      1.1  christos     type = DT_UNKNOWN;
     94      1.1  christos 
     95      1.1  christos   /* Reuse the memory of dirp->entry for the result.  */
     96      1.1  christos   result =
     97      1.1  christos     (struct dirent *)
     98      1.1  christos     ((char *) dirp->entry.cFileName - offsetof (struct dirent, d_name[0]));
     99      1.1  christos   result->d_type = type;
    100      1.1  christos 
    101      1.1  christos   return result;
    102      1.1  christos }
    103