diff --git a/js/common/bootstrap/module-fs.js b/js/common/bootstrap/module-fs.js index a4f916c9f7..9ac6dcca1d 100644 --- a/js/common/bootstrap/module-fs.js +++ b/js/common/bootstrap/module-fs.js @@ -401,6 +401,14 @@ if (global.FS_MTIME) { delete global.FS_MTIME; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief copy one file +//////////////////////////////////////////////////////////////////////////////// + +if (global.FS_COPY_FILE) { + exports.copyFile = global.FS_COPY_FILE; + delete global.FS_COPY_FILE; +} //////////////////////////////////////////////////////////////////////////////// /// @brief copy recursive diff --git a/js/server/modules/org/arangodb/testing.js b/js/server/modules/org/arangodb/testing.js index e20228b5b3..7c32240c95 100644 --- a/js/server/modules/org/arangodb/testing.js +++ b/js/server/modules/org/arangodb/testing.js @@ -475,13 +475,6 @@ function readImportantLogLines(logPath) { return importantLines; } -function copy (src, dst) { - var fs = require("fs"); - var buffer = fs.readBuffer(src); - - fs.write(dst, buffer); -} - function analyzeCoreDump(instanceInfo, options, storeArangodPath, pid) { var command; command = '('; @@ -523,13 +516,13 @@ function checkInstanceAlive(instanceInfo, options) { storeArangodPath + " " + options.coreDirectory + "/core*" + instanceInfo.pid.pid + "*'"; if (require("internal").platform.substr(0,3) === 'win') { - copy("bin\\arangod.exe", instanceInfo.tmpDataDir + "\\arangod.exe"); - copy("bin\\arangod.pdb", instanceInfo.tmpDataDir + "\\arangod.pdb"); + fs.copyFile("bin\\arangod.exe", instanceInfo.tmpDataDir + "\\arangod.exe"); + fs.copyFile("bin\\arangod.pdb", instanceInfo.tmpDataDir + "\\arangod.pdb"); // Windows: wait for procdump to do its job... statusExternal(instanceInfo.monitor, true); } else { - copy("bin/arangod", storeArangodPath); + fs.copyFile("bin/arangod", storeArangodPath); analyzeCoreDump(instanceInfo, options, storeArangodPath, instanceInfo.pid.pid); } } @@ -557,13 +550,13 @@ function checkInstanceAlive(instanceInfo, options) { " /var/tmp/core*" + checkpid.pid + "*'"; if (require("internal").platform.substr(0,3) === 'win') { - copy("bin\\arangod.exe", instanceInfo.tmpDataDir + "\\arangod.exe"); - copy("bin\\arangod.pdb", instanceInfo.tmpDataDir + "\\arangod.pdb"); + fs.copyFile("bin\\arangod.exe", instanceInfo.tmpDataDir + "\\arangod.exe"); + fs.copyFile("bin\\arangod.pdb", instanceInfo.tmpDataDir + "\\arangod.pdb"); // Windows: wait for procdump to do its job... statusExternal(instanceInfo.monitor, true); } else { - copy("bin/arangod", storeArangodPath); + fs.copyFile("bin/arangod", storeArangodPath); analyzeCoreDump(instanceInfo, options, storeArangodPath, checkpid.pid); } diff --git a/lib/V8/v8-utils.cpp b/lib/V8/v8-utils.cpp index a2fd234751..de070ace27 100644 --- a/lib/V8/v8-utils.cpp +++ b/lib/V8/v8-utils.cpp @@ -2168,7 +2168,7 @@ static void JS_MoveFile (const v8::FunctionCallbackInfo& args) { //////////////////////////////////////////////////////////////////////////////// /// @brief copies a directory structure /// @startDocuBlock JS_CopyDirectoryRecursive -/// `fs.xcopy(source, destination)` +/// `fs.copyRecursive(source, destination)` /// /// Copies *source* to destination. Failure to copy the file, or /// specifying a directory for destination when source is a file will throw an @@ -2183,7 +2183,7 @@ static void JS_CopyRecursive (const v8::FunctionCallbackInfo& args) { // extract two arguments if (args.Length() != 2) { - TRI_V8_THROW_EXCEPTION_USAGE("xcopy(, )"); + TRI_V8_THROW_EXCEPTION_USAGE("copyRecursive(, )"); } string source = TRI_ObjectToString(args[0]); @@ -2233,6 +2233,61 @@ static void JS_CopyRecursive (const v8::FunctionCallbackInfo& args) { TRI_V8_RETURN_UNDEFINED(); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief copies a file into a target file +/// @startDocuBlock JS_CopyFile +/// `fs.copyRecursive(source, destination)` +/// +/// Copies *source* to destination. If Destination is a directory, a file +/// of the same name will be created, else it will be the name of the new file. +/// @endDocuBlock +//////////////////////////////////////////////////////////////////////////////// + +static void JS_CopyFile (const v8::FunctionCallbackInfo& args) { + v8::Isolate* isolate = args.GetIsolate(); + v8::HandleScope scope(isolate); + + // extract two arguments + if (args.Length() != 2) { + TRI_V8_THROW_EXCEPTION_USAGE("copyFile(, )"); + } + + string source = TRI_ObjectToString(args[0]); + string destination = TRI_ObjectToString(args[1]); + + bool const destinationIsDirectory = TRI_IsDirectory(destination.c_str()); + + if (! TRI_IsRegularFile(source.c_str())) { + TRI_V8_THROW_EXCEPTION_PARAMETER("can only copy regular files."); + } + + std::string systemErrorStr; + + if (destinationIsDirectory) { + const char* file = strrchr(source.c_str(), TRI_DIR_SEPARATOR_CHAR); + if (file == nullptr) { + if (destination[destination.length()] == TRI_DIR_SEPARATOR_CHAR) { + destination += TRI_DIR_SEPARATOR_CHAR; + } + destination += source; + } + else { + destination += file; + } + } + if (!TRI_CopyFile(source, destination, systemErrorStr)) { + std::string errMsg = "cannot copy file [" + + source + + "] to [" + + destination + + " ] : " + + systemErrorStr; + TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, errMsg); + } + + TRI_V8_RETURN_UNDEFINED(); +} + //////////////////////////////////////////////////////////////////////////////// @@ -4414,6 +4469,7 @@ void TRI_InitV8Utils (v8::Isolate* isolate, TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("FS_MAKE_DIRECTORY_RECURSIVE"), JS_MakeDirectoryRecursive); TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("FS_MOVE"), JS_MoveFile); TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("FS_COPY_RECURSIVE"), JS_CopyRecursive); + TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("FS_COPY_FILE"), JS_CopyFile); TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("FS_MTIME"), JS_MTime); TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("FS_REMOVE"), JS_Remove);