1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Michael Hackstein 2014-01-31 17:38:20 +01:00
commit 0b0d4c5dd7
4 changed files with 516 additions and 71 deletions

View File

@ -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
// -----------------------------------------------------------------------------

View File

@ -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

View File

@ -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--\\|/// @\\}"

View File

@ -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);