Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
windows: uv_fs_link + uv_fs_symlink
  • Loading branch information
Igor Zinkovsky committed Sep 4, 2011
1 parent 6422a14 commit df38443
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 9 deletions.
4 changes: 3 additions & 1 deletion include/uv.h
Expand Up @@ -894,6 +894,8 @@ struct uv_fs_s {
UV_FS_PRIVATE_FIELDS
};

#define UV_FS_SYMLINK_DIR 0x0001

void uv_fs_req_cleanup(uv_fs_t* req);

int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
Expand Down Expand Up @@ -949,7 +951,7 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);

int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);
const char* new_path, int flags, uv_fs_cb cb);

int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb);
Expand Down
2 changes: 1 addition & 1 deletion src/unix/fs.c
Expand Up @@ -490,7 +490,7 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,


int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
const char* new_path, int flags, uv_fs_cb cb) {
WRAP_EIO(UV_FS_SYMLINK, eio_symlink, symlink, ARGS2(path, new_path))
}

Expand Down
101 changes: 94 additions & 7 deletions src/win/fs.c
Expand Up @@ -22,6 +22,7 @@
#include <assert.h>
#include <malloc.h>
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -187,6 +188,7 @@ void fs__readdir(uv_fs_t* req, const char* path, int flags) {

if(dir == INVALID_HANDLE_VALUE) {
result = -1;
uv_set_sys_error(req->loop, GetLastError());
goto done;
}

Expand Down Expand Up @@ -267,6 +269,9 @@ void fs__rename(uv_fs_t* req, const char* path, const char* new_path) {

void fs__fsync(uv_fs_t* req, uv_file file) {
int result = FlushFileBuffers((HANDLE)_get_osfhandle(file)) ? 0 : -1;
if (result == -1) {
uv_set_sys_error(req->loop, GetLastError());
}
SET_REQ_RESULT(req, result);
}

Expand Down Expand Up @@ -383,6 +388,50 @@ void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) {
}


void fs__link(uv_fs_t* req, const char* path, const char* new_path) {
int result = CreateHardLinkA(new_path, path, NULL) ? 0 : -1;
if (result == -1) {
uv_set_sys_error(req->loop, GetLastError());
}
SET_REQ_RESULT(req, result);
}


void fs__symlink(uv_fs_t* req, const char* path, const char* new_path,
int flags) {
int result;
if (pCreateSymbolicLinkA) {
result = pCreateSymbolicLinkA(new_path,
path,
flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
if (result == -1) {
uv_set_sys_error(req->loop, GetLastError());
}
} else {
result = -1;
errno = ENOTSUP;
}

SET_REQ_RESULT(req, result);
}


void fs__readlink(uv_fs_t* req, const char* path) {
int result = -1;
assert(0 && "implement me");

/* TODO: the link path must be returned in a req->ptr buffer,
* which need to be alloce'd here.
* Just do this (it'll take care of freeing the buffer).
* req->ptr = malloc(...);
* req->flags |= UV_FS_FREE_PTR;
* Also result needs to contain the length of the string.
*/

SET_REQ_RESULT(req, result);
}


void fs__nop(uv_fs_t* req) {
req->result = 0;
}
Expand Down Expand Up @@ -464,6 +513,15 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
case UV_FS_FUTIME:
fs__futime(req, (uv_file)req->arg0, req->arg4, req->arg5);
break;
case UV_FS_LINK:
fs__link(req, (const char*)req->arg0, (const char*)req->arg1);
break;
case UV_FS_SYMLINK:
fs__symlink(req, (const char*)req->arg0, (const char*)req->arg1, (int)req->arg2);
break;
case UV_FS_READLINK:
fs__readlink(req, (const char*)req->arg0);
break;
case UV_FS_CHOWN:
case UV_FS_FCHOWN:
fs__nop(req);
Expand Down Expand Up @@ -603,22 +661,51 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,

int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
if (cb) {
uv_fs_req_init_async(loop, req, UV_FS_LINK, cb);
WRAP_REQ_ARGS2(req, path, new_path);
STRDUP_ARG(req, 0);
STRDUP_ARG(req, 1);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(loop, req, UV_FS_LINK);
fs__link(req, path, new_path);
}

return 0;
}


int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
const char* new_path, int flags, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(loop, req, UV_FS_SYMLINK, cb);
WRAP_REQ_ARGS3(req, path, new_path, flags);
STRDUP_ARG(req, 0);
STRDUP_ARG(req, 1);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(loop, req, UV_FS_SYMLINK);
fs__symlink(req, path, new_path, flags);
}

return 0;
}


int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
if (cb) {
uv_fs_req_init_async(loop, req, UV_FS_READLINK, cb);
WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(loop, req, UV_FS_READLINK);
fs__readlink(req, path);
}

return 0;
}


Expand Down
4 changes: 4 additions & 0 deletions src/win/winapi.c
Expand Up @@ -31,6 +31,7 @@ sNtQueryInformationFile pNtQueryInformationFile;
sNtSetInformationFile pNtSetInformationFile;
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
sCreateSymbolicLinkA pCreateSymbolicLinkA;


void uv_winapi_init() {
Expand Down Expand Up @@ -74,4 +75,7 @@ void uv_winapi_init() {

pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes)
GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes");

pCreateSymbolicLinkA = (sCreateSymbolicLinkA)
GetProcAddress(kernel32_module, "CreateSymbolicLinkA");
}
8 changes: 8 additions & 0 deletions src/win/winapi.h
Expand Up @@ -4186,6 +4186,8 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
#define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2

#define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1

#ifdef __MINGW32__
typedef struct _OVERLAPPED_ENTRY {
ULONG_PTR lpCompletionKey;
Expand All @@ -4207,6 +4209,11 @@ typedef BOOL (WINAPI* sSetFileCompletionNotificationModes)
(HANDLE FileHandle,
UCHAR Flags);

typedef BOOLEAN (WINAPI* sCreateSymbolicLinkA)
(LPCSTR lpSymlinkFileName,
LPCSTR lpTargetFileName,
DWORD dwFlags);


/* Ntapi function pointers */
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
Expand All @@ -4217,5 +4224,6 @@ extern sNtSetInformationFile pNtSetInformationFile;
/* Kernel32 function pointers */
extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
extern sCreateSymbolicLinkA pCreateSymbolicLinkA;

#endif /* UV_WIN_WINAPI_H_ */

0 comments on commit df38443

Please sign in to comment.