diff --git a/src/node.h b/src/node.h index 05e3f7535f4ce7..3692060263ed37 100644 --- a/src/node.h +++ b/src/node.h @@ -91,6 +91,14 @@ #define NODE_STRINGIFY_HELPER(n) #n #endif +#ifndef STATIC_ASSERT +#if defined(_MSC_VER) +# define STATIC_ASSERT(expr) static_assert(expr, "") +# else +# define STATIC_ASSERT(expr) static_cast((sizeof(char[-1 + !!(expr)]))) +# endif +#endif + namespace node { int Start(int argc, char *argv[]); diff --git a/src/node_file.cc b/src/node_file.cc index 645f44532bd2e9..0c0555e7e22631 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -40,7 +40,6 @@ # include #endif - namespace node { using namespace v8; @@ -68,10 +67,41 @@ static Persistent buf_symbol; static Persistent oncomplete_sym; -#ifdef _LARGEFILE_SOURCE -static inline int IsInt64(double x) { - return x == static_cast(static_cast(x)); -} +#ifndef _LARGEFILE_SOURCE + typedef off_t node_off_t; +# define ASSERT_OFFSET(a) \ + STATIC_ASSERT(sizeof(node_off_t) * CHAR_BIT >= 32); \ + if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsInt32()) { \ + return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ + } +# define ASSERT_TRUNCATE_LENGTH(a) \ + if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsUint32()) { \ + return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ + } +# define GET_OFFSET(a) ((a)->IsNumber() ? (a)->Int32Value() : -1) +# define GET_TRUNCATE_LENGTH(a) ((a)->Uint32Value()) +#else +# ifdef _WIN32 +# define NODE_USE_64BIT_UV_FS_API + typedef int64_t node_off_t; +# else + typedef off_t node_off_t; +# endif +# define ASSERT_OFFSET(a) \ + STATIC_ASSERT(sizeof(node_off_t) * CHAR_BIT >= 64); \ + if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ + return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ + } +# define ASSERT_TRUNCATE_LENGTH(a) \ + if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ + return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ + } +# define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1) +# define GET_TRUNCATE_LENGTH(a) ((a)->IntegerValue()) + + static inline int IsInt64(double x) { + return x == static_cast(static_cast(x)); + } #endif @@ -470,20 +500,6 @@ static Handle Rename(const Arguments& args) { } } -#ifndef _LARGEFILE_SOURCE -#define ASSERT_TRUNCATE_LENGTH(a) \ - if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsUint32()) { \ - return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ - } -#define GET_TRUNCATE_LENGTH(a) ((a)->Uint32Value()) -#else -#define ASSERT_TRUNCATE_LENGTH(a) \ - if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ - return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ - } -#define GET_TRUNCATE_LENGTH(a) ((a)->IntegerValue()) -#endif - static Handle Truncate(const Arguments& args) { HandleScope scope; @@ -494,12 +510,20 @@ static Handle Truncate(const Arguments& args) { int fd = args[0]->Int32Value(); ASSERT_TRUNCATE_LENGTH(args[1]); - off_t len = GET_TRUNCATE_LENGTH(args[1]); + node_off_t len = GET_TRUNCATE_LENGTH(args[1]); if (args[2]->IsFunction()) { +#ifdef NODE_USE_64BIT_UV_FS_API + ASYNC_CALL(ftruncate64, args[2], fd, len) +#else ASYNC_CALL(ftruncate, args[2], fd, len) +#endif } else { +#ifdef NODE_USE_64BIT_UV_FS_API + SYNC_CALL(ftruncate64, 0, fd, len) +#else SYNC_CALL(ftruncate, 0, fd, len) +#endif return Undefined(); } } @@ -671,20 +695,6 @@ static Handle Open(const Arguments& args) { } } -#ifndef _LARGEFILE_SOURCE -#define ASSERT_OFFSET(a) \ - if (!(a)->IsUndefined() && !(a)->IsNull() && !(a)->IsInt32()) { \ - return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ - } -#define GET_OFFSET(a) ((a)->IsNumber() ? (a)->Int32Value() : -1) -#else -#define ASSERT_OFFSET(a) \ - if (!(a)->IsUndefined() && !(a)->IsNull() && !IsInt64((a)->NumberValue())) { \ - return ThrowException(Exception::TypeError(String::New("Not an integer"))); \ - } -#define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1) -#endif - // bytesWritten = write(fd, data, position, enc, callback) // Wrapper for write(2). // @@ -725,15 +735,23 @@ static Handle Write(const Arguments& args) { } ASSERT_OFFSET(args[4]); - off_t pos = GET_OFFSET(args[4]); + node_off_t pos = GET_OFFSET(args[4]); char * buf = (char*)buffer_data + off; Local cb = args[5]; if (cb->IsFunction()) { +#ifdef NODE_USE_64BIT_UV_FS_API + ASYNC_CALL(write64, cb, fd, buf, len, pos) +#else ASYNC_CALL(write, cb, fd, buf, len, pos) +#endif } else { +#ifdef NODE_USE_64BIT_UV_FS_API + SYNC_CALL(write64, 0, fd, buf, len, pos) +#else SYNC_CALL(write, 0, fd, buf, len, pos) +#endif return scope.Close(Integer::New(SYNC_RESULT)); } } @@ -762,7 +780,7 @@ static Handle Read(const Arguments& args) { Local cb; size_t len; - off_t pos; + node_off_t pos; char * buf = NULL; @@ -794,9 +812,17 @@ static Handle Read(const Arguments& args) { cb = args[5]; if (cb->IsFunction()) { +#ifdef NODE_USE_64BIT_UV_FS_API + ASYNC_CALL(read64, cb, fd, buf, len, pos); +#else ASYNC_CALL(read, cb, fd, buf, len, pos); +#endif } else { +#ifdef NODE_USE_64BIT_UV_FS_API + SYNC_CALL(read64, 0, fd, buf, len, pos) +#else SYNC_CALL(read, 0, fd, buf, len, pos) +#endif Local bytesRead = Integer::New(SYNC_RESULT); return scope.Close(bytesRead); }