windows/msvc: Implement file/directory type query.

Add some more POSIX compatibility by adding a d_type field to the
dirent structure and defining corresponding macros so listdir_next
in the unix' port modos.c can use it, end result being uos.ilistdir
now reports the file type.
This commit is contained in:
stijn 2018-10-04 12:46:06 +02:00 committed by Damien George
parent 397ee7c00e
commit 02ca8d4674
2 changed files with 21 additions and 0 deletions

View File

@ -25,6 +25,7 @@
*/ */
#include "dirent.h" #include "dirent.h"
#include "extmod/vfs.h"
#include <errno.h> #include <errno.h>
#include <Windows.h> #include <Windows.h>
@ -96,8 +97,22 @@ struct dirent *readdir(DIR *dir) {
// first pass d_name is NULL so use result from FindFirstFile in opendir, else use FindNextFile // first pass d_name is NULL so use result from FindFirstFile in opendir, else use FindNextFile
if (!dir->result.d_name || FindNextFile(dir->findHandle, &dir->findData)) { if (!dir->result.d_name || FindNextFile(dir->findHandle, &dir->findData)) {
dir->result.d_name = dir->findData.cFileName; dir->result.d_name = dir->findData.cFileName;
dir->result.d_type = dir->findData.dwFileAttributes;
return &dir->result; return &dir->result;
} }
return NULL; return NULL;
} }
int dttoif(int d_type) {
if (d_type == INVALID_FILE_ATTRIBUTES) {
return 0;
}
// Could be a couple of things (symlink, junction, ...) and non-trivial to
// figure out so just report it as unknown. Should we ever want this then
// the proper code can be found in msvc's std::filesystem implementation.
if (d_type & FILE_ATTRIBUTE_REPARSE_POINT) {
return 0;
}
return (d_type & FILE_ATTRIBUTE_DIRECTORY) ? MP_S_IFDIR : MP_S_IFREG;
}

View File

@ -31,18 +31,24 @@
// for ino_t // for ino_t
#include <sys/types.h> #include <sys/types.h>
#define _DIRENT_HAVE_D_TYPE (1)
#define DTTOIF dttoif
// opaque DIR structure // opaque DIR structure
typedef struct DIR DIR; typedef struct DIR DIR;
// the dirent structure // the dirent structure
// d_ino is always 0 - if ever needed use GetFileInformationByHandle // d_ino is always 0 - if ever needed use GetFileInformationByHandle
// d_type can be converted using DTTOIF, into 0 (unknown) or MP_S_IFDIR or MP_S_IFREG
typedef struct dirent { typedef struct dirent {
ino_t d_ino; ino_t d_ino;
int d_type;
char *d_name; char *d_name;
} dirent; } dirent;
DIR *opendir(const char *name); DIR *opendir(const char *name);
int closedir(DIR *dir); int closedir(DIR *dir);
struct dirent *readdir(DIR *dir); struct dirent *readdir(DIR *dir);
int dttoif(int d_type);
#endif // MICROPY_INCLUDED_WINDOWS_MSVC_DIRENT_H #endif // MICROPY_INCLUDED_WINDOWS_MSVC_DIRENT_H