Home | History | Annotate | Line # | Download | only in import
readdir.c revision 1.1
      1  1.1  christos /* Read the next entry of a directory.
      2  1.1  christos    Copyright (C) 2011-2020 Free Software Foundation, Inc.
      3  1.1  christos 
      4  1.1  christos    This program is free software: you can redistribute it and/or modify
      5  1.1  christos    it under the terms of the GNU General Public License as published by
      6  1.1  christos    the Free Software Foundation; either version 3 of the License, or
      7  1.1  christos    (at your option) any later version.
      8  1.1  christos 
      9  1.1  christos    This program 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  christos    GNU General Public License for more details.
     13  1.1  christos 
     14  1.1  christos    You should have received a copy of the GNU 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