From df8ab507a06a501f5ea16760d7c8de6928b4ce74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Thu, 14 Aug 2014 22:18:28 +0200 Subject: [PATCH] fs: extend reported types in uv_fs_readdir_next Support all possible types on Unix, and files, directories and links on Windows. Some systems (hello SunOS!) don't have the d_type field on struct dirent, so mark them as UV_DIRENT_UNKNOWN. --- include/uv-unix.h | 39 ++++++++++++++++++++++++++++++++++++++- include/uv-win.h | 9 +++++++-- include/uv.h | 8 +++++++- src/uv-common.c | 33 +++++++++++++++++++++++++++++---- src/win/fs.c | 2 ++ test/test-fs.c | 8 ++++---- 6 files changed, 87 insertions(+), 12 deletions(-) diff --git a/include/uv-unix.h b/include/uv-unix.h index 2a1ead5b..f66e4941 100644 --- a/include/uv-unix.h +++ b/include/uv-unix.h @@ -158,7 +158,44 @@ typedef uid_t uv_uid_t; typedef struct dirent uv__dirent_t; -#define UV__DT_DIR DT_DIR +#if defined(DT_UNKNOWN) +# define HAVE_DIRENT_TYPES +# if defined(DT_REG) +# define UV__DT_FILE DT_REG +# else +# define UV__DT_FILE -1 +# endif +# if defined(DT_DIR) +# define UV__DT_DIR DT_DIR +# else +# define UV__DT_DIR -2 +# endif +# if defined(DT_LNK) +# define UV__DT_LINK DT_LNK +# else +# define UV__DT_LINK -3 +# endif +# if defined(DT_FIFO) +# define UV__DT_FIFO DT_FIFO +# else +# define UV__DT_FIFO -4 +# endif +# if defined(DT_SOCK) +# define UV__DT_SOCKET DT_SOCK +# else +# define UV__DT_SOCKET -5 +# endif +# if defined(DT_CHR) +# define UV__DT_CHAR DT_CHR +# else +# define UV__DT_CHAR -6 +# endif +# if defined(DT_BLK) +# define UV__DT_BLOCK DT_BLK +# else +# define UV__DT_BLOCK -7 +# endif +#endif /* Platform-specific definitions for uv_dlopen support. */ #define UV_DYNAMIC /* empty */ diff --git a/include/uv-win.h b/include/uv-win.h index 116d67f6..48fa020a 100644 --- a/include/uv-win.h +++ b/include/uv-win.h @@ -294,8 +294,13 @@ typedef struct uv__dirent_s { char d_name[1]; } uv__dirent_t; -#define UV__DT_DIR UV_DIRENT_DIR -#define UV__DT_FILE UV_DIRENT_FILE +#define UV__DT_DIR UV_DIRENT_DIR +#define UV__DT_FILE UV_DIRENT_FILE +#define UV__DT_LINK UV_DIRENT_LINK +#define UV__DT_FIFO UV_DIRENT_FIFO +#define UV__DT_SOCKET UV_DIRENT_SOCKET +#define UV__DT_CHAR UV_DIRENT_CHAR +#define UV__DT_BLOCK UV_DIRENT_BLOCK /* Platform-specific definitions for uv_dlopen support. */ #define UV_DYNAMIC FAR WINAPI diff --git a/include/uv.h b/include/uv.h index 221d5d03..730aa151 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1788,8 +1788,14 @@ struct uv_interface_address_s { }; typedef enum { + UV_DIRENT_UNKNOWN, UV_DIRENT_FILE, - UV_DIRENT_DIR + UV_DIRENT_DIR, + UV_DIRENT_LINK, + UV_DIRENT_FIFO, + UV_DIRENT_SOCKET, + UV_DIRENT_CHAR, + UV_DIRENT_BLOCK } uv_dirent_type_t; struct uv_dirent_s { diff --git a/src/uv-common.c b/src/uv-common.c index e2307aa0..aaee9305 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -482,10 +482,35 @@ int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent) { dent = dents[req->nbufs++]; ent->name = dent->d_name; - if (dent->d_type == UV__DT_DIR) - ent->type = UV_DIRENT_DIR; - else - ent->type = UV_DIRENT_FILE; +#ifdef HAVE_DIRENT_TYPES + switch (dent->d_type) { + case UV__DT_DIR: + ent->type = UV_DIRENT_DIR; + break; + case UV__DT_FILE: + ent->type = UV_DIRENT_FILE; + break; + case UV__DT_LINK: + ent->type = UV_DIRENT_LINK; + break; + case UV__DT_FIFO: + ent->type = UV_DIRENT_FIFO; + break; + case UV__DT_SOCKET: + ent->type = UV_DIRENT_SOCKET; + break; + case UV__DT_CHAR: + ent->type = UV_DIRENT_CHAR; + break; + case UV__DT_BLOCK: + ent->type = UV_DIRENT_BLOCK; + break; + default: + ent->type = UV_DIRENT_UNKNOWN; + } +#else + ent->type = UV_DIRENT_UNKNOWN; +#endif return 0; } diff --git a/src/win/fs.c b/src/win/fs.c index f1835b0b..d3801460 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -877,6 +877,8 @@ void fs__readdir(uv_fs_t* req) { /* Copy file type */ if ((ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) dent->d_type = UV__DT_DIR; + else if ((ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) + dent->d_type = UV__DT_LINK; else dent->d_type = UV__DT_FILE; diff --git a/test/test-fs.c b/test/test-fs.c index 38bc3e03..a06ddada 100644 --- a/test/test-fs.c +++ b/test/test-fs.c @@ -425,7 +425,7 @@ static void readdir_cb(uv_fs_t* req) { while (UV_EOF != uv_fs_readdir_next(req, &dent)) { ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - ASSERT(dent.type == UV_DIRENT_FILE); + ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); } readdir_cb_count++; ASSERT(req->path); @@ -851,7 +851,7 @@ TEST_IMPL(fs_async_dir) { ASSERT(readdir_req.ptr); while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) { ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - ASSERT(dent.type == UV_DIRENT_FILE); + ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); } uv_fs_req_cleanup(&readdir_req); ASSERT(!readdir_req.ptr); @@ -1607,7 +1607,7 @@ TEST_IMPL(fs_symlink_dir) { ASSERT(readdir_req.ptr); while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) { ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - ASSERT(dent.type == UV_DIRENT_FILE); + ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); } uv_fs_req_cleanup(&readdir_req); ASSERT(!readdir_req.ptr); @@ -1627,7 +1627,7 @@ TEST_IMPL(fs_symlink_dir) { ASSERT(readdir_req.ptr); while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) { ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); - ASSERT(dent.type == UV_DIRENT_FILE); + ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); } uv_fs_req_cleanup(&readdir_req); ASSERT(!readdir_req.ptr);