mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
0b0d4c5dd7
|
@ -19,7 +19,7 @@
|
|||
COLOR_BOLD_MAGENTA, PRETTY_PRINT, VALGRIND, VERSION, UPGRADE,
|
||||
BYTES_SENT_DISTRIBUTION, BYTES_RECEIVED_DISTRIBUTION, CONNECTION_TIME_DISTRIBUTION,
|
||||
REQUEST_TIME_DISTRIBUTION, DEVELOPMENT_MODE, THREAD_NUMBER, LOGFILE_PATH,
|
||||
SYS_PLATFORM */
|
||||
SYS_PLATFORM, SYS_EXECUTE_EXTERNAL, SYS_STATUS_EXTERNAL, SYS_KILL_EXTERNAL */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief module "internal"
|
||||
|
@ -662,6 +662,33 @@
|
|||
delete SYS_HTTP_STATISTICS;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_EXECUTE_EXTERNAL !== "undefined") {
|
||||
exports.executeExternal = SYS_EXECUTE_EXTERNAL;
|
||||
delete SYS_EXECUTE_EXTERNAL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief kills an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_KILL_EXTERNAL !== "undefined") {
|
||||
exports.killExternal = SYS_KILL_EXTERNAL;
|
||||
delete SYS_KILL_EXTERNAL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks a status of an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof SYS_STATUS_EXTERNAL !== "undefined") {
|
||||
exports.statusExternal = SYS_STATUS_EXTERNAL;
|
||||
delete SYS_STATUS_EXTERNAL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -42,17 +42,13 @@
|
|||
#endif
|
||||
|
||||
#include "BasicsC/tri-strings.h"
|
||||
#include "BasicsC/locks.h"
|
||||
#include "BasicsC/logging.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief contains all data documented by "proc"
|
||||
///
|
||||
|
@ -124,19 +120,10 @@ process_state_t;
|
|||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief original process name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -178,18 +165,142 @@ static bool MustFreeEnvironment = false;
|
|||
static size_t MaximalProcessTitleSize = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief all external processes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_vector_pointer_t ExternalProcesses;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief lock for protected access to vector ExternalProcesses
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_mutex_t ExternalProcessesLock;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates pipe pair
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool CreatePipes (int* pipe_server_to_child,
|
||||
int* pipe_child_to_server) {
|
||||
|
||||
if (pipe(pipe_server_to_child) == -1) {
|
||||
LOG_ERROR("cannot create pipe");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pipe(pipe_child_to_server) == -1) {
|
||||
LOG_ERROR("cannot create pipe");
|
||||
|
||||
close(pipe_server_to_child[0]);
|
||||
close(pipe_server_to_child[1]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief starts external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void StartExternalProcess (TRI_external_t* external, bool usePipes) {
|
||||
int pipe_server_to_child[2];
|
||||
int pipe_child_to_server[2];
|
||||
int processPid;
|
||||
bool ok;
|
||||
|
||||
if (usePipes) {
|
||||
ok = CreatePipes(pipe_server_to_child, pipe_child_to_server);
|
||||
|
||||
if (! ok) {
|
||||
external->_status = TRI_EXT_PIPE_FAILED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
processPid = fork();
|
||||
|
||||
// child process
|
||||
if (processPid == 0) {
|
||||
|
||||
// set stdin and stdout of child process
|
||||
if (usePipes) {
|
||||
dup2(pipe_server_to_child[0], 0);
|
||||
dup2(pipe_child_to_server[1], 1);
|
||||
|
||||
fcntl(0, F_SETFD, 0);
|
||||
fcntl(1, F_SETFD, 0);
|
||||
fcntl(2, F_SETFD, 0);
|
||||
|
||||
// close pipes
|
||||
close(pipe_server_to_child[0]);
|
||||
close(pipe_server_to_child[1]);
|
||||
close(pipe_child_to_server[0]);
|
||||
close(pipe_child_to_server[1]);
|
||||
}
|
||||
else {
|
||||
close(0);
|
||||
fcntl(1, F_SETFD, 0);
|
||||
fcntl(2, F_SETFD, 0);
|
||||
}
|
||||
|
||||
// ignore signals in worker process
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
|
||||
// execute worker
|
||||
execv(external->_executable, external->_arguments);
|
||||
|
||||
// should not happen
|
||||
LOG_ERROR("execution of '%s' failed with %d", external->_executable, errno);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// parent
|
||||
if (processPid == -1) {
|
||||
LOG_ERROR("fork failed");
|
||||
|
||||
if (usePipes) {
|
||||
close(pipe_server_to_child[0]);
|
||||
close(pipe_server_to_child[1]);
|
||||
close(pipe_child_to_server[0]);
|
||||
close(pipe_child_to_server[1]);
|
||||
}
|
||||
|
||||
external->_status = TRI_EXT_FORK_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("fork succeeded %d", processPid);
|
||||
|
||||
if (usePipes) {
|
||||
close(pipe_server_to_child[0]);
|
||||
close(pipe_child_to_server[1]);
|
||||
|
||||
external->_writePipe = pipe_server_to_child[1];
|
||||
external->_readPipe = pipe_child_to_server[0];
|
||||
}
|
||||
else {
|
||||
external->_writePipe = -1;
|
||||
external->_readPipe = -1;
|
||||
}
|
||||
|
||||
external->_pid = processPid;
|
||||
external->_status = TRI_EXT_RUNNING;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts usec and sec into seconds
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -472,22 +583,148 @@ void TRI_SetProcessTitle (char const* title) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief starts an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_external_id_t TRI_CreateExternalProcess (const char* executable,
|
||||
const char** arguments,
|
||||
size_t n) {
|
||||
TRI_external_t* external;
|
||||
TRI_external_id_t pid;
|
||||
size_t i;
|
||||
|
||||
// create the external structure
|
||||
external = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(TRI_external_t), true);
|
||||
|
||||
external->_executable = TRI_DuplicateString(executable);
|
||||
external->_numberArguments = n;
|
||||
|
||||
external->_arguments = TRI_Allocate(TRI_CORE_MEM_ZONE, (n + 2) * sizeof(char*), true);
|
||||
external->_arguments[0] = TRI_DuplicateString(executable);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
external->_arguments[i + 1] = TRI_DuplicateString(arguments[i]);
|
||||
}
|
||||
|
||||
external->_arguments[n + 1] = NULL;
|
||||
external->_status = TRI_EXT_NOT_STARTED;
|
||||
|
||||
StartExternalProcess(external, false);
|
||||
|
||||
TRI_LockMutex(&ExternalProcessesLock);
|
||||
TRI_PushBackVectorPointer(&ExternalProcesses, external);
|
||||
pid = external->_pid;
|
||||
TRI_UnlockMutex(&ExternalProcessesLock);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the status of an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_external_status_t TRI_CheckExternalProcess (pid_t pid) {
|
||||
TRI_external_status_t status;
|
||||
TRI_external_t* external;
|
||||
int loc;
|
||||
int opts;
|
||||
pid_t res;
|
||||
size_t i;
|
||||
|
||||
TRI_LockMutex(&ExternalProcessesLock);
|
||||
|
||||
status._status = TRI_EXT_NOT_FOUND;
|
||||
status._exitStatus = 0;
|
||||
|
||||
for (i = 0; i < ExternalProcesses._length; ++i) {
|
||||
external = TRI_AtVectorPointer(&ExternalProcesses, i);
|
||||
|
||||
if (external->_pid == pid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ExternalProcesses._length) {
|
||||
TRI_UnlockMutex(&ExternalProcessesLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (external->_status == TRI_EXT_RUNNING || external->_status == TRI_EXT_STOPPED) {
|
||||
opts = WNOHANG | WUNTRACED;
|
||||
res = waitpid(external->_pid, &loc, opts);
|
||||
|
||||
if (res == 0) {
|
||||
external->_exitStatus = 0;
|
||||
}
|
||||
else if (WIFEXITED(loc)) {
|
||||
external->_status = TRI_EXT_TERMINATED;
|
||||
external->_exitStatus = WEXITSTATUS(loc);
|
||||
}
|
||||
else if (WIFSIGNALED(loc)) {
|
||||
external->_status = TRI_EXT_ABORTED;
|
||||
external->_exitStatus = 0;
|
||||
}
|
||||
else if (WIFSTOPPED(loc)) {
|
||||
external->_status = TRI_EXT_STOPPED;
|
||||
external->_exitStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
status._status = external->_status;
|
||||
status._exitStatus = external->_exitStatus;
|
||||
|
||||
TRI_UnlockMutex(&ExternalProcessesLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief kills an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_KillExternalProcess (pid_t pid) {
|
||||
TRI_external_t* external;
|
||||
size_t i;
|
||||
|
||||
TRI_LockMutex(&ExternalProcessesLock);
|
||||
|
||||
for (i = 0; i < ExternalProcesses._length; ++i) {
|
||||
external = TRI_AtVectorPointer(&ExternalProcesses, i);
|
||||
|
||||
if (external->_pid == pid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ExternalProcesses._length) {
|
||||
TRI_UnlockMutex(&ExternalProcessesLock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (external->_status == TRI_EXT_RUNNING || external->_status == TRI_EXT_STOPPED) {
|
||||
int val = kill(external->_pid , SIGKILL);
|
||||
|
||||
if (val) {
|
||||
external->_status = TRI_EXT_KILL_FAILED;
|
||||
}
|
||||
else {
|
||||
TRI_RemoveVectorPointer(&ExternalProcesses, i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRI_RemoveVectorPointer(&ExternalProcesses, i);
|
||||
}
|
||||
|
||||
TRI_UnlockMutex(&ExternalProcessesLock);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- MODULE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// --SECTION-- modules initialisation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialises the process components
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -500,10 +737,13 @@ void TRI_InitialiseProcess (int argc, char* argv[]) {
|
|||
ProcessName = TRI_DuplicateString(argv[0]);
|
||||
ARGC = argc;
|
||||
ARGV = argv;
|
||||
|
||||
TRI_InitVectorPointer(&ExternalProcesses, TRI_CORE_MEM_ZONE);
|
||||
TRI_InitMutex(&ExternalProcessesLock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief shut downs the process components
|
||||
/// @brief shuts down the process components
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_ShutdownProcess () {
|
||||
|
@ -523,11 +763,14 @@ void TRI_ShutdownProcess () {
|
|||
TRI_Free(TRI_CORE_MEM_ZONE, environ);
|
||||
}
|
||||
#endif
|
||||
|
||||
TRI_DestroyVectorPointer(&ExternalProcesses);
|
||||
TRI_DestroyMutex(&ExternalProcessesLock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
|
|
|
@ -40,30 +40,16 @@ extern "C" {
|
|||
// --SECTION-- public constants
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief invalid process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define INVALID_PROCESS (0)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public types
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns information about the process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -81,18 +67,61 @@ typedef struct TRI_process_info_s {
|
|||
TRI_process_info_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief status of an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef enum {
|
||||
TRI_EXT_NOT_STARTED = 0, // not yet started
|
||||
TRI_EXT_PIPE_FAILED = 1, // pipe before start failed
|
||||
TRI_EXT_FORK_FAILED = 2, // fork failed
|
||||
TRI_EXT_RUNNING = 3, // running
|
||||
TRI_EXT_NOT_FOUND = 4, // unknown pid
|
||||
TRI_EXT_TERMINATED = 5, // process has terminated normally
|
||||
TRI_EXT_ABORTED = 6, // process has terminated abnormally
|
||||
TRI_EXT_STOPPED = 7, // process has been stopped
|
||||
TRI_EXT_KILL_FAILED = 8, // kill failed
|
||||
}
|
||||
TRI_external_status_e;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief identifier of an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef pid_t TRI_external_id_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief external process description
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_external_s {
|
||||
char* _executable;
|
||||
size_t _numberArguments;
|
||||
char** _arguments;
|
||||
|
||||
TRI_external_id_t _pid;
|
||||
|
||||
int _readPipe;
|
||||
int _writePipe;
|
||||
|
||||
TRI_external_status_e _status;
|
||||
int _exitStatus;
|
||||
}
|
||||
TRI_external_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief external process status
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_external_status_s {
|
||||
TRI_external_status_e _status;
|
||||
int _exitStatus;
|
||||
}
|
||||
TRI_external_status_t;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts usec and sec into seconds
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -132,22 +161,33 @@ uint64_t TRI_ProcessSize (TRI_pid_t pid);
|
|||
void TRI_SetProcessTitle (char const* title);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
/// @brief starts an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_external_id_t TRI_CreateExternalProcess (const char* executable,
|
||||
const char** arguments,
|
||||
size_t n);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the status of an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_external_status_t TRI_CheckExternalProcess (pid_t pid);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief kills an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_KillExternalProcess (pid_t pid);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- MODULE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public functions
|
||||
// --SECTION-- modules initialisation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @addtogroup SystemProcess
|
||||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialises the process components
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -160,16 +200,16 @@ void TRI_InitialiseProcess (int argc, char* argv[]);
|
|||
|
||||
void TRI_ShutdownProcess (void);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
|
|
|
@ -458,6 +458,7 @@ static v8::Handle<v8::Value> JS_Download (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
v8::Handle<v8::Array> options = v8::Handle<v8::Array>::Cast(argv[2]);
|
||||
|
||||
if (options.IsEmpty()) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, signature);
|
||||
}
|
||||
|
@ -647,11 +648,12 @@ static v8::Handle<v8::Value> JS_Download (v8::Arguments const& argv) {
|
|||
map<string, string>::const_iterator it;
|
||||
|
||||
v8::Handle<v8::Object> headers = v8::Object::New();
|
||||
|
||||
for (it = responseHeaders.begin(); it != responseHeaders.end(); ++it) {
|
||||
headers->Set(v8::String::New((*it).first.c_str()), v8::String::New((*it).second.c_str()));
|
||||
}
|
||||
result->Set(v8::String::New("headers"), headers);
|
||||
|
||||
result->Set(v8::String::New("headers"), headers);
|
||||
|
||||
if (returnBodyOnError || (returnCode >= 200 && returnCode <= 299)) {
|
||||
try {
|
||||
|
@ -2360,6 +2362,136 @@ static v8::Handle<v8::Value> JS_HttpStatistics (v8::Arguments const& argv) {
|
|||
return scope.Close(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes a external program
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_ExecuteExternal (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
// extract the arguments
|
||||
if (2 < argv.Length() || argv.Length() < 1) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "executeExternal(<filename>, [<arguments>])");
|
||||
}
|
||||
|
||||
TRI_Utf8ValueNFC name(TRI_UNKNOWN_MEM_ZONE, argv[0]);
|
||||
|
||||
if (*name == 0) {
|
||||
TRI_V8_TYPE_ERROR(scope, "<filename> must be a string");
|
||||
}
|
||||
|
||||
char** arguments = 0;
|
||||
size_t n = 0;
|
||||
|
||||
if (2 <= argv.Length()) {
|
||||
v8::Handle<v8::Value> a = argv[1];
|
||||
|
||||
if (a->IsArray()) {
|
||||
v8::Handle<v8::Array> arr = v8::Handle<v8::Array>::Cast(a);
|
||||
|
||||
n = arr->Length();
|
||||
arguments = (char**) TRI_Allocate(TRI_CORE_MEM_ZONE, n * sizeof(char*), false);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_Utf8ValueNFC arg(TRI_UNKNOWN_MEM_ZONE, arr->Get(i));
|
||||
|
||||
if (*arg == 0) {
|
||||
arguments[i] = TRI_DuplicateString("");
|
||||
}
|
||||
else {
|
||||
arguments[i] = TRI_DuplicateString(*arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = 1;
|
||||
arguments = (char**) TRI_Allocate(TRI_CORE_MEM_ZONE, n * sizeof(char*), false);
|
||||
|
||||
TRI_Utf8ValueNFC arg(TRI_UNKNOWN_MEM_ZONE, a);
|
||||
|
||||
if (*arg == 0) {
|
||||
arguments[0] = TRI_DuplicateString("");
|
||||
}
|
||||
else {
|
||||
arguments[0] = TRI_DuplicateString(*arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRI_external_id_t external = TRI_CreateExternalProcess(*name, (const char**) arguments, n);
|
||||
|
||||
if (arguments != 0) {
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, arguments[i]);
|
||||
}
|
||||
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, arguments);
|
||||
}
|
||||
|
||||
// return the result
|
||||
return scope.Close(v8::Number::New(external));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the status of an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_StatusExternal (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
// extract the arguments
|
||||
if (argv.Length() != 1) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "statusExternal(<external-identifier>)");
|
||||
}
|
||||
|
||||
TRI_external_id_t pid = TRI_ObjectToUInt64(argv[0], true);
|
||||
TRI_external_status_t external = TRI_CheckExternalProcess(pid);
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
const char* status = "UNKNOWN";
|
||||
|
||||
switch (external._status) {
|
||||
case TRI_EXT_NOT_STARTED: status = "NOT-STARTED"; break;
|
||||
case TRI_EXT_PIPE_FAILED: status = "FAILED"; break;
|
||||
case TRI_EXT_FORK_FAILED: status = "FAILED"; break;
|
||||
case TRI_EXT_RUNNING: status = "RUNNING"; break;
|
||||
case TRI_EXT_NOT_FOUND: status = "NOT-FOUND"; break;
|
||||
case TRI_EXT_TERMINATED: status = "TERMINATED"; break;
|
||||
case TRI_EXT_ABORTED: status = "ABORTED"; break;
|
||||
case TRI_EXT_STOPPED: status = "STOPPED"; break;
|
||||
case TRI_EXT_KILL_FAILED: status = "ZOMBIE"; break;
|
||||
}
|
||||
|
||||
result->Set(v8::String::New("status"), v8::String::New(status));
|
||||
|
||||
if (external._status == TRI_EXT_TERMINATED) {
|
||||
result->Set(v8::String::New("exit"), v8::Number::New(external._exitStatus));
|
||||
}
|
||||
|
||||
// return the result
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief kills an external process
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_KillExternal (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
// extract the arguments
|
||||
if (argv.Length() != 1) {
|
||||
TRI_V8_EXCEPTION_USAGE(scope, "killExternal(<external-identifier>)");
|
||||
}
|
||||
|
||||
TRI_external_id_t pid = TRI_ObjectToUInt64(argv[0], true);
|
||||
|
||||
TRI_KillExternalProcess(pid);
|
||||
|
||||
// return the result
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ArangoError
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2706,7 +2838,7 @@ v8::Handle<v8::Object> TRI_CreateErrorObject (int errorNumber, string const& mes
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief normalize a v8 object
|
||||
/// @brief normalizes a v8 object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
v8::Handle<v8::Value> TRI_normalize_V8_Obj (v8::Handle<v8::Value> obj) {
|
||||
|
@ -2842,20 +2974,22 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context,
|
|||
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_BASE64DECODE", JS_Base64Decode);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_BASE64ENCODE", JS_Base64Encode);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_CHECK_AND_MARK_NONCE", JS_MarkNonce);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_CLIENT_STATISTICS", JS_ClientStatistics);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_CREATE_NONCE", JS_CreateNonce);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_DOWNLOAD", JS_Download);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_EXECUTE", JS_Execute);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_EXECUTE_EXTERNAL", JS_ExecuteExternal);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GEN_RANDOM_ALPHA_NUMBERS", JS_RandomAlphaNum);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GEN_RANDOM_NUMBERS", JS_RandomNumbers);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GEN_RANDOM_SALT", JS_RandomSalt);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GETLINE", JS_Getline);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_HTTP_STATISTICS", JS_HttpStatistics);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_KILL_EXTERNAL", JS_KillExternal);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_LOAD", JS_Load);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_LOG", JS_Log);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_LOG_LEVEL", JS_LogLevel);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_MD5", JS_Md5);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GEN_RANDOM_NUMBERS", JS_RandomNumbers);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GEN_RANDOM_ALPHA_NUMBERS", JS_RandomAlphaNum);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_GEN_RANDOM_SALT", JS_RandomSalt);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_HTTP_STATISTICS", JS_HttpStatistics);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_CREATE_NONCE", JS_CreateNonce);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_CHECK_AND_MARK_NONCE", JS_MarkNonce);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_OUTPUT", JS_Output);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_PARSE", JS_Parse);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_PROCESS_STATISTICS", JS_ProcessStatistics);
|
||||
|
@ -2866,6 +3000,7 @@ void TRI_InitV8Utils (v8::Handle<v8::Context> context,
|
|||
TRI_AddGlobalFunctionVocbase(context, "SYS_SERVER_STATISTICS", JS_ServerStatistics);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_SHA256", JS_Sha256);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_SPRINTF", JS_SPrintF);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_STATUS_EXTERNAL", JS_StatusExternal);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_TIME", JS_Time);
|
||||
TRI_AddGlobalFunctionVocbase(context, "SYS_WAIT", JS_Wait);
|
||||
|
||||
|
|
Loading…
Reference in New Issue