root/maint/gnulib/lib/readdir.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. readdir

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

/* [previous][next][first][last][top][bottom][index][help] */