Bring inline with node common.gypi.
Win32 readlink()
This commit is contained in:
parent
060026ced3
commit
7db243dc6f
102
common.gypi
102
common.gypi
@ -1,5 +1,6 @@
|
||||
{
|
||||
'variables': {
|
||||
'visibility%': 'hidden', # V8's visibility setting
|
||||
'target_arch%': 'ia32', # set v8's target architecture
|
||||
'host_arch%': 'ia32', # set v8's host architecture
|
||||
'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
|
||||
@ -87,6 +88,11 @@
|
||||
'DataExecutionPrevention': 2, # enable DEP
|
||||
'AllowIsolation': 'true',
|
||||
'SuppressStartupBanner': 'true',
|
||||
'target_conditions': [
|
||||
['_type=="executable"', {
|
||||
'SubSystem': 1, # console executable
|
||||
}],
|
||||
],
|
||||
},
|
||||
},
|
||||
'conditions': [
|
||||
@ -103,61 +109,55 @@
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
|
||||
'target_defaults': {
|
||||
'cflags': [ '-Wall', '-pthread', '-fno-rtti', '-fno-exceptions' ],
|
||||
'ldflags': [ '-pthread', ],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32"', {
|
||||
'cflags': [ '-m32' ],
|
||||
'ldflags': [ '-m32' ],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
'cflags': [ '-ansi' ],
|
||||
}],
|
||||
[ 'visibility=="hidden"', {
|
||||
'cflags': [ '-fvisibility=hidden' ],
|
||||
}],
|
||||
],
|
||||
},
|
||||
'cflags': [ '-Wall', '-pthread', ],
|
||||
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
|
||||
'ldflags': [ '-pthread', ],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32"', {
|
||||
'cflags': [ '-m32' ],
|
||||
'ldflags': [ '-m32' ],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
'cflags': [ '-ansi' ],
|
||||
}],
|
||||
[ 'visibility=="hidden"', {
|
||||
'cflags': [ '-fvisibility=hidden' ],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
['OS=="mac"', {
|
||||
'target_defaults': {
|
||||
'xcode_settings': {
|
||||
'ALWAYS_SEARCH_USER_PATHS': 'NO',
|
||||
'GCC_C_LANGUAGE_STANDARD': 'ansi', # -ansi
|
||||
'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
|
||||
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
|
||||
# (Equivalent to -fPIC)
|
||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
|
||||
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
|
||||
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
|
||||
# GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
|
||||
'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
|
||||
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
|
||||
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
|
||||
'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES', # -Werror
|
||||
'GCC_VERSION': '4.2',
|
||||
'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4
|
||||
'PREBINDING': 'NO', # No -Wl,-prebind
|
||||
'USE_HEADERMAP': 'NO',
|
||||
'OTHER_CFLAGS': [
|
||||
'-fno-strict-aliasing',
|
||||
],
|
||||
'WARNING_CFLAGS': [
|
||||
'-Wall',
|
||||
'-Wendif-labels',
|
||||
'-W',
|
||||
'-Wno-unused-parameter',
|
||||
'-Wnon-virtual-dtor',
|
||||
],
|
||||
},
|
||||
'target_conditions': [
|
||||
['_type!="static_library"', {
|
||||
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
|
||||
}],
|
||||
'xcode_settings': {
|
||||
'ALWAYS_SEARCH_USER_PATHS': 'NO',
|
||||
'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
|
||||
'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
|
||||
# (Equivalent to -fPIC)
|
||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
|
||||
'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
|
||||
'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
|
||||
# GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
|
||||
'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
|
||||
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
|
||||
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
|
||||
'GCC_VERSION': '4.2',
|
||||
'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4
|
||||
'PREBINDING': 'NO', # No -Wl,-prebind
|
||||
'USE_HEADERMAP': 'NO',
|
||||
'OTHER_CFLAGS': [
|
||||
'-fno-strict-aliasing',
|
||||
],
|
||||
'WARNING_CFLAGS': [
|
||||
'-Wall',
|
||||
'-Wendif-labels',
|
||||
'-W',
|
||||
'-Wno-unused-parameter',
|
||||
],
|
||||
},
|
||||
'target_conditions': [
|
||||
['_type!="static_library"', {
|
||||
'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
||||
94
src/win/fs.c
94
src/win/fs.c
@ -430,15 +430,93 @@ void fs__symlink(uv_fs_t* req, const char* path, const char* new_path,
|
||||
|
||||
void fs__readlink(uv_fs_t* req, const char* path) {
|
||||
int result = -1;
|
||||
assert(0 && "implement me");
|
||||
BOOL rv;
|
||||
HANDLE symlink;
|
||||
void* buffer;
|
||||
DWORD bytes_returned;
|
||||
REPARSE_DATA_BUFFER* reparse_data;
|
||||
int utf8size;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
symlink = CreateFileA(path,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
|
||||
if (INVALID_HANDLE_VALUE == symlink) {
|
||||
result = -1;
|
||||
SET_REQ_LAST_ERROR(req, GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
||||
if (!buffer) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
rv = DeviceIoControl(symlink,
|
||||
FSCTL_GET_REPARSE_POINT,
|
||||
NULL,
|
||||
0,
|
||||
buffer,
|
||||
MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
|
||||
&bytes_returned,
|
||||
NULL);
|
||||
|
||||
if (!rv) {
|
||||
result = -1;
|
||||
SET_REQ_LAST_ERROR(req, GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
reparse_data = buffer;
|
||||
if (reparse_data->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
|
||||
result = -1;
|
||||
/* something is seriously wrong */
|
||||
SET_REQ_LAST_ERROR(req, GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
utf8size = uv_utf16_to_utf8(reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)),
|
||||
reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t),
|
||||
NULL,
|
||||
0);
|
||||
if (!utf8size) {
|
||||
result = -1;
|
||||
SET_REQ_LAST_ERROR(req, GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
req->ptr = malloc(utf8size + 1);
|
||||
if (!req->ptr) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
req->flags |= UV_FS_FREE_PTR;
|
||||
|
||||
utf8size = uv_utf16_to_utf8(reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)),
|
||||
reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t),
|
||||
req->ptr,
|
||||
utf8size);
|
||||
if (!utf8size) {
|
||||
result = -1;
|
||||
SET_REQ_LAST_ERROR(req, GetLastError());
|
||||
goto done;
|
||||
}
|
||||
|
||||
((char*)req->ptr)[utf8size] = '\0';
|
||||
result = 0;
|
||||
|
||||
done:
|
||||
if (buffer) {
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
if (symlink != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(symlink);
|
||||
}
|
||||
|
||||
SET_REQ_RESULT(req, result);
|
||||
}
|
||||
|
||||
@ -4075,6 +4075,33 @@
|
||||
(FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_ERROR)))
|
||||
#endif
|
||||
|
||||
/* from ntifs.h */
|
||||
typedef struct _REPARSE_DATA_BUFFER {
|
||||
ULONG ReparseTag;
|
||||
USHORT ReparseDataLength;
|
||||
USHORT Reserved;
|
||||
union {
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
ULONG Flags;
|
||||
WCHAR PathBuffer[1];
|
||||
} SymbolicLinkReparseBuffer;
|
||||
struct {
|
||||
USHORT SubstituteNameOffset;
|
||||
USHORT SubstituteNameLength;
|
||||
USHORT PrintNameOffset;
|
||||
USHORT PrintNameLength;
|
||||
WCHAR PathBuffer[1];
|
||||
} MountPointReparseBuffer;
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
} DUMMYUNIONNAME;
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
NTSTATUS Status;
|
||||
|
||||
@ -65,6 +65,7 @@ static int chown_cb_count;
|
||||
static int fchown_cb_count;
|
||||
static int link_cb_count;
|
||||
static int symlink_cb_count;
|
||||
static int readlink_cb_count;
|
||||
|
||||
static uv_loop_t* loop;
|
||||
|
||||
@ -127,6 +128,13 @@ static void symlink_cb(uv_fs_t* req) {
|
||||
uv_fs_req_cleanup(req);
|
||||
}
|
||||
|
||||
static void readlink_cb(uv_fs_t* req) {
|
||||
ASSERT(req->fs_type == UV_FS_READLINK);
|
||||
ASSERT(req->result == 0);
|
||||
ASSERT(strcmp(req->ptr, "test_file_symlink2") == 0);
|
||||
readlink_cb_count++;
|
||||
uv_fs_req_cleanup(req);
|
||||
}
|
||||
|
||||
static void fchmod_cb(uv_fs_t* req) {
|
||||
ASSERT(req->fs_type == UV_FS_FCHMOD);
|
||||
@ -936,6 +944,8 @@ TEST_IMPL(fs_symlink) {
|
||||
unlink("test_file");
|
||||
unlink("test_file_symlink");
|
||||
unlink("test_file_symlink2");
|
||||
unlink("test_file_symlink_symlink");
|
||||
unlink("test_file_symlink2_symlink");
|
||||
|
||||
uv_init();
|
||||
|
||||
@ -992,6 +1002,13 @@ TEST_IMPL(fs_symlink) {
|
||||
|
||||
close(link);
|
||||
|
||||
r = uv_fs_symlink(loop, &req, "test_file_symlink", "test_file_symlink_symlink", 0, NULL);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fs_readlink(loop, &req, "test_file_symlink_symlink", NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* async link */
|
||||
r = uv_fs_symlink(loop, &req, "test_file", "test_file_symlink2", 0, symlink_cb);
|
||||
ASSERT(r == 0);
|
||||
@ -1012,6 +1029,13 @@ TEST_IMPL(fs_symlink) {
|
||||
|
||||
close(link);
|
||||
|
||||
r = uv_fs_symlink(loop, &req, "test_file_symlink2", "test_file_symlink2_symlink", 0, NULL);
|
||||
ASSERT(r == 0);
|
||||
r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb);
|
||||
ASSERT(r == 0);
|
||||
uv_run(loop);
|
||||
ASSERT(readlink_cb_count == 1);
|
||||
|
||||
/*
|
||||
* Run the loop just to check we don't have make any extraneous uv_ref()
|
||||
* calls. This should drop out immediately.
|
||||
@ -1021,7 +1045,9 @@ TEST_IMPL(fs_symlink) {
|
||||
/* Cleanup. */
|
||||
unlink("test_file");
|
||||
unlink("test_file_symlink");
|
||||
unlink("test_file_symlink_symlink");
|
||||
unlink("test_file_symlink2");
|
||||
unlink("test_file_symlink2_symlink");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user