92 lines
2.9 KiB
C++
92 lines
2.9 KiB
C++
#include <sys/syscall.h> /* Definition of SYS_* constants */
|
|
#include <sys/reboot.h>
|
|
#include <unistd.h>
|
|
#include <node.h>
|
|
#include <errno.h>
|
|
#include <list>
|
|
|
|
#define returnjs(val) args.GetReturnValue().Set(val);
|
|
namespace syscallNode {
|
|
void freeList(std::list<std::string *> &list) {
|
|
std::list<std::string *>::iterator it = list.begin();
|
|
for(; it != list.end(); it++) {
|
|
delete *it;
|
|
}
|
|
}
|
|
|
|
void nodeSyscall(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
v8::Isolate* isolate = args.GetIsolate();
|
|
|
|
std::list<std::string *> memoryToClean;
|
|
|
|
//les registres rdi, rsi, rdx ...
|
|
long int registers[args.Length()];
|
|
|
|
for(int i=0; i < args.Length(); i++) {
|
|
if(args[i]->IsNumber()) {
|
|
registers[i] = args[i].As<v8::Number>()->Value();
|
|
} else if(args[i]->IsString()) {
|
|
v8::String::Utf8Value argv8(isolate, args[i]);
|
|
std::string *argStr = new std::string(*argv8);
|
|
//un pointer c'est un u_int32_t donc sa deverais passer
|
|
registers[i] = (long int)argStr->c_str();
|
|
memoryToClean.push_front(argStr);
|
|
} else {
|
|
freeList(memoryToClean);
|
|
//respond -1 is something went wrong
|
|
returnjs(-1);
|
|
return;
|
|
}
|
|
}
|
|
long int syscallReturnValue;
|
|
|
|
switch(memoryToClean.size()) {
|
|
case 1:
|
|
syscallReturnValue = syscall(registers[0]);
|
|
return;
|
|
case 2:
|
|
syscallReturnValue = syscall(registers[0], registers[1]);
|
|
return;
|
|
case 3:
|
|
syscallReturnValue = syscall(registers[0], registers[1], registers[2]);
|
|
return;
|
|
case 4:
|
|
syscallReturnValue = syscall(registers[0], registers[1], registers[2], registers[3]);
|
|
return;
|
|
case 5:
|
|
syscallReturnValue = syscall(registers[0], registers[1], registers[2], registers[3], registers[4]);
|
|
return;
|
|
|
|
default:
|
|
//unsuported length
|
|
returnjs(-2);
|
|
return;
|
|
}
|
|
|
|
freeList(memoryToClean);
|
|
if(syscallReturnValue == -1) {
|
|
returnjs(errno);
|
|
}
|
|
}
|
|
|
|
void nodeReboot(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
v8::Isolate* isolate = args.GetIsolate();
|
|
if (!args[0]->IsNumber()) {
|
|
isolate->ThrowException(v8::Exception::TypeError(
|
|
v8::String::NewFromUtf8(isolate, "Argument must be a number").ToLocalChecked()));
|
|
return;
|
|
}
|
|
|
|
long argsValue = args[0].As<v8::Number>()->Value();
|
|
reboot(argsValue);
|
|
}
|
|
|
|
|
|
void Initialize(v8::Local<v8::Object> exports) {
|
|
NODE_SET_METHOD(exports, "reboot", nodeReboot);
|
|
NODE_SET_METHOD(exports, "syscall", nodeSyscall);
|
|
}
|
|
|
|
NODE_MODULE(syscall_api, Initialize)
|
|
}
|