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.
This commit is contained in:
Saúl Ibarra Corretgé 2014-08-14 22:18:28 +02:00
parent ab2c4425a5
commit df8ab507a0
6 changed files with 87 additions and 12 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);