Blame lib/readdir.c

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