2017-11-22 57 views
7

सामान्य सी ++ ++ ऐड-ऑन execl ठीक काम करता है (g++ ok.cc -o ok.elf साथ संकलन)execl दुर्घटनाओं सी ++ Node.js-ऐड-ऑन

#include <unistd.h> 
int main(){ 
    execl("/usr/bin/python", "/usr/bin/python", nullptr); 
} 

लेकिन दुर्घटनाओं, काम करता है Node.js सी के रूप में जब के रूप में

#include <node.h> 
#include <unistd.h> 

namespace bug{ 
    void wtf(const v8::FunctionCallbackInfo<v8::Value>& args){ 
    execl("/usr/bin/python", "/usr/bin/python", nullptr); 
    } 

    void init(v8::Local<v8::Object> exports){ 
    NODE_SET_METHOD(exports, "wtf", bug::wtf); 
    } 
    NODE_MODULE(NODE_GYP_MODULE_NAME, init) 
} 

Crash of node.js extension

node.js v8.9.1
नोड-जीईपी v3.6.2
जीसीसी संस्करण 6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2)

+0

हां मुझे पता है, execl प्रक्रिया स्मृति प्रस्तुति को प्रतिस्थापित करता है। मूल रूप से मैं इसे 'फोर्क() 'syscall –

+1

के साथ बाल प्रक्रिया को बढ़ाने के लिए उपयोग करता हूं नोड सभी पॉज़िक्स syscall का समर्थन नहीं करता है। यह थ्रेड https://stackoverflow.com/questions/34290403/a-way-to-call-execl-execle-execlp-execv-execvp-or-execvp-from-node-js देखें। दुर्घटना की उम्मीद है क्योंकि आप कुछ ऐसा उपयोग कर रहे हैं जो आपके लिए उपलब्ध नहीं है –

उत्तर

1

नोड सभी पॉज़िक्स syscall का समर्थन नहीं करता है।

इस सूत्र

A way to call execl, execle, execlp, execv, execvP or execvp from Node.js

दुर्घटना के रूप में आप कुछ है कि आप के लिए उपलब्ध नहीं है का उपयोग कर रहे उम्मीद है देखें। जैसा कि ऊपर सूत्र में चर्चा की या तो आप

index.cc

#include <nan.h> 
#include <fcntl.h> 
#include <unistd.h> 

int doNotCloseStreamsOnExit(int desc) { 
    int flags = fcntl(desc, F_GETFD, 0); 
    if (flags < 0) return flags; 
    flags &= ~FD_CLOEXEC; //clear FD_CLOEXEC bit 
    return fcntl(desc, F_SETFD, flags); 
} 

void copyArray(char* dest[], unsigned int offset, v8::Local<v8::Array> src) { 
    unsigned int length = src->Length(); 
    for (unsigned int i = 0; i < length; i++) { 
    v8::String::Utf8Value arrayElem(Nan::Get(src, i).ToLocalChecked()->ToString()); 
    std::string arrayElemStr (*arrayElem); 
    char* tmp = new char[arrayElemStr.length() +1]; 
    strcpy(tmp, arrayElemStr.c_str()); 
    dest[i + offset] = tmp; 
    } 
} 

void setEnv(v8::Local<v8::Array> src) { 
    unsigned int length = src->Length(); 
    v8::Local<v8::String> keyProp = Nan::New<v8::String>("key").ToLocalChecked(); 
    v8::Local<v8::String> valueProp = Nan::New<v8::String>("value").ToLocalChecked(); 
    for (unsigned int i = 0; i < length; i++) { 
    v8::Local<v8::Object> obj = Nan::Get(src, i).ToLocalChecked()->ToObject(); 

    v8::String::Utf8Value objKey(Nan::Get(obj, keyProp).ToLocalChecked()->ToString()); 
    v8::String::Utf8Value objValue(Nan::Get(obj, valueProp).ToLocalChecked()->ToString()); 

    std::string objKeyStr (*objKey); 
    char *key = const_cast<char*> (objKeyStr.c_str()); 
    std::string objValueStr (*objValue); 
    char *value = const_cast<char*> (objValueStr.c_str()); 

    setenv(key, value, 1); 
    } 
} 

void Method(const Nan::FunctionCallbackInfo<v8::Value>& info) { 
    if (info.Length() < 3) { 
    return; 
    } 
    if (!info[0]->IsString()) { 
    return; 
    } 

    // get command 
    v8::String::Utf8Value val(info[0]->ToString()); 
    std::string str (*val); 
    char *command = const_cast<char*> (str.c_str()); 

    // set env on the current process 
    v8::Local<v8::Array> envArr = v8::Local<v8::Array>::Cast(info[1]); 
    setEnv(envArr); 

    // build args: command, ...args, NULL 
    v8::Local<v8::Array> argsArr = v8::Local<v8::Array>::Cast(info[2]); 
    char* args[argsArr->Length() + 2]; 
    args[0] = command; 
    copyArray(args, 1, argsArr); 
    args[argsArr->Length() + 1] = NULL; 

    // fix stream flags 
    doNotCloseStreamsOnExit(0); //stdin 
    doNotCloseStreamsOnExit(1); //stdout 
    doNotCloseStreamsOnExit(2); //stderr 

    execvp(command, args); 
} 

void Init(v8::Local<v8::Object> exports) { 
    exports->Set(Nan::New("exec").ToLocalChecked(), 
       Nan::New<v8::FunctionTemplate>(Method)->GetFunction()); 
} 

NODE_MODULE(exec, Init) 

index.js

'use strict'; 

var addon = require('bindings')('addon'); 
var path = require('path'); 
var fs = require('fs'); 

module.exports = function(cmd, env, args) { 
    if (!cmd) { 
    throw new Error('Command is required'); 
    } 

    var envArr = Object.keys(env || {}).map(key => { 
    return { 
     key, 
     value: env[key], 
    }; 
    }); 

    addon.exec(cmd, envArr, args || []); 
}; 

पी एस बनाने के लिए अपने स्वयं के कार्यकारी जरूरत: कोड https://github.com/OrKoN/native-exec से पोस्ट किए गए, में केस लिंक भविष्य में निष्क्रिय हो जाता है

यह भी एक और बात है कि आपको ऐसा करने की कोशिश नहीं करनी चाहिए जिसे टीटीई प्राप्त करने की आवश्यकता है, आप उस मामले में बहुत जटिलता जोड़ देंगे। तो पाइथन चलाना आपके टीटीवी पर नियंत्रण रखना होगा।

संबंधित मुद्दे