github.com/goplusjs/gopherjs@v1.2.6-0.20211206034512-f187917453b8/node-syscall/syscall.cc (about) 1 #include <cstdlib> 2 #include <node.h> 3 #include <v8.h> 4 #include <unistd.h> 5 #include <sys/syscall.h> 6 #include <errno.h> 7 8 using namespace v8; 9 10 #if NODE_MAJOR_VERSION == 0 11 #define ARRAY_BUFFER_DATA_OFFSET 23 12 #else 13 #define ARRAY_BUFFER_DATA_OFFSET 31 14 #endif 15 16 intptr_t toNative(Local<Value> value) { 17 if (value.IsEmpty()) { 18 return 0; 19 } 20 if (value->IsArrayBufferView()) { 21 Local<ArrayBufferView> view = Local<ArrayBufferView>::Cast(value); 22 return *reinterpret_cast<intptr_t*>(*reinterpret_cast<char**>(*view->Buffer()) + ARRAY_BUFFER_DATA_OFFSET) + view->ByteOffset(); // ugly hack, because of https://codereview.chromium.org/25221002 23 } 24 if (value->IsArray()) { 25 Local<Array> array = Local<Array>::Cast(value); 26 intptr_t* native = reinterpret_cast<intptr_t*>(malloc(array->Length() * sizeof(intptr_t))); // TODO memory leak 27 for (uint32_t i = 0; i < array->Length(); i++) { 28 native[i] = toNative(array->Get(i)); 29 } 30 return reinterpret_cast<intptr_t>(native); 31 } 32 return static_cast<intptr_t>(static_cast<int32_t>(value->ToInteger()->Value())); 33 } 34 35 void Syscall(const FunctionCallbackInfo<Value>& info) { 36 int trap = info[0]->ToInteger()->Value(); 37 int r1 = 0, r2 = 0; 38 switch (trap) { 39 case SYS_fork: 40 r1 = fork(); 41 break; 42 case SYS_pipe: 43 int fd[2]; 44 r1 = pipe(fd); 45 if (r1 == 0) { 46 r1 = fd[0]; 47 r2 = fd[1]; 48 } 49 break; 50 default: 51 r1 = syscall( 52 trap, 53 toNative(info[1]), 54 toNative(info[2]), 55 toNative(info[3]) 56 ); 57 break; 58 } 59 int err = 0; 60 if (r1 < 0) { 61 err = errno; 62 } 63 Isolate* isolate = info.GetIsolate(); 64 Local<Array> res = Array::New(isolate, 3); 65 res->Set(0, Integer::New(isolate, r1)); 66 res->Set(1, Integer::New(isolate, r2)); 67 res->Set(2, Integer::New(isolate, err)); 68 info.GetReturnValue().Set(res); 69 } 70 71 void Syscall6(const FunctionCallbackInfo<Value>& info) { 72 int r = syscall( 73 info[0]->ToInteger()->Value(), 74 toNative(info[1]), 75 toNative(info[2]), 76 toNative(info[3]), 77 toNative(info[4]), 78 toNative(info[5]), 79 toNative(info[6]) 80 ); 81 int err = 0; 82 if (r < 0) { 83 err = errno; 84 } 85 Isolate* isolate = info.GetIsolate(); 86 Local<Array> res = Array::New(isolate, 3); 87 res->Set(0, Integer::New(isolate, r)); 88 res->Set(1, Integer::New(isolate, 0)); 89 res->Set(2, Integer::New(isolate, err)); 90 info.GetReturnValue().Set(res); 91 } 92 93 void init(Handle<Object> target) { 94 NODE_SET_METHOD(target, "Syscall", Syscall); 95 NODE_SET_METHOD(target, "Syscall6", Syscall6); 96 } 97 98 NODE_MODULE(syscall, init);