mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
1. Fixed execv(e)
2. Fixed service.restart() for OpenRC
This commit is contained in:
@@ -595,7 +595,19 @@ duk_ret_t ILibDuktape_ChildProcess_execve(duk_context *ctx)
|
|||||||
duk_pop(ctx); // [WCHAR_ARRAY][obj][array]
|
duk_pop(ctx); // [WCHAR_ARRAY][obj][array]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
duk_array_pop(ctx, -1); // [array][fd]
|
||||||
|
close(duk_get_int(ctx, -1)); duk_pop(ctx); // [array]
|
||||||
|
}
|
||||||
|
|
||||||
execve(path, (char**)args, (char**)env);
|
execve(path, (char**)args, (char**)env);
|
||||||
return(ILibDuktape_Error(ctx, "_execve() returned error: %d ", errno));
|
return(ILibDuktape_Error(ctx, "_execve() returned error: %d ", errno));
|
||||||
#else
|
#else
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1553,17 +1553,27 @@ function serviceManager()
|
|||||||
ret.stop.platform = platform;
|
ret.stop.platform = platform;
|
||||||
ret.restart = function restart()
|
ret.restart = function restart()
|
||||||
{
|
{
|
||||||
var child = require('child_process').execFile('/bin/sh', ['sh'], this.OpenRC ? { type: require('child_process').SpawnTypes.TERM } : null);
|
if (this.isMe() && this.OpenRC)
|
||||||
child.stdout.on('data', function (chunk) { });
|
|
||||||
if (restart.platform == 'upstart')
|
|
||||||
{
|
{
|
||||||
child.stdin.write('initctl restart ' + this.name + '\nexit\n');
|
// On OpenRC platforms, we cannot restart our own service using rc-service, so we must use execv
|
||||||
|
var args = this.parameters();
|
||||||
|
args.unshift(process.execPath);
|
||||||
|
require('child_process')._execve(process.execPath, args);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
child.stdin.write('service ' + this.name + ' restart\nexit\n');
|
var child = require('child_process').execFile('/bin/sh', ['sh'], this.OpenRC ? { type: require('child_process').SpawnTypes.TERM } : null);
|
||||||
|
child.stdout.on('data', function (chunk) { });
|
||||||
|
if (restart.platform == 'upstart')
|
||||||
|
{
|
||||||
|
child.stdin.write('initctl restart ' + this.name + '\nexit\n');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child.stdin.write('service ' + this.name + ' restart\nexit\n');
|
||||||
|
}
|
||||||
|
child.waitExit();
|
||||||
}
|
}
|
||||||
child.waitExit();
|
|
||||||
};
|
};
|
||||||
ret.restart.platform = platform;
|
ret.restart.platform = platform;
|
||||||
ret.status = function status()
|
ret.status = function status()
|
||||||
@@ -1607,6 +1617,17 @@ function serviceManager()
|
|||||||
child.waitExit();
|
child.waitExit();
|
||||||
return (parseInt(child.stdout.str.trim()));
|
return (parseInt(child.stdout.str.trim()));
|
||||||
}
|
}
|
||||||
|
ret.parameters = function()
|
||||||
|
{
|
||||||
|
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 () { });
|
||||||
|
child.stdin.write('cat ' + this.conf + ' | grep "^\\s*command_args=" | awk \'NR==1{ gsub(/^\\s*command_args=/,"",$0); print $0; }\'\nexit\n');
|
||||||
|
child.waitExit();
|
||||||
|
var val = JSON.parse(child.stdout.str.trim());
|
||||||
|
val = val.match(/(?:[^\s"]+|"[^"]*")+/g);
|
||||||
|
return (val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret.status.platform = platform;
|
ret.status.platform = platform;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,43 +90,71 @@ function getOpenDescriptors()
|
|||||||
return ([]);
|
return ([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function closeDescriptors(fdArray, libc)
|
function closeDescriptors(fdArray)
|
||||||
{
|
{
|
||||||
var fd = null;
|
var fd = null;
|
||||||
if (libc == null)
|
if (this.libc == null) { throw ('cannot find libc'); }
|
||||||
{
|
|
||||||
var libs = require('monitor-info').getLibInfo('libc');
|
|
||||||
while (libs.length > 0)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
libc = require('_GenericMarshal').CreateNativeProxy(libs.shift().path);
|
|
||||||
libc.CreateMethod('close');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
libc = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (libc == null) { throw ('cannot find libc'); }
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fdArray.length > 0)
|
while (fdArray.length > 0)
|
||||||
{
|
{
|
||||||
fd = fdArray.pop();
|
fd = fdArray.pop();
|
||||||
if (fd > 2)
|
if (fd > 2)
|
||||||
{
|
{
|
||||||
libc.close(fd);
|
this.libc.close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function _execv(exePath, argarr)
|
||||||
|
{
|
||||||
|
if (this.libc == null)
|
||||||
|
{
|
||||||
|
throw ('cannot find libc');
|
||||||
|
}
|
||||||
|
|
||||||
|
var i;
|
||||||
|
var path = require('_GenericMarshal').CreateVariable(exePath);
|
||||||
|
var args = require('_GenericMarshal').CreateVariable((1 + argarr.length) * require('_GenericMarshal').PointerSize);
|
||||||
|
for (i = 0; i < argarr.length; ++i)
|
||||||
|
{
|
||||||
|
var arg = require('_GenericMarshal').CreateVariable(argarr[i]);
|
||||||
|
arg.pointerBuffer().copy(args.toBuffer(), i * require('_GenericMarshal').PointerSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fds = this.getOpenDescriptors();
|
||||||
|
this.closeDescriptors(fds);
|
||||||
|
|
||||||
|
this.libc.execv(path, args);
|
||||||
|
throw('exec error');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLibc()
|
||||||
|
{
|
||||||
|
var libs = require('monitor-info').getLibInfo('libc');
|
||||||
|
var libc = null;
|
||||||
|
|
||||||
|
while (libs.length > 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
libc = require('_GenericMarshal').CreateNativeProxy(libs.pop().path);
|
||||||
|
libc.CreateMethod('execv');
|
||||||
|
libc.CreateMethod('close');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
libc = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (libc);
|
||||||
|
}
|
||||||
switch (process.platform)
|
switch (process.platform)
|
||||||
{
|
{
|
||||||
case 'linux':
|
case 'linux':
|
||||||
case 'freebsd':
|
case 'freebsd':
|
||||||
module.exports = { getOpenDescriptors: getOpenDescriptors, closeDescriptors: closeDescriptors };
|
module.exports = { getOpenDescriptors: getOpenDescriptors, closeDescriptors: closeDescriptors, _execv: _execv, libc: getLibc() };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
module.exports = { getOpenDescriptors: invalid, closeDescriptors: invalid };
|
module.exports = { getOpenDescriptors: invalid, closeDescriptors: invalid };
|
||||||
|
|||||||
Reference in New Issue
Block a user