Blame lib/readdir.c

Packit 709fb3
/* Read the next entry of a directory.
Packit 709fb3
   Copyright (C) 2011-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
   This program is free software: you can redistribute it and/or modify
Packit 709fb3
   it under the terms of the GNU General Public License as published by
Packit 709fb3
   the Free Software Foundation; either version 3 of the License, or
Packit 709fb3
   (at your option) any later version.
Packit 709fb3
Packit 709fb3
   This program is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
   GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public License
Packit 709fb3
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
#include <config.h>
Packit 709fb3
Packit 709fb3
/* Specification.  */
Packit 709fb3
#include <dirent.h>
Packit 709fb3
Packit 709fb3
#include <errno.h>
Packit 709fb3
#include <stddef.h>
Packit 709fb3
Packit 709fb3
#include "dirent-private.h"
Packit 709fb3
Packit 709fb3
struct dirent *
Packit 709fb3
readdir (DIR *dirp)
Packit 709fb3
{
Packit 709fb3
  char type;
Packit 709fb3
  struct dirent *result;
Packit 709fb3
Packit 709fb3
  /* There is no need to add code to produce entries for "." and "..".
Packit 709fb3
     According to the POSIX:2008 section "4.12 Pathname Resolution"
Packit 709fb3
     <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html>
Packit 709fb3
     "." and ".." are syntactic entities.
Packit 709fb3
     POSIX also says:
Packit 709fb3
       "If entries for dot or dot-dot exist, one entry shall be returned
Packit 709fb3
        for dot and one entry shall be returned for dot-dot; otherwise,
Packit 709fb3
        they shall not be returned."  */
Packit 709fb3
Packit 709fb3
  switch (dirp->status)
Packit 709fb3
    {
Packit 709fb3
    case -2:
Packit 709fb3
      /* End of directory already reached.  */
Packit 709fb3
      return NULL;
Packit 709fb3
    case -1:
Packit 709fb3
      break;
Packit 709fb3
    case 0:
Packit 709fb3
      if (!FindNextFile (dirp->current, &dirp->entry))
Packit 709fb3
        {
Packit 709fb3
          switch (GetLastError ())
Packit 709fb3
            {
Packit 709fb3
            case ERROR_NO_MORE_FILES:
Packit 709fb3
              dirp->status = -2;
Packit 709fb3
              return NULL;
Packit 709fb3
            default:
Packit 709fb3
              errno = EIO;
Packit 709fb3
              return NULL;
Packit 709fb3
            }
Packit 709fb3
        }
Packit 709fb3
      break;
Packit 709fb3
    default:
Packit 709fb3
      errno = dirp->status;
Packit 709fb3
      return NULL;
Packit 709fb3
    }
Packit 709fb3
Packit 709fb3
  dirp->status = 0;
Packit 709fb3
Packit 709fb3
  if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
Packit 709fb3
    type = DT_DIR;
Packit 709fb3
  else if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
Packit 709fb3
    type = DT_LNK;
Packit 709fb3
  else if ((dirp->entry.dwFileAttributes
Packit 709fb3
            & ~(FILE_ATTRIBUTE_READONLY
Packit 709fb3
                | FILE_ATTRIBUTE_HIDDEN
Packit 709fb3
                | FILE_ATTRIBUTE_SYSTEM
Packit 709fb3
                | FILE_ATTRIBUTE_ARCHIVE
Packit 709fb3
                | FILE_ATTRIBUTE_NORMAL
Packit 709fb3
                | FILE_ATTRIBUTE_TEMPORARY
Packit 709fb3
                | FILE_ATTRIBUTE_SPARSE_FILE
Packit 709fb3
                | FILE_ATTRIBUTE_COMPRESSED
Packit 709fb3
                | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
Packit 709fb3
                | FILE_ATTRIBUTE_ENCRYPTED)) == 0)
Packit 709fb3
    /* Devices like COM1, LPT1, NUL would also have the attributes 0x20 but
Packit 709fb3
       they cannot occur here.  */
Packit 709fb3
    type = DT_REG;
Packit 709fb3
  else
Packit 709fb3
    type = DT_UNKNOWN;
Packit 709fb3
Packit 709fb3
  /* Reuse the memory of dirp->entry for the result.  */
Packit 709fb3
  result =
Packit 709fb3
    (struct dirent *)
Packit 709fb3
    ((char *) dirp->entry.cFileName - offsetof (struct dirent, d_name[0]));
Packit 709fb3
  result->d_type = type;
Packit 709fb3
Packit 709fb3
  return result;
Packit 709fb3
}