Skip to content

Commit

Permalink
fs: uv_fs_{open,read,close}_dir
Browse files Browse the repository at this point in the history
This is the same changes as joyent/libuv#1574.
This commit is just the start of getting them to work in libuv/libuv.

Failing tests will be fixed asap.

Fixes libuv#170.
  • Loading branch information
Julien Gilli committed Jan 30, 2015
1 parent 5a52cc1 commit e0a2fd5
Show file tree
Hide file tree
Showing 11 changed files with 1,090 additions and 21 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Expand Up @@ -158,6 +158,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-fs-event.c \
test/test-fs-poll.c \
test/test-fs.c \
test/test-fs-readdir.c \
test/test-get-currentexe.c \
test/test-get-loadavg.c \
test/test-get-memory.c \
Expand Down
7 changes: 7 additions & 0 deletions include/uv-unix.h
Expand Up @@ -158,6 +158,13 @@ typedef gid_t uv_gid_t;
typedef uid_t uv_uid_t;

typedef struct dirent uv__dirent_t;
/*
* "dirent" is used to hold a buffer large enough for any dirent in the
* directory being read. Avoids allocating for each directory entry.
*/
#define UV_DIR_PRIVATE_FIELDS \
uv__dirent_t* dirent; \
DIR* dir;

#if defined(DT_UNKNOWN)
# define HAVE_DIRENT_TYPES
Expand Down
23 changes: 23 additions & 0 deletions include/uv-win.h
Expand Up @@ -294,6 +294,29 @@ typedef struct uv__dirent_s {
char d_name[1];
} uv__dirent_t;

/*
* "handle" is the actual directory handle that is used to perform calls
* to FindFirstFile/FindNextFile.
*
* "find_data" is needed to store the result of the FindFirstFile call that
* happened in uv_fs_opendir so that it can be used in the subsequent
* uv_fs_readdir call.
*
* "need_find_call" is a boolean determining if the next call to uv_fs_readdir
* must call FindNextFile. In uv_fs_opendir, FindFirstFile reads the first
* entry of the directory, and thus the subsequent call to uv_fs_readdir must
* not call FindNextFile, or otherwise it would miss the first directory entry.
* The next uv_fs_readdir calls after the first one will use FindNextFile.
*
* "dirent" is used to hold a buffer large enough for any dirent in the
* directory being read. It avoids allocating for each directory entry.
*/
#define UV_DIR_PRIVATE_FIELDS \
HANDLE dir_handle; \
WIN32_FIND_DATAW find_data; \
BOOL need_find_call; \
uv__dirent_t* dirent;

#define UV__DT_DIR UV_DIRENT_DIR
#define UV__DT_FILE UV_DIRENT_FILE
#define UV__DT_LINK UV_DIRENT_LINK
Expand Down
27 changes: 27 additions & 0 deletions include/uv.h
Expand Up @@ -197,6 +197,7 @@ typedef enum {
/* Handle types. */
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_dir_s uv_dir_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
typedef struct uv_udp_s uv_udp_t;
Expand Down Expand Up @@ -1060,13 +1061,20 @@ typedef enum {
UV_FS_MKDTEMP,
UV_FS_RENAME,
UV_FS_SCANDIR,
UV_FS_OPENDIR,
UV_FS_READDIR,
UV_FS_CLOSEDIR,
UV_FS_LINK,
UV_FS_SYMLINK,
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN
} uv_fs_type;

struct uv_dir_s {
UV_DIR_PRIVATE_FIELDS
};

/* uv_fs_t is a subclass of uv_req_t. */
struct uv_fs_s {
UV_REQ_FIELDS
Expand All @@ -1077,6 +1085,9 @@ struct uv_fs_s {
void* ptr;
const char* path;
uv_stat_t statbuf; /* Stores the result of uv_fs_stat() and uv_fs_fstat(). */
const uv_dir_t* dir; /* Stores the result of uv_fs_opendir() */
uv_dirent_t* dirents;
size_t nentries;
UV_FS_PRIVATE_FIELDS
};

Expand Down Expand Up @@ -1129,6 +1140,22 @@ UV_EXTERN int uv_fs_scandir(uv_loop_t* loop,
uv_fs_cb cb);
UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req,
uv_dirent_t* ent);

UV_EXTERN int uv_fs_opendir(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_fs_cb cb);
UV_EXTERN int uv_fs_readdir(uv_loop_t* loop,
uv_fs_t* req,
const uv_dir_t* dir,
uv_dirent_t dirents[],
size_t nentries,
uv_fs_cb cb);
UV_EXTERN int uv_fs_closedir(uv_loop_t* loop,
uv_fs_t* req,
const uv_dir_t* dir,
uv_fs_cb cb);

UV_EXTERN int uv_fs_stat(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
Expand Down

0 comments on commit e0a2fd5

Please sign in to comment.