首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >execl崩溃C++ node.js-addon

execl崩溃C++ node.js-addon
EN

Stack Overflow用户
提问于 2017-11-22 11:41:19
回答 1查看 341关注 0票数 7

正常情况下,C++ execl工作正常(用g++ ok.cc -o ok.elf编译)

代码语言:javascript
复制
#include <unistd.h>
int main(){
  execl("/usr/bin/python", "/usr/bin/python", nullptr);
}

但是崩溃,当作为node.js C++的加注时

代码语言:javascript
复制
#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)
}

node.js v8.9.1

节点-回转体v3.6.2

gcc版6.3.0 20170406 (Ubuntu 6.3.0-12ubuntu2)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-16 05:12:43

节点不支持所有posix syscall。

看这个线程

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

当您正在使用一些您无法使用的东西时,预计会发生崩溃。正如在上面的线程中所讨论的,您需要创建自己的exec。

index.cc

代码语言:javascript
复制
#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

代码语言:javascript
复制
'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 || []);
};

PS:从https://github.com/OrKoN/native-exec发布的代码,以防将来链接失效

另外,您不应该尝试的另一件事是执行一些需要获得TTY的东西,在这种情况下,您将增加很多复杂性。因此,运行python需要控制TTY。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47433804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档