mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
1. Fixed bug with process.cwd() on windows when the cwd is a root level folder
2. Added process.chdir() 3. Updated child_process._execve() to use process.env if not specified 4. Updated service manager to work better with docker container
This commit is contained in:
@@ -552,6 +552,25 @@ duk_ret_t ILibDuktape_ChildProcess_execve(duk_context *ctx)
|
||||
WCHAR* wtmp;
|
||||
#endif
|
||||
|
||||
if (nargs < 3 || !(duk_is_object(ctx, 2) && duk_has_prop_string(ctx, 2, "env")))
|
||||
{
|
||||
duk_push_this(ctx); // [childprocess]
|
||||
duk_prepare_method_call(ctx, -1, "_execve"); // [childprocess][execve][this]
|
||||
duk_dup(ctx, 0); duk_dup(ctx, 1); // [childprocess][execve][this][path][parms]
|
||||
if (nargs > 2 && duk_is_object(ctx, 2))
|
||||
{
|
||||
duk_dup(ctx, 2); // [childprocess][execve][this][path][parms][options]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_object(ctx); // [childprocess][execve][this][path][parms][options]
|
||||
}
|
||||
duk_eval_string(ctx, "process.env"); // [childprocess][execve][this][path][parms][options][env]
|
||||
duk_put_prop_string(ctx, -2, "env"); // [childprocess][execve][this][path][parms][options]
|
||||
duk_call_method(ctx, 3);
|
||||
return(ILibDuktape_Error(ctx, "execve() error"));
|
||||
}
|
||||
|
||||
duk_push_array(ctx); // [WCHAR_ARRAY]
|
||||
args = (void**)ILibMemory_SmartAllocate(sizeof(char*) * (1 + duk_get_length(ctx, 1)));
|
||||
for (i = 0; i < (int)duk_get_length(ctx, 1); ++i)
|
||||
@@ -566,10 +585,9 @@ duk_ret_t ILibDuktape_ChildProcess_execve(duk_context *ctx)
|
||||
#endif
|
||||
duk_pop(ctx); // [WCHAR_ARRAY]
|
||||
}
|
||||
|
||||
if (nargs > 2 && duk_is_object(ctx, 2) && duk_has_prop_string(ctx, 2, "env"))
|
||||
{
|
||||
duk_get_prop_string(ctx, 2, "env"); // [WCHAR_ARRAY][obj]
|
||||
duk_get_prop_string(ctx, 2, "env"); // [WCHAR_ARRAY][obj]
|
||||
|
||||
duk_push_array(ctx); // [WCHAR_ARRAY][obj][array]
|
||||
duk_enum(ctx, -2, DUK_ENUM_OWN_PROPERTIES_ONLY); // [WCHAR_ARRAY][obj][array][enum]
|
||||
@@ -601,13 +619,17 @@ duk_ret_t ILibDuktape_ChildProcess_execve(duk_context *ctx)
|
||||
//
|
||||
// We must close all open descriptors first, since the "new" process will have no idea about any that are still open
|
||||
//
|
||||
duk_eval_string(ctx, "require('util-descriptors').getOpenDescriptors();"); // [array]
|
||||
while (duk_get_length(ctx, -1) > 0)
|
||||
if (nargs > 2 && duk_is_object(ctx, 2) && Duktape_GetBooleanProperty(ctx, 2, "close", 1) != 0)
|
||||
{
|
||||
duk_array_pop(ctx, -1); // [array][fd]
|
||||
close(duk_get_int(ctx, -1)); duk_pop(ctx); // [array]
|
||||
int d;
|
||||
duk_eval_string(ctx, "require('util-descriptors').getOpenDescriptors();"); // [array]
|
||||
while (duk_get_length(ctx, -1) > 0)
|
||||
{
|
||||
duk_array_pop(ctx, -1); // [array][fd]
|
||||
d = duk_get_int(ctx, -1); duk_pop(ctx); // [array]
|
||||
if (d > 2) { close(d); } // [array]
|
||||
}
|
||||
}
|
||||
|
||||
execve(path, (char**)args, (char**)env);
|
||||
return(ILibDuktape_Error(ctx, "_execve() returned error: %d ", errno));
|
||||
#else
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
#include <Windows.h>
|
||||
#include <WinBase.h>
|
||||
#include <signal.h>
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -890,7 +891,16 @@ duk_ret_t ILibDuktape_Process_cwd(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "concat"); // [string][concat]
|
||||
duk_swap_top(ctx, -2); // [concat][this]
|
||||
#ifdef WIN32
|
||||
duk_push_string(ctx, "\\");
|
||||
duk_string_endsWith(ctx, -1, "\\"); // [concat][this][bool]
|
||||
if (!duk_get_boolean(ctx, -1))
|
||||
{
|
||||
duk_push_string(ctx, "\\"); // [concat][this][bool][/]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_string(ctx, "");
|
||||
}
|
||||
duk_remove(ctx, -2); // [concat][this][/]
|
||||
#else
|
||||
duk_push_string(ctx, "/");
|
||||
#endif
|
||||
@@ -1196,6 +1206,17 @@ duk_ret_t ILibDuktape_Process_SignalHooks(duk_context *ctx)
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Process_chdir(duk_context *ctx)
|
||||
{
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
#ifdef WIN32
|
||||
if (_wchdir(ILibUTF8ToWide(path, -1)) != 0) { return(ILibDuktape_Error(ctx, "chdir() failed")); }
|
||||
#else
|
||||
if (chdir(path) != 0) { return(ILibDuktape_Error(ctx, "chdir() failed")); }
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -1210,6 +1231,7 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||
ILibDuktape_WriteID(ctx, "process");
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "cwd", ILibDuktape_Process_cwd, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "chdir", ILibDuktape_Process_chdir, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "setenv", ILibDuktape_Process_setenv, 2);
|
||||
ILibDuktape_CreateEventWithSetterEx(ctx, "_SemaphoreTracking", ILibDuktape_Process_SemaphoreTracking);
|
||||
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "coreDumpLocation", ILibDuktape_ScriptContainer_Process_coreDumpLocation_getter, ILibDuktape_ScriptContainer_Process_coreDumpLocation_setter);
|
||||
|
||||
@@ -1267,7 +1267,7 @@ function serviceManager()
|
||||
child.stdin.write(' p=substr($0,4);');
|
||||
child.stdin.write(' gsub(/"/,"",p);');
|
||||
child.stdin.write(' gsub("/$","",p);');
|
||||
child.stdin.write(' print p;');
|
||||
child.stdin.write(' printf "%s/",p;');
|
||||
child.stdin.write("}'");
|
||||
child.stdin.write('\nexit\n');
|
||||
child.waitExit();
|
||||
@@ -1321,7 +1321,7 @@ function serviceManager()
|
||||
ret = child.stdout.str.trim();
|
||||
if(!ret.startsWith('/'))
|
||||
{
|
||||
ret = (this.appWorkingDirectory() + '/' + ret);
|
||||
ret = (this.appWorkingDirectory() + ret);
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
@@ -1434,11 +1434,11 @@ function serviceManager()
|
||||
{
|
||||
if (this._autorestart)
|
||||
{
|
||||
child.stdin.write('cat /etc/init.d/' + this.name + ' | grep "^\\s*supervise_daemon_args=" | awk \'NR==1{ split($0,A,"--chdir "); split(A[2],B,"\\\\\\\\\\""); print B[2]; }\'\nexit\n');
|
||||
child.stdin.write('cat /etc/init.d/' + this.name + ' | grep "^\\s*supervise_daemon_args=" | awk \'NR==1{ split($0,A,"--chdir "); split(A[2],B,"\\\\\\\\\\""); gsub("/$","",B[2]); printf "%s/",B[2]; }\'\nexit\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
child.stdin.write('cat /etc/init.d/' + this.name + ' | grep "^\\s*start_stop_daemon_args=" | awk \'NR==1{ split($0,A,"--chdir "); split(A[2],B,"\\\\\\\\\\""); print B[2]; }\'\nexit\n');
|
||||
child.stdin.write('cat /etc/init.d/' + this.name + ' | grep "^\\s*start_stop_daemon_args=" | awk \'NR==1{ split($0,A,"--chdir "); split(A[2],B,"\\\\\\\\\\""); gsub("/$","",B[2]); printf "%s/",B[2]; }\'\nexit\n');
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1731,11 +1731,13 @@ function serviceManager()
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = '';
|
||||
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
|
||||
if (require('fs').existsSync('/lib/systemd/system/' + this.name + '.service')) {
|
||||
child.stdin.write("cat /lib/systemd/system/" + this.name + ".service | grep 'WorkingDirectory=' | awk -F= '{ print $2 }'\n\exit\n");
|
||||
if (require('fs').existsSync('/lib/systemd/system/' + this.name + '.service'))
|
||||
{
|
||||
child.stdin.write("cat /lib/systemd/system/" + this.name + ".service | grep 'WorkingDirectory=' | awk 'NR==1" + '{ gsub(/^.+=/,"",$0); gsub("/$","",$0); printf "%s/",$0; }\'\n\exit\n');
|
||||
}
|
||||
else {
|
||||
child.stdin.write("cat /usr/lib/systemd/system/" + this.name + ".service | grep 'WorkingDirectory=' | awk -F= '{ print $2 }'\n\exit\n");
|
||||
else
|
||||
{
|
||||
child.stdin.write("cat /usr/lib/systemd/system/" + this.name + ".service | grep 'WorkingDirectory=' | awk 'NR==1" + '{ gsub(/^.+=/,"",$0); gsub("/$","",$0); printf "%s/",$0; }\'\n\exit\n');
|
||||
}
|
||||
child.waitExit();
|
||||
return (child.stdout.str.trim());
|
||||
@@ -1826,20 +1828,38 @@ function serviceManager()
|
||||
if (require('fs').existsSync('/usr/local/mesh_daemons/' + name + '.service'))
|
||||
{
|
||||
ret.conf = '/usr/local/mesh_daemons/' + name + '.service';
|
||||
ret.parameters = function parameters()
|
||||
{
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.on('data', function (c) { });
|
||||
child.stdin.write('cat ' + this.conf + ' | grep "^[ \\t]*parameters=" | awk \'NR==1{ gsub(/^[ \t]*parameters=/,"",$0); print $0; }\'\nexit\n');
|
||||
child.waitExit();
|
||||
try
|
||||
{
|
||||
return (JSON.parse(child.stdout.str.trim()));
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
return ([]);
|
||||
}
|
||||
};
|
||||
ret.start = function start()
|
||||
{
|
||||
var child;
|
||||
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.on('data', function (c) { });
|
||||
child.stdin.write('cat ' + this.conf + " | tr '\n' '~' | awk -F~ '{ wd=" + '""; parms=""; respawn="0"; for(i=1;i<=NF;++i) { split($i, tok1, "="); if(tok1[1]=="workingDirectory") { wd=tok1[2];} if(tok1[1]=="parameters") { parms=substr($i,12);} if(tok1[1]=="respawn") { respawn="1"; } } printf "{ \\\"wd\\\": \\\"%s\\\", \\\"parms\\\": %s, \\\"respawn\\\": %s }", wd, parms, respawn }\'\nexit\n');
|
||||
child.stdin.write('cat ' + this.conf + ' | grep "^[ \\t]*respawn$"\nexit\n');
|
||||
child.waitExit();
|
||||
|
||||
var info = JSON.parse(child.stdout.str.trim());
|
||||
info.exePath = info.wd + '/' + info.parms.shift();
|
||||
var respawn = child.stdout.str.trim() != '';
|
||||
var wd = this.appWorkingDirectory();
|
||||
var parameters = this.parameters();
|
||||
var location = wd + parameters.shift();
|
||||
|
||||
var options = { pidPath: info.wd + '/pid', logOutputs: false, crashRestart: info.respawn ? true : false };
|
||||
require('service-manager').manager.daemon(info.exePath, info.parms, options);
|
||||
var options = { pidPath: wd + 'pid', logOutputs: false, crashRestart: respawn, cwd: wd };
|
||||
require('service-manager').manager.daemon(location, parameters, options);
|
||||
};
|
||||
ret.stop = function stop()
|
||||
{
|
||||
@@ -1855,12 +1875,32 @@ function serviceManager()
|
||||
{
|
||||
}
|
||||
};
|
||||
ret.restart = function restart()
|
||||
{
|
||||
if(!this.isMe())
|
||||
{
|
||||
this.stop();
|
||||
this.start();
|
||||
return;
|
||||
}
|
||||
|
||||
var p = this.parameters();
|
||||
require('child_process')._execve(process.execPath, p);
|
||||
}
|
||||
ret.isMe = function isMe()
|
||||
{
|
||||
var child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stdin.write('cat /usr/local/mesh_daemons/' + name + '/pid \nexit\n');
|
||||
child.waitExit();
|
||||
var pid = child.stdout.str.trim();
|
||||
if (pid == '') { return (false); }
|
||||
|
||||
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stdin.write('ps -e -o pid -o ppid | grep "[ \\t]*' + pid + '$" | awk \'NR==1{ print $1; }\'\nexit\n');
|
||||
child.waitExit();
|
||||
|
||||
return (parseInt(child.stdout.str.trim()) == process.pid);
|
||||
};
|
||||
ret.appWorkingDirectory = function appWorkingDirectory()
|
||||
@@ -1869,23 +1909,13 @@ function serviceManager()
|
||||
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.on('data', function (c) { });
|
||||
child.stdin.write('cat ' + this.conf + " | tr '\n' '~' | awk -F~ '{ wd=" + '""; parms=""; for(i=1;i<=NF;++i) { split($i, tok1, "="); if(tok1[1]=="workingDirectory") { wd=tok1[2];} if(tok1[1]=="parameters") { parms=tok1[2];} } printf "{ \\\"wd\\\": \\\"%s\\\", \\\"parms\\\": %s }", wd, parms }\'\nexit\n');
|
||||
child.stdin.write('cat ' + this.conf + " | grep 'workingDirectory=' | awk 'NR==1" + '{ gsub(/^.+=/,"",$0); gsub("/$","",$0); printf "%s/",$0; }\'\nexit\n');
|
||||
child.waitExit();
|
||||
|
||||
var info = JSON.parse(child.stdout.str.trim());
|
||||
return (info.wd);
|
||||
return (child.stdout.str.trim());
|
||||
};
|
||||
ret.appLocation = function appLocation()
|
||||
{
|
||||
var child;
|
||||
child = require('child_process').execFile('/bin/sh', ['sh']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.stderr.on('data', function (c) { });
|
||||
child.stdin.write('cat ' + this.conf + " | tr '\n' '~' | awk -F~ '{ wd=" + '""; parms=""; for(i=1;i<=NF;++i) { split($i, tok1, "="); if(tok1[1]=="workingDirectory") { wd=tok1[2];} if(tok1[1]=="parameters") { parms=substr($i,12);} } printf "{ \\\"wd\\\": \\\"%s\\\", \\\"parms\\\": %s }", wd, parms }\'\nexit\n');
|
||||
child.waitExit();
|
||||
|
||||
var info = JSON.parse(child.stdout.str.trim());
|
||||
return (info.wd + '/' + info.parms.shift());
|
||||
return (this.appWorkingDirectory() + this.parameters().shift());
|
||||
};
|
||||
ret.isRunning = function isRunning()
|
||||
{
|
||||
@@ -2829,7 +2859,7 @@ function serviceManager()
|
||||
if (!options || !options.skipDeleteBinary)
|
||||
{
|
||||
require('fs').unlinkSync(servicePath);
|
||||
require('fs').unlinkSync(workingPath + '/' + name + '.sh');
|
||||
require('fs').unlinkSync(workingPath + name + '.sh');
|
||||
}
|
||||
console.log(name + ' uninstalled');
|
||||
}
|
||||
@@ -3118,6 +3148,7 @@ function serviceManager()
|
||||
{\
|
||||
console.setDestination(console.Destinations.DISABLED);\
|
||||
}\
|
||||
if(options.cwd) { process.chdir(options.cwd); }\
|
||||
function cleanupAndExit()\
|
||||
{\
|
||||
if(options.pidPath) { try{require('fs').unlinkSync(options.pidPath);} catch(x){} }\
|
||||
|
||||
Reference in New Issue
Block a user