Created
January 16, 2018 01:24
-
-
Save hinzundcode/6ce03dcd62bd5571fc3c1ceea141f3d1 to your computer and use it in GitHub Desktop.
call execve from nodejs!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { syscall, getAddress } = require("libsys"); | |
const os = require("os"); | |
if (os.endianess() != "LE") | |
throw "only little endian supported"; | |
let dontGC = []; | |
function ref(buffer) { | |
dontGC.push(buffer); | |
return getAddress(buffer); | |
} | |
const pointerSize = 8; | |
const SYS_execve = 59; | |
const SYS_dup2 = 33; | |
// Buffer.from(string) doesn't append a null byte | |
function stringToBuffer(string) { | |
let buffer = Buffer.alloc(Buffer.byteLength(string)+1, 0); | |
buffer.write(string); | |
return buffer; | |
} | |
function stringArrayToBuffer(strings) { | |
let buffer = Buffer.alloc((strings.length+1)*pointerSize, 0); | |
let offset = 0; | |
for (let string of strings) { | |
let stringBuffer = stringToBuffer(string); | |
let pos = ref(stringBuffer); | |
buffer.writeInt32LE(pos[0], offset); | |
buffer.writeInt32LE(pos[1], offset+4); | |
offset += 8; | |
} | |
return buffer; | |
} | |
function dup2(oldfd, newfd) { | |
return syscall(SYS_dup2, oldfd, newfd); | |
} | |
function execve(cmd, argv, envp) { | |
let cmdBuf = stringToBuffer(cmd); | |
let argvBuf = stringArrayToBuffer(argv); | |
let envpBuf = stringArrayToBuffer(envp); | |
return syscall(SYS_execve, cmdBuf, argvBuf, envpBuf); | |
} | |
let cmd = "/bin/ls"; | |
let argv = ["/bin/ls", "-la"]; | |
let envp = [ | |
"HOME=/", | |
"PATH=/bin", | |
]; | |
dup2(process.stdin._handle.fd, 0); | |
dup2(process.stdout._handle.fd, 1); | |
dup2(process.stderr._handle.fd, 2); | |
execve(cmd, argv, envp); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, this looks useful! I'm replacing a docker container bootstrap script written in bash with the equivalent in nodejs and the missing piece is the final exec call. Using this code it works nicely when I run docker in interactive mode, but when I remove
-it
I don't get the standard output after the execve call. I would greatly appreciate if you could give me a pointer. (I skip the dup2 call if stdout._handle.fd === 1 and so on)