Пример #1
0
void spawn_helper(uv_pipe_t* channel,
                  uv_process_t* process,
                  const char* helper) {
  uv_process_options_t options;
  size_t exepath_size;
  char exepath[1024];
  char* args[3];
  int r;
  uv_stdio_container_t stdio[1];

  r = uv_pipe_init(uv_default_loop(), channel, 1);
  ASSERT(r == 0);
  ASSERT(channel->ipc);

  exepath_size = sizeof(exepath);
  r = uv_exepath(exepath, &exepath_size);
  ASSERT(r == 0);

  exepath[exepath_size] = '\0';
  args[0] = exepath;
  args[1] = (char*)helper;
  args[2] = NULL;

  memset(&options, 0, sizeof(options));
  options.file = exepath;
  options.args = args;
  options.exit_cb = exit_cb;

  options.stdio = stdio;
  options.stdio[0].flags = UV_CREATE_PIPE |
    UV_READABLE_PIPE | UV_WRITABLE_PIPE;
  options.stdio[0].data.stream = (uv_stream_t*)channel;
  options.stdio_count = 1;

  r = uv_spawn(uv_default_loop(), process, options);
  ASSERT(r == 0);
}
Пример #2
0
/// Sets the underlying file descriptor that will be read from. Only pipes
/// and regular files are supported for now.
///
/// @param rstream The `RStream` instance
/// @param file The file descriptor
void rstream_set_file(RStream *rstream, uv_file file)
{
  rstream->file_type = uv_guess_handle(file);

  if (rstream->free_handle) {
    // If this is the second time we're calling this function, free the
    // previously allocated memory
    if (rstream->fread_idle != NULL) {
      uv_close((uv_handle_t *)rstream->fread_idle, close_cb);
    } else {
      uv_close((uv_handle_t *)rstream->stream, close_cb);
    }
  }

  if (rstream->file_type == UV_FILE) {
    // Non-blocking file reads are simulated with an idle handle that reads
    // in chunks of rstream->buffer_size, giving time for other events to
    // be processed between reads.
    rstream->fread_idle = xmalloc(sizeof(uv_idle_t));
    uv_idle_init(uv_default_loop(), rstream->fread_idle);
    rstream->fread_idle->data = NULL;
    handle_set_rstream((uv_handle_t *)rstream->fread_idle, rstream);
  } else {
    // Only pipes are supported for now
    assert(rstream->file_type == UV_NAMED_PIPE
        || rstream->file_type == UV_TTY);
    rstream->stream = xmalloc(sizeof(uv_pipe_t));
    uv_pipe_init(uv_default_loop(), (uv_pipe_t *)rstream->stream, 0);
    uv_pipe_open((uv_pipe_t *)rstream->stream, file);
    rstream->stream->data = NULL;
    handle_set_rstream((uv_handle_t *)rstream->stream, rstream);
  }

  rstream->fd = file;
  rstream->free_handle = true;
}
Пример #3
0
static void on_connection(uv_stream_t* server, int status) {
  uv_stream_t* stream;
  int r;

  if (status != 0) {
    fprintf(stderr, "Connect error %d\n", uv_last_error().code);
  }
  ASSERT(status == 0);

  switch (serverType) {
  case TCP:
    stream = malloc(sizeof(uv_tcp_t));
    ASSERT(stream != NULL);
    uv_tcp_init((uv_tcp_t*)stream);
    break;

  case PIPE:
    stream = malloc(sizeof(uv_pipe_t));
    ASSERT(stream != NULL);
    uv_pipe_init((uv_pipe_t*)stream);
    break;

  default:
    ASSERT(0 && "Bad serverType");
    abort();
  }

  /* associate server with stream */
  stream->data = server;

  r = uv_accept(server, stream);
  ASSERT(r == 0);

  r = uv_read_start(stream, echo_alloc, after_read);
  ASSERT(r == 0);
}
Пример #4
0
void stdinReadStart(WrenVM* vm)
{
  if (stdinStream == NULL)
  {
    if (uv_guess_handle(stdinDescriptor) == UV_TTY)
    {
      // stdin is connected to a terminal.
      uv_tty_t* handle = (uv_tty_t*)malloc(sizeof(uv_tty_t));
      uv_tty_init(getLoop(), handle, stdinDescriptor, true);
      stdinStream = (uv_stream_t*)handle;
    }
    else
    {
      // stdin is a pipe or a file.
      uv_pipe_t* handle = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
      uv_pipe_init(getLoop(), handle, false);
      uv_pipe_open(handle, stdinDescriptor);
      stdinStream = (uv_stream_t*)handle;
    }
  }

  uv_read_start(stdinStream, allocCallback, stdinReadCallback);
  // TODO: Check return.
}
Пример #5
0
static void connection_cb(uv_handle_t* s, int status) {
  uv_stream_t* stream;
  int r;

  ASSERT(server == s);
  ASSERT(status == 0);

  if (type == TCP) {
    stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t));
    uv_tcp_init((uv_tcp_t*)stream);
  } else {
    stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t));
    uv_pipe_init((uv_pipe_t*)stream);
  }

  r = uv_accept(s, stream);
  ASSERT(r == 0);

  r = uv_read_start(stream, buf_alloc, read_cb);
  ASSERT(r == 0);

  read_sockets++;
  max_read_sockets++;
}
Пример #6
0
int main(void)
{
	uv_loop_t loop;

	struct sockaddr_in addr;
	uv_connect_t connect_req;

	int fd, r;

	/* loop init */
	uv_loop_init(&loop);

#if USE_PIPE
	uv_pipe_init(&loop, &client, 1);
	uv_pipe_connect(&connect_req, &client, "/var/tmp/pipe.server1",
			connect_cb);

#else
	/*tcp socket initial */
	uv_ip4_addr("127.0.0.1", 4789, &addr);

	uv_tcp_init(&loop, &client);

	uv_tcp_connect(&connect_req, &client,
		       (const struct sockaddr *)&addr, connect_cb);
#endif

	r = uv_tty_init(&loop, &tty, 0, 1);
	printf("r=%d\n", r);
	uv_read_start((uv_stream_t *) & tty, alloc_cb, recv_cb);

	uv_run(&loop, UV_RUN_DEFAULT);

	printf("end\n");
	return 0;
}
Пример #7
0
Файл: luv.c Проект: Strongc/luv
LUALIB_API int luaopen_luv(lua_State *L) {

#ifndef WIN32
  signal(SIGPIPE, SIG_IGN);
#endif

  int i;
  uv_loop_t*    loop;
  luv_state_t*  curr;
  luv_object_t* stdfh;

  lua_settop(L, 0);

  /* register decoders */
  lua_pushcfunction(L, luvL_lib_decoder);
  lua_setfield(L, LUA_REGISTRYINDEX, "luv:lib:decoder");

#ifdef USE_ZMQ
  lua_pushcfunction(L, luvL_zmq_ctx_decoder);
  lua_setfield(L, LUA_REGISTRYINDEX, "luv:zmq:decoder");
#endif

  /* luv */
  luvL_new_module(L, "luv", luv_funcs);

  /* luv.thread */
  luvL_new_module(L, "luv_thread", luv_thread_funcs);
  lua_setfield(L, -2, "thread");
  luvL_new_class(L, LUV_THREAD_T, luv_thread_meths);
  lua_pop(L, 1);

  if (!MAIN_INITIALIZED) {
    luvL_thread_init_main(L);
    lua_pop(L, 1);
  }

  /* luv.fiber */
  luvL_new_module(L, "luv_fiber", luv_fiber_funcs);

  /* borrow coroutine.yield (fast on LJ2) */
  lua_getglobal(L, "coroutine");
  lua_getfield(L, -1, "yield");
  lua_setfield(L, -3, "yield");
  lua_pop(L, 1); /* coroutine */

  lua_setfield(L, -2, "fiber");

  luvL_new_class(L, LUV_FIBER_T, luv_fiber_meths);
  lua_pop(L, 1);

  /* luv.codec */
  luvL_new_module(L, "luv_codec", luv_codec_funcs);
  lua_setfield(L, -2, "codec");

  /* luv.timer */
  luvL_new_module(L, "luv_timer", luv_timer_funcs);
  lua_setfield(L, -2, "timer");
  luvL_new_class(L, LUV_TIMER_T, luv_timer_meths);
  lua_pop(L, 1);

  /* luv.idle */
  luvL_new_module(L, "luv_idle", luv_idle_funcs);
  lua_setfield(L, -2, "idle");
  luvL_new_class(L, LUV_IDLE_T, luv_idle_meths);
  lua_pop(L, 1);

  /* luv.fs */
  luvL_new_module(L, "luv_fs", luv_fs_funcs);
  lua_setfield(L, -2, "fs");
  luvL_new_class(L, LUV_FILE_T, luv_file_meths);
  lua_pop(L, 1);

  /* luv.pipe */
  luvL_new_module(L, "luv_pipe", luv_pipe_funcs);
  lua_setfield(L, -2, "pipe");
  luvL_new_class(L, LUV_PIPE_T, luv_stream_meths);
  luaL_register(L, NULL, luv_pipe_meths);
  lua_pop(L, 1);

  /* luv.std{in,out,err} */
  if (!MAIN_INITIALIZED) {
    MAIN_INITIALIZED = 1;
    loop = luvL_event_loop(L);
    curr = luvL_state_self(L);

    const char* stdfhs[] = { "stdin", "stdout", "stderr" };
    for (i = 0; i < 3; i++) {
#ifdef WIN32
      const uv_file fh = GetStdHandle(i == 0 ? STD_INPUT_HANDLE
       : (i == 1 ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE));
#else
      const uv_file fh = i;
#endif
      stdfh = (luv_object_t*)lua_newuserdata(L, sizeof(luv_object_t));
      luaL_getmetatable(L, LUV_PIPE_T);
      lua_setmetatable(L, -2);
      luvL_object_init(curr, stdfh);
      uv_pipe_init(loop, &stdfh->h.pipe, 0);
      uv_pipe_open(&stdfh->h.pipe, fh);
      lua_pushvalue(L, -1);
      lua_setfield(L, LUA_REGISTRYINDEX, stdfhs[i]);
      lua_setfield(L, -2, stdfhs[i]);
    }
  }

  /* luv.net */
  luvL_new_module(L, "luv_net", luv_net_funcs);
  lua_setfield(L, -2, "net");
  luvL_new_class(L, LUV_NET_TCP_T, luv_stream_meths);
  luaL_register(L, NULL, luv_net_tcp_meths);
  lua_pop(L, 1);

  /* luv.process */
  luvL_new_module(L, "luv_process", luv_process_funcs);
  lua_setfield(L, -2, "process");
  luvL_new_class(L, LUV_PROCESS_T, luv_process_meths);
  lua_pop(L, 1);

  /* luv.zmq */
#ifdef USE_ZMQ
  luvL_new_module(L, "luv_zmq", luv_zmq_funcs);
  const luv_const_reg_t* c = luv_zmq_consts;
  for (; c->key; c++) {
    lua_pushinteger(L, c->val);
    lua_setfield(L, -2, c->key);
  }
  lua_setfield(L, -2, "zmq");
  luvL_new_class(L, LUV_ZMQ_CTX_T, luv_zmq_ctx_meths);
  luvL_new_class(L, LUV_ZMQ_SOCKET_T, luv_zmq_socket_meths);
  lua_pop(L, 2);
#endif

  lua_settop(L, 1);
  return 1;
}
Пример #8
0
void spawn() {
  int i;
  char** env = NULL;

  env = env_copy(environ, env);

  child = malloc(sizeof(uv_process_t));
  uv_stdio_container_t stdio[4];
  uv_process_options_t options;

  uv_pipe_init(loop, &child_stdout, 0);
  uv_pipe_init(loop, &child_stderr, 0);
  uv_pipe_init(loop, &child_ipc, 0);

  //
  // Setup child's stdio. stdout and stderr are pipes so that we can read
  // child process' output.
  // FD 3 is a pipe used for IPC.
  //
  options.stdio_count = 4;
  stdio[0].flags = UV_INHERIT_FD;
  stdio[0].data.fd = 0;
  stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  stdio[1].data.stream = (uv_stream_t*) &child_stdout;
  stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  stdio[2].data.stream = (uv_stream_t*) &child_stderr;
  stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  stdio[3].data.stream = (uv_stream_t*) &child_ipc;

  options.env = env;
  options.cwd = NULL;
  options.file = arguments[0];
  options.args = arguments;
  options.flags = 0;
  options.stdio = stdio;
  options.exit_cb = on_process_exit;

  for (i = 0; i < PLUGIN_COUNT; i++) {
    if (plugins[i].process_options_cb) {
      plugins[i].process_options_cb(&options);
    }
  }

  if (uv_spawn(loop, child, options)) {
    fprintf(stderr, "uv_spawn: %s\n", uv_err_name(uv_last_error(loop)));
    return;
  }

  for (i = 0; i < PLUGIN_COUNT; i++) {
    if (plugins[i].process_spawned_cb) {
      plugins[i].process_spawned_cb(child, &options);
    }
  }

  uv_read_start(options.stdio[1].data.stream, forza__on_alloc, forza__on_stdout_read);
  uv_read_start(options.stdio[2].data.stream, forza__on_alloc, forza__on_stderr_read);
  uv_read_start(options.stdio[3].data.stream, forza__on_alloc, forza__on_ipc_read);

  // Switch to using `options->env` here instead of `env`, since plugins can
  // override `options->env` using, for example `env_set`, like in the start
  // plugin.
  env_free(options.env);
}
Пример #9
0
static int stdio_over_pipes_helper() {
  /* Write several buffers to test that the write order is preserved. */
  char* buffers[] = {
    "he",
    "ll",
    "o ",
    "wo",
    "rl",
    "d",
    "\n"
  };

  uv_write_t write_req[ARRAY_SIZE(buffers)];
  uv_buf_t buf[ARRAY_SIZE(buffers)];
  int r, i;
  uv_loop_t* loop = uv_default_loop();
  
  ASSERT(UV_NAMED_PIPE == uv_guess_handle(0));
  ASSERT(UV_NAMED_PIPE == uv_guess_handle(1));

  r = uv_pipe_init(loop, &stdin_pipe, 0);
  ASSERT(r == 0);
  r = uv_pipe_init(loop, &stdout_pipe, 0);
  ASSERT(r == 0);

  uv_pipe_open(&stdin_pipe, 0);
  uv_pipe_open(&stdout_pipe, 1);

  /* Unref both stdio handles to make sure that all writes complete. */
  uv_unref(loop);
  uv_unref(loop);

  for (i = 0; i < ARRAY_SIZE(buffers); i++) {
    buf[i] = uv_buf_init((char*)buffers[i], strlen(buffers[i]));
  }

  for (i = 0; i < ARRAY_SIZE(buffers); i++) {
    r = uv_write(&write_req[i], (uv_stream_t*)&stdout_pipe, &buf[i], 1,
      after_pipe_write);
    ASSERT(r == 0);
  }

  uv_run(loop);

  ASSERT(after_write_called == 7);
  ASSERT(on_pipe_read_called == 0);
  ASSERT(close_cb_called == 0);

  uv_ref(loop);
  uv_ref(loop);

  r = uv_read_start((uv_stream_t*)&stdin_pipe, on_pipe_read_alloc,
    on_pipe_read);
  ASSERT(r == 0);

  uv_run(loop);

  ASSERT(after_write_called == 7);
  ASSERT(on_pipe_read_called == 1);
  ASSERT(close_cb_called == 2);

  return 0;
}
Пример #10
0
/* u2_term_io_init(): initialize terminal.
*/
void
u2_term_io_init()
{
  u2_utty* uty_u = malloc(sizeof(u2_utty));

  if ( u2_yes == u2_Host.ops_u.dem ) {
    uty_u->fid_i = 1;

    uv_pipe_init(u2L, &(uty_u->pop_u), uty_u->fid_i);
    uv_pipe_open(&(uty_u->pop_u), uty_u->fid_i);
  }
  else {
    //  Initialize event processing.  Rawdog it.
    //
    {
      uty_u->fid_i = 0;                       //  stdin, yes we write to it...

      uv_poll_init(u2L, &(uty_u->wax_u), uty_u->fid_i);
      uv_poll_start(&(uty_u->wax_u),
                    UV_READABLE | UV_WRITABLE,
                    _term_poll_cb);
    }

    //  Configure horrible stateful terminfo api.
    //
    {
      if ( 0 != setupterm(0, 2, 0) ) {
        c3_assert(!"init-setupterm");
      }
    }

    //  Load terminfo strings.
    //
    {
      c3_w len_w;

#   define _utfo(way, nam) \
      { \
        uty_u->ufo_u.way.nam##_y = (const c3_y *) tigetstr(#nam); \
        c3_assert(uty_u->ufo_u.way.nam##_y); \
      }

      uty_u->ufo_u.inn.max_w = 0;

#if 1
      _utfo(inn, kcuu1);
      _utfo(inn, kcud1);
      _utfo(inn, kcub1);
      _utfo(inn, kcuf1);

      _utfo(out, clear);
      _utfo(out, el);
      // _utfo(out, el1);
      _utfo(out, ed);
      _utfo(out, bel);
      _utfo(out, cub1);
      _utfo(out, cuf1);
      _utfo(out, cuu1);
      _utfo(out, cud1);
      // _utfo(out, cub);
      // _utfo(out, cuf);
#else
      //  libuv hardcodes an ansi terminal - which doesn't seem to work...
      //
      uty_u->ufo_u.out.clear_y = "\033[H\033[J";
      uty_u->ufo_u.out.el_y = "\033[K";
      uty_u->ufo_u.out.ed_y = "\033[J";
      uty_u->ufo_u.out.bel_y = "\007";
      uty_u->ufo_u.out.cub1_y = "\010";
      uty_u->ufo_u.out.cud1_y = "\033[B";
      uty_u->ufo_u.out.cuu1_y = "\033[A";
      uty_u->ufo_u.out.cuf1_y = "\033[C";
#endif

      //  Terminfo chronically reports the wrong sequence for arrow
      //  keys on xterms.  Drastic fix for ridiculous unacceptable bug.
      //  Yes, we could fix this with smkx/rmkx, but this is retarded as well.
      {
        uty_u->ufo_u.inn.kcuu1_y = (const c3_y*)"\033[A";
        uty_u->ufo_u.inn.kcud1_y = (const c3_y*)"\033[B";
        uty_u->ufo_u.inn.kcuf1_y = (const c3_y*)"\033[C";
        uty_u->ufo_u.inn.kcub1_y = (const c3_y*)"\033[D";
      }

      uty_u->ufo_u.inn.max_w = 0;
      if ( (len_w = strlen((c3_c*)uty_u->ufo_u.inn.kcuu1_y)) >
            uty_u->ufo_u.inn.max_w )
      {
        uty_u->ufo_u.inn.max_w = len_w;
      }
      if ( (len_w = strlen((c3_c*)uty_u->ufo_u.inn.kcud1_y)) >
            uty_u->ufo_u.inn.max_w )
      {
        uty_u->ufo_u.inn.max_w = len_w;
      }
      if ( (len_w = strlen((c3_c*)uty_u->ufo_u.inn.kcub1_y)) >
            uty_u->ufo_u.inn.max_w )
      {
        uty_u->ufo_u.inn.max_w = len_w;
      }
      if ( (len_w = strlen((c3_c*)uty_u->ufo_u.inn.kcuf1_y)) >
            uty_u->ufo_u.inn.max_w )
      {
        uty_u->ufo_u.inn.max_w = len_w;
      }
    }

    //  Load old terminal state to restore.
    //
#if 1
    {
      if ( 0 != tcgetattr(uty_u->fid_i, &uty_u->bak_u) ) {
        c3_assert(!"init-tcgetattr");
      }
      if ( -1 == fcntl(uty_u->fid_i, F_GETFL, &uty_u->cug_i) ) {
        c3_assert(!"init-fcntl");
      }
      uty_u->cug_i &= ~O_NONBLOCK;                // could fix?
      uty_u->nob_i = uty_u->cug_i | O_NONBLOCK;   // O_NDELAY on older unix
    }

    //  Construct raw termios configuration.
    //
    {
      uty_u->raw_u = uty_u->bak_u;

      uty_u->raw_u.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
      uty_u->raw_u.c_iflag &= ~(ICRNL | INPCK | ISTRIP);
      uty_u->raw_u.c_cflag &= ~(CSIZE | PARENB);
      uty_u->raw_u.c_cflag |= CS8;
      uty_u->raw_u.c_oflag &= ~(OPOST);
      uty_u->raw_u.c_cc[VMIN] = 0;
      uty_u->raw_u.c_cc[VTIME] = 0;
    }
#endif

    //  Initialize mirror and accumulator state.
    //
    {
      uty_u->tat_u.mir.lin_w = 0;
      uty_u->tat_u.mir.len_w = 0;
      uty_u->tat_u.mir.cus_w = 0;

      uty_u->tat_u.esc.ape = u2_no;
      uty_u->tat_u.esc.bra = u2_no;

      uty_u->tat_u.fut.len_w = 0;
      uty_u->tat_u.fut.wid_w = 0;
    }
  }

  //  This is terminal 1, linked in host.
  //
  {
    uty_u->tid_l = 1;
    uty_u->out_u = 0;
    uty_u->tou_u = 0;

    uty_u->nex_u = u2_Host.uty_u;
    u2_Host.uty_u = uty_u;
    u2_Host.tem_u = uty_u;
  }

  if ( u2_no == u2_Host.ops_u.dem ) {
    //  Start raw input.
    //
    {
      if ( 0 != tcsetattr(uty_u->fid_i, TCSADRAIN, &uty_u->raw_u) ) {
        c3_assert(!"init-tcsetattr");
      }
      if ( -1 == fcntl(uty_u->fid_i, F_SETFL, uty_u->nob_i) ) {
        c3_assert(!"init-fcntl");
      }
    }
  }
}
Пример #11
0
 Pipe(const bool fd_pass = false):
     stream()
 {
     uv_pipe_init(uv_default_loop(), get(), fd_pass ? 1 : 0);
 }
Пример #12
0
 Pipe(loop& l, const bool fd_pass = false):
     stream()
 {
     uv_pipe_init(l.get(), get(), fd_pass ? 1 : 0);
 }
Пример #13
0
extern "C" int
rust_uv_pipe_init(uv_loop_t *loop, uv_pipe_t* p, int ipc) {
  return uv_pipe_init(loop, p, ipc);
}
Пример #14
0
bud_error_t bud_worker(bud_config_t* config) {
    int r;
    bud_error_t err;

    bud_log(config, kBudLogDebug, "worker starting");

    config->loop = uv_default_loop();
    config->ipc = malloc(sizeof(*config->ipc));
    config->signal.sighup = malloc(sizeof(*config->signal.sighup));
    if (config->ipc == NULL || config->signal.sighup == NULL) {
        err = bud_error_str(kBudErrNoMem, "config->ipc");
        goto fatal;
    }

    config->ipc->data = config;
    config->signal.sighup->data = config;

    r = uv_pipe_init(config->loop, config->ipc, 1);
    if (r != 0) {
        err = bud_error_num(kBudErrIPCPipeInit, r);
        goto fatal;
    }

    r = uv_pipe_open(config->ipc, 0);
    if (r != 0) {
        err = bud_error_num(kBudErrIPCPipeOpen, r);
        goto failed_pipe_open;
    }

    r = uv_read_start((uv_stream_t*) config->ipc,
                      bud_worker_alloc_cb,
                      bud_worker_read_cb);
    if (r != 0) {
        err = bud_error_num(kBudErrIPCReadStart, r);
        goto failed_pipe_open;
    }

#ifndef _WIN32
    /* Drop privileges */
    err = bud_config_drop_privileges(config);
    if (!bud_is_ok(err))
        goto failed_pipe_open;

    r = uv_signal_init(config->loop, config->signal.sighup);
    if (r != 0) {
        err = bud_error_num(kBudErrSignalInit, r);
        goto failed_pipe_open;
    }

    r = uv_signal_start(config->signal.sighup, bud_worker_signal_cb, SIGHUP);
    if (r != 0) {
        err = bud_error_num(kBudErrSignalInit, r);
        goto failed_signal_start;
    }
#endif  /* !_WIN32 */

    err = bud_ok();
    return err;

#ifndef _WIN32
failed_signal_start:
    uv_close((uv_handle_t*) config->signal.sighup, bud_worker_close_cb);
#endif  /* !_WIN32 */

failed_pipe_open:
    uv_close((uv_handle_t*) config->ipc, bud_worker_close_cb);
    goto cleanup;

fatal:
    free(config->ipc);

cleanup:
    config->ipc = NULL;
    return err;
}
Пример #15
0
MVMObject * MVM_file_openpipe(MVMThreadContext *tc, MVMString *cmd, MVMString *cwd, MVMObject *env, MVMString *err_path) {
    MVMint64 spawn_result = 0;
    uv_process_t *process = calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i;
    int status;
    int readable = 1;
    uv_pipe_t *out, *in;

    char * const cmdin = MVM_string_utf8_encode_C_string(tc, cmd);
    char * const _cwd = MVM_string_utf8_encode_C_string(tc, cwd);
    const MVMuint64 size = MVM_repr_elems(tc, env);
    MVMIter * const iter = (MVMIter *)MVM_iter(tc, env);
    char **_env = malloc((size + 1) * sizeof(char *));

#ifdef _WIN32
    const MVMuint16 acp = GetACP(); /* We should get ACP at runtime. */
    char * const _cmd = ANSIToUTF8(acp, getenv("ComSpec"));
    char *args[3];
    args[0] = "/c";
    {
        MVMint64 len = strlen(cmdin);
        MVMint64 i;
        for (i = 0; i < len; i++)
            if (cmdin[i] == '/')
                cmdin[i] = '\\';
    }
    args[1] = cmdin;
    args[2] = NULL;
#else
    char * const _cmd = "/bin/sh";
    char *args[4];
    args[0] = "/bin/sh";
    args[1] = "-c";
    args[2] = cmdin;
    args[3] = NULL;
#endif

    INIT_ENV();
    /* Making openpipe distinguish between :rp and :wp and all other options
     * is left as an excercise for the reader. 
    readable = strncmp(cmdin, "/usr/bin/wc", 11) != 0; */

    if (readable) {
        /* We want to read from the child's stdout. */
        out = malloc(sizeof(uv_pipe_t));
        uv_pipe_init(tc->loop, out, 0);
        uv_pipe_open(out, 0);
        process_stdio[0].flags       = UV_INHERIT_FD; // child's stdin
        process_stdio[0].data.fd     = 0;
        process_stdio[1].flags       = UV_CREATE_PIPE | UV_WRITABLE_PIPE; // child's stdout
        process_stdio[1].data.stream = (uv_stream_t*)out;
    }
    else {
        /* We want to print to the child's stdin. */
        in  = malloc(sizeof(uv_pipe_t));
        uv_pipe_init(tc->loop, in, 0);
        uv_pipe_open(in, 1);
        process_stdio[0].flags       = UV_CREATE_PIPE | UV_READABLE_PIPE; // child's stdin
        process_stdio[0].data.stream = (uv_stream_t*)in;
        process_stdio[1].flags       = UV_INHERIT_FD; // child's stdout
        process_stdio[1].data.fd     = 1;
    }
    process_stdio[2].flags      = UV_INHERIT_FD; // child's stderr
    process_stdio[2].data.fd    = 2;
    process_options.stdio       = process_stdio;
    process_options.file        = _cmd;
    process_options.args        = args;
    process_options.cwd         = _cwd;
    process_options.flags       = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS | UV_PROCESS_WINDOWS_HIDE;
    process_options.env         = _env;
    process_options.stdio_count = 3;
    process_options.exit_cb     = spawn_on_exit;
    uv_ref((uv_handle_t *)process);
    spawn_result = uv_spawn(tc->loop, process, &process_options);
    if (spawn_result) {
        FREE_ENV();
        free(_cwd);
        free(cmdin);
        uv_unref((uv_handle_t *)process);
        MVM_exception_throw_adhoc(tc, "Failed to open pipe: %d", errno);
    }

    FREE_ENV();
    free(_cwd);
    free(cmdin);
    uv_unref((uv_handle_t *)process);

    return MVM_io_syncpipe(tc, (uv_stream_t *)(readable ? out : in), process);
}
Пример #16
0
int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
{
  uv_stdio_container_t proc_stdio[3];
  uv_process_options_t proc_opts;
  uv_process_t proc;
  uv_pipe_t proc_stdin, proc_stdout;
  uv_write_t write_req;
  int expected_exits = 1;
  ProcessData pdata = {
    .reading = false,
    .exited = 0,
    .old_mode = cur_tmode,
    .old_state = State,
    .shell_stdin = (uv_stream_t *)&proc_stdin,
    .wbuffer = NULL,
  };

  out_flush();
  if (opts & kShellOptCooked) {
    // set to normal mode
    settmode(TMODE_COOK);
  }

  // While the child is running, ignore terminating signals
  signal_reject_deadly();

  // Create argv for `uv_spawn`
  // TODO(tarruda): we can use a static buffer for small argument vectors. 1024
  // bytes should be enough for most of the commands and if more is necessary
  // we can allocate a another buffer
  proc_opts.args = shell_build_argv(cmd, extra_shell_arg);
  proc_opts.file = proc_opts.args[0];
  proc_opts.exit_cb = exit_cb;
  // Initialize libuv structures
  proc_opts.stdio = proc_stdio;
  proc_opts.stdio_count = 3;
  // Hide window on Windows :)
  proc_opts.flags = UV_PROCESS_WINDOWS_HIDE;
  proc_opts.cwd = NULL;
  proc_opts.env = NULL;

  // The default is to inherit all standard file descriptors(this will change
  // when the UI is moved to an external process)
  proc_stdio[0].flags = UV_INHERIT_FD;
  proc_stdio[0].data.fd = 0;
  proc_stdio[1].flags = UV_INHERIT_FD;
  proc_stdio[1].data.fd = 1;
  proc_stdio[2].flags = UV_INHERIT_FD;
  proc_stdio[2].data.fd = 2;

  if (opts & (kShellOptHideMess | kShellOptExpand)) {
    // Ignore the shell stdio(redirects to /dev/null on unixes)
    proc_stdio[0].flags = UV_IGNORE;
    proc_stdio[1].flags = UV_IGNORE;
    proc_stdio[2].flags = UV_IGNORE;
  } else {
    State = EXTERNCMD;

    if (opts & kShellOptWrite) {
      // Write from the current buffer into the process stdin
      uv_pipe_init(uv_default_loop(), &proc_stdin, 0);
      write_req.data = &pdata;
      proc_stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
      proc_stdio[0].data.stream = (uv_stream_t *)&proc_stdin;
    }

    if (opts & kShellOptRead) {
      // Read from the process stdout into the current buffer
      uv_pipe_init(uv_default_loop(), &proc_stdout, 0);
      proc_stdout.data = &pdata;
      proc_stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
      proc_stdio[1].data.stream = (uv_stream_t *)&proc_stdout;
      ga_init(&pdata.ga, 1, BUFFER_LENGTH);
    }
  }

  if (uv_spawn(uv_default_loop(), &proc, &proc_opts)) {
    // Failed, probably due to `sh` not being executable
    if (!emsg_silent) {
      MSG_PUTS(_("\nCannot execute shell "));
      msg_outtrans(p_sh);
      msg_putchar('\n');
    }

    return proc_cleanup_exit(&pdata, &proc_opts, opts);
  }

  // Assign the flag address after `proc` is initialized by `uv_spawn`
  proc.data = &pdata;

  if (opts & kShellOptWrite) {
    // Queue everything for writing to the shell stdin
    write_selection(&write_req);
    expected_exits++;
  }

  if (opts & kShellOptRead) {
    // Start the read stream for the shell stdout
    uv_read_start((uv_stream_t *)&proc_stdout, alloc_cb, read_cb);
    expected_exits++;
  }

  // Keep running the loop until all three handles are completely closed
  while (pdata.exited < expected_exits) {
    uv_run(uv_default_loop(), UV_RUN_ONCE);

    if (got_int) {
      // Forward SIGINT to the shell
      // TODO(tarruda): for now this is only needed if the terminal is in raw
      // mode, but when the UI is externalized we'll also need it, so leave it
      // here
      uv_process_kill(&proc, SIGINT);
      got_int = false;
    }
  }

  if (opts & kShellOptRead) {
    if (pdata.ga.ga_len > 0) {
      // If there's an unfinished line in the growable array, append it now.
      append_ga_line(&pdata.ga);
      // remember that the NL was missing
      curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
    } else {
      curbuf->b_no_eol_lnum = 0;
    }
    ga_clear(&pdata.ga);
  }

  if (opts & kShellOptWrite) {
    free(pdata.wbuffer);
  }

  return proc_cleanup_exit(&pdata, &proc_opts, opts);
}

static int tokenize(char_u *str, char **argv)
{
  int argc = 0, len;
  char_u *p = str;

  while (*p != NUL) {
    len = word_length(p);

    if (argv != NULL) {
      // Fill the slot
      argv[argc] = xmalloc(len + 1);
      memcpy(argv[argc], p, len);
      argv[argc][len] = NUL;
    }

    argc++;
    p += len;
    p = skipwhite(p);
  }

  return argc;
}
Пример #17
0
static bool caerOutputUnixSocketServerInit(caerModuleData moduleData) {
	// First, always create all needed setting nodes, set their default values
	// and add their listeners.
	sshsNodeCreateString(moduleData->moduleNode, "socketPath", "/tmp/caer.sock", 2, PATH_MAX, SSHS_FLAGS_NORMAL,
		"Unix Socket path for writing output data (server mode, create new socket).");
	sshsNodeCreateInt(
		moduleData->moduleNode, "backlogSize", 5, 1, 32, SSHS_FLAGS_NORMAL, "Maximum number of pending connections.");
	sshsNodeCreateInt(moduleData->moduleNode, "concurrentConnections", 10, 1, 128, SSHS_FLAGS_NORMAL,
		"Maximum number of concurrent active connections.");

	// Allocate memory.
	size_t numClients         = (size_t) sshsNodeGetInt(moduleData->moduleNode, "concurrentConnections");
	outputCommonNetIO streams = malloc(sizeof(*streams) + (numClients * sizeof(uv_stream_t *)));
	if (streams == NULL) {
		caerModuleLog(moduleData, CAER_LOG_ERROR, "Failed to allocate memory for streams structure.");
		return (false);
	}

	streams->server = malloc(sizeof(uv_pipe_t));
	if (streams->server == NULL) {
		free(streams);

		caerModuleLog(moduleData, CAER_LOG_ERROR, "Failed to allocate memory for network server.");
		return (false);
	}

	// Initialize common info.
	streams->isTCP         = false;
	streams->isUDP         = false;
	streams->isPipe        = true;
	streams->activeClients = 0;
	streams->clientsSize   = numClients;
	for (size_t i = 0; i < streams->clientsSize; i++) {
		streams->clients[i] = NULL;
	}

	// Remember address.
	streams->address = sshsNodeGetString(moduleData->moduleNode, "socketPath");

	streams->server->data = streams;

	// Initialize loop and network handles.
	int retVal = uv_loop_init(&streams->loop);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_loop_init", free(streams->server);
				 free(streams->address); free(streams); return (false));

	retVal = uv_pipe_init(&streams->loop, (uv_pipe_t *) streams->server, false);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_pipe_init", uv_loop_close(&streams->loop);
				 free(streams->server); free(streams->address); free(streams); return (false));

	retVal = uv_pipe_bind((uv_pipe_t *) streams->server, streams->address);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_pipe_bind", libuvCloseLoopHandles(&streams->loop);
				 uv_loop_close(&streams->loop); free(streams->address); free(streams); return (false));

	retVal = uv_listen(
		streams->server, sshsNodeGetInt(moduleData->moduleNode, "backlogSize"), &caerOutputCommonOnServerConnection);
	UV_RET_CHECK(retVal, moduleData->moduleSubSystemString, "uv_listen", libuvCloseLoopHandles(&streams->loop);
				 uv_loop_close(&streams->loop); free(streams->address); free(streams); return (false));

	// Start.
	if (!caerOutputCommonInit(moduleData, -1, streams)) {
		libuvCloseLoopHandles(&streams->loop);
		uv_loop_close(&streams->loop);
		free(streams->address);
		free(streams);

		return (false);
	}

	return (true);
}
Пример #18
0
Файл: init.c Проект: aviks/julia
void *init_stdio_handle(uv_file fd,int readable)
{
    void *handle;
    uv_handle_type type = uv_guess_handle(fd);
    jl_uv_file_t *file;
#ifndef _OS_WINDOWS_
    // Duplicate the file descritor so we can later dup it over if we want to redirect
    // STDIO without having to worry about closing the associated libuv object.
    // On windows however, libuv objects remember streams by their HANDLE, so this is
    // unnessecary.
    fd = dup(fd);
#endif
    //printf("%d: %d -- %d\n", fd, type);
    switch(type)
    {
    case UV_TTY:
        handle = malloc(sizeof(uv_tty_t));
        if (uv_tty_init(jl_io_loop,(uv_tty_t*)handle,fd,readable)) {
            jl_errorf("Error initializing stdio in uv_tty_init (%d, %d)\n", fd, type);
            abort();
        }
        ((uv_tty_t*)handle)->data=0;
        uv_tty_set_mode((void*)handle,0); //cooked stdio
        break;
    case UV_FILE:
        file = malloc(sizeof(jl_uv_file_t));
        file->loop = jl_io_loop;
        file->type = UV_FILE;
        file->file = fd;
        file->data = 0;
        handle = file;
        break;
    case UV_NAMED_PIPE:
        handle = malloc(sizeof(uv_pipe_t));
        if (uv_pipe_init(jl_io_loop, (uv_pipe_t*)handle, (readable?UV_PIPE_READABLE:UV_PIPE_WRITABLE))) {
            jl_errorf("Error initializing stdio in uv_pipe_init (%d, %d)\n", fd, type);
            abort();
        }
        if (uv_pipe_open((uv_pipe_t*)handle,fd)) {
            jl_errorf("Error initializing stdio in uv_pipe_open (%d, %d)\n", fd, type);
            abort();
        }
        ((uv_pipe_t*)handle)->data=0;
        break;
    case UV_TCP:
        handle = malloc(sizeof(uv_tcp_t));
        if (uv_tcp_init(jl_io_loop, (uv_tcp_t*)handle)) {
            jl_errorf("Error initializing stdio in uv_tcp_init (%d, %d)\n", fd, type);
            abort();
        }
        if (uv_tcp_open((uv_tcp_t*)handle,fd)) {
            jl_errorf("Error initializing stdio in uv_tcp_open (%d, %d)\n", fd, type);
            abort();
        }
        ((uv_tcp_t*)handle)->data=0;
        break;
    case UV_UDP:
    default:
        jl_errorf("This type of handle for stdio is not yet supported (%d, %d)!\n", fd, type);
        handle = NULL;
        break;
    }
    return handle;
}
Пример #19
0
int job_start(char **argv,
              void *data,
              rstream_cb stdout_cb,
              rstream_cb stderr_cb,
              job_exit_cb job_exit_cb)
{
  int i;
  Job *job;

  // Search for a free slot in the table
  for (i = 0; i < MAX_RUNNING_JOBS; i++) {
    if (table[i] == NULL) {
      break;
    }
  }

  if (i == MAX_RUNNING_JOBS) {
    // No free slots
    return 0;
  }

  job = xmalloc(sizeof(Job));
  // Initialize
  job->id = i + 1;
  job->pending_refs = 3;
  job->pending_closes = 4;
  job->data = data;
  job->stdout_cb = stdout_cb;
  job->stderr_cb = stderr_cb;
  job->exit_cb = job_exit_cb;
  job->stopped = false;
  job->exit_timeout = EXIT_TIMEOUT;
  job->proc_opts.file = argv[0];
  job->proc_opts.args = argv;
  job->proc_opts.stdio = job->stdio;
  job->proc_opts.stdio_count = 3;
  job->proc_opts.flags = UV_PROCESS_WINDOWS_HIDE;
  job->proc_opts.exit_cb = exit_cb;
  job->proc_opts.cwd = NULL;
  job->proc_opts.env = NULL;
  job->proc.data = NULL;
  job->proc_stdin.data = NULL;
  job->proc_stdout.data = NULL;
  job->proc_stderr.data = NULL;

  // Initialize the job std{in,out,err}
  uv_pipe_init(uv_default_loop(), &job->proc_stdin, 0);
  job->stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
  job->stdio[0].data.stream = (uv_stream_t *)&job->proc_stdin;

  uv_pipe_init(uv_default_loop(), &job->proc_stdout, 0);
  job->stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  job->stdio[1].data.stream = (uv_stream_t *)&job->proc_stdout;

  uv_pipe_init(uv_default_loop(), &job->proc_stderr, 0);
  job->stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
  job->stdio[2].data.stream = (uv_stream_t *)&job->proc_stderr;

  // Spawn the job
  if (uv_spawn(uv_default_loop(), &job->proc, &job->proc_opts) != 0) {
    free_job(job);
    return -1;
  }

  // Give all handles a reference to the job
  handle_set_job((uv_handle_t *)&job->proc, job);
  handle_set_job((uv_handle_t *)&job->proc_stdin, job);
  handle_set_job((uv_handle_t *)&job->proc_stdout, job);
  handle_set_job((uv_handle_t *)&job->proc_stderr, job);

  job->in = wstream_new(JOB_WRITE_MAXMEM);
  wstream_set_stream(job->in, (uv_stream_t *)&job->proc_stdin);
  // Start the readable streams
  job->out = rstream_new(read_cb, JOB_BUFFER_SIZE, job, true);
  job->err = rstream_new(read_cb, JOB_BUFFER_SIZE, job, true);
  rstream_set_stream(job->out, (uv_stream_t *)&job->proc_stdout);
  rstream_set_stream(job->err, (uv_stream_t *)&job->proc_stderr);
  rstream_start(job->out);
  rstream_start(job->err);
  // Save the job to the table
  table[i] = job;

  // Start polling job status if this is the first
  if (job_count == 0) {
    uv_prepare_start(&job_prepare, job_prepare_cb);
  }
  job_count++;

  return job->id;
}
Пример #20
0
int ftw_libuv_spawn_process(struct ftw_libuv_callsite **callsite, LVUserEventRef *lv_event,
    char *exe, char *cmd, int64_t *exit_code, int64_t *signal)
{
    int rc;
    char *args [3];
    uv_loop_t loop;
    uv_pipe_t stdout_pipe;
    uv_pipe_t stderr_pipe;
    uv_process_t new_process;
    uv_process_options_t opts = {0};
    uv_stdio_container_t iostreams [3];
    struct ftw_libuv_process proc_data = {0};
    struct ftw_libuv_stream context;

    /*  Preconditions expected of LabVIEW. */
    ftw_assert(callsite && *callsite && lv_event && cmd);

    rc = uv_loop_init(&loop);
    if (rc) {
        return rc;
    }

    args[0] = exe;
    args[1] = cmd;
    args[2] = NULL;

    proc_data.exit_code = exit_code;
    proc_data.signal = signal;
    new_process.data = &proc_data;
    context.msg_to_lv_event = lv_event;
    stdout_pipe.data = &context;
    stderr_pipe.data = &context;

    rc = uv_pipe_init(&loop, &stdout_pipe, 0);
    if (rc) {
        uv_loop_close(&loop);
        return rc;
    }

    rc = uv_pipe_init(&loop, &stderr_pipe, 0);
    if (rc) {
        uv_loop_close(&loop);
        return rc;
    }

    opts.stdio_count = 3;
    opts.stdio = iostreams;
    opts.stdio[0].flags = UV_IGNORE;
    opts.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    opts.stdio[1].data.stream = (uv_stream_t *) &stdout_pipe;
    opts.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    opts.stdio[2].data.stream = (uv_stream_t *) &stderr_pipe;
    //opts.stdio[2].flags = UV_IGNORE;
    
    opts.file = exe;
    opts.args = args;
    opts.exit_cb = ftw_libuv_callback_process_exit;

    rc = uv_spawn(&loop, &new_process, &opts);
    if (rc) {
        uv_loop_close(&loop);
        return rc;
    }

    rc = uv_read_start((uv_stream_t*) &stdout_pipe, ftw_libuv_callback_alloc, ftw_libuv_callback_read_pipe);
    if (rc) {
        uv_loop_close(&loop);
        return rc;
    }

    rc = uv_read_start((uv_stream_t*) &stderr_pipe, ftw_libuv_callback_alloc, ftw_libuv_callback_read_pipe);
    if (rc) {
        uv_loop_close(&loop);
        return rc;
    }

    rc = uv_run(&loop, UV_RUN_DEFAULT);
    if (rc) {
        uv_loop_close(&loop);
        return rc;
    }

    rc = uv_loop_close(&loop);

    return rc;
}
Пример #21
0
static PyObject *
Pipe_func_write2(Pipe *self, PyObject *args)
{
    uv_buf_t buf;
    Py_buffer *view;
    PyObject *callback, *send_handle;

    callback = Py_None;

    RAISE_IF_HANDLE_NOT_INITIALIZED(self, NULL);
    RAISE_IF_HANDLE_CLOSED(self, PyExc_HandleClosedError, NULL);

    view = PyMem_Malloc(sizeof *view);
    if (!view) {
        PyErr_NoMemory();
        return NULL;
    }

#ifdef PYUV_PYTHON3
    if (!PyArg_ParseTuple(args, "y*O|O:write", view, &send_handle, &callback)) {
#else
    if (!PyArg_ParseTuple(args, "s*O|O:write", view, &send_handle, &callback)) {
#endif
        return NULL;
    }

    if (PyObject_IsSubclass((PyObject *)send_handle->ob_type, (PyObject *)&StreamType)) {
        if (UV_HANDLE(send_handle)->type != UV_TCP && UV_HANDLE(send_handle)->type != UV_NAMED_PIPE) {
            PyErr_SetString(PyExc_TypeError, "Only TCP and Pipe objects are supported for write2");
            goto error;
        }
    } else if (PyObject_IsSubclass((PyObject *)send_handle->ob_type, (PyObject *)&UDPType)) {
        /* empty */
    } else {
        PyErr_SetString(PyExc_TypeError, "Only Stream and UDP objects are supported");
        goto error;
    }

    if (callback != Py_None && !PyCallable_Check(callback)) {
        PyErr_SetString(PyExc_TypeError, "a callable or None is required");
        goto error;
    }

    buf = uv_buf_init(view->buf, view->len);

    return pyuv_stream_write((Stream *)self, view, &buf, 1, callback, send_handle);

error:
        PyBuffer_Release(view);
        PyMem_Free(view);
        return NULL;
}


static int
Pipe_tp_init(Pipe *self, PyObject *args, PyObject *kwargs)
{
    int r;
    Loop *loop;
    PyObject *ipc = Py_False;

    UNUSED_ARG(kwargs);

    RAISE_IF_HANDLE_INITIALIZED(self, -1);

    if (!PyArg_ParseTuple(args, "O!|O!:__init__", &LoopType, &loop, &PyBool_Type, &ipc)) {
        return -1;
    }

    r = uv_pipe_init(loop->uv_loop, (uv_pipe_t *)UV_HANDLE(self), (ipc == Py_True) ? 1 : 0);
    if (r != 0) {
        RAISE_UV_EXCEPTION(loop->uv_loop, PyExc_PipeError);
        return -1;
    }

    initialize_handle(HANDLE(self), loop);

    return 0;
}
Пример #22
0
void ::yajr::comms::internal::ActiveUnixPeer::retry() {

    if (destroying_) {

        LOG(INFO)
            << this
            << "Not retrying because of pending destroy"
        ;

        return;

    }
    if (uvRefCnt_ != 1) {
        LOG(INFO)
            << this
            << " has to wait for reference count to fall to 1 before retrying"
        ;

        insert(internal::Peer::LoopData::RETRY_TO_CONNECT);

        return;

    }

    int rc;
    if ((rc = uv_pipe_init(
                    getUvLoop(),
                    reinterpret_cast<uv_pipe_t *>(getHandle()),
                    0))) {
        LOG(WARNING)
            << "uv_pipe_init: ["
            << uv_err_name(rc)
            << "] "
            << uv_strerror(rc)
            ;
        onError(rc);
        insert(internal::Peer::LoopData::RETRY_TO_CONNECT);
        return;
    }
 
    /* potentially switch uv loop if some rebalancing is needed */
    uv_loop_t * newLoop = uvLoopSelector_(getData());

    if (newLoop != getHandle()->loop) {
        getLoopData()->down();
        getHandle()->loop = newLoop;
        getLoopData()->up();
    }

    /* uv_pipe_connect errors are always asynchronous */
    uv_pipe_connect(&connect_req_,
                    reinterpret_cast<uv_pipe_t *>(getHandle()),
                    socketName_.c_str(),
                    on_active_connection);
    /* workaround for libuv synchronous uv_pipe_connect() failures bug */
    getLoopData()->kickLibuv();

    up();
    status_ = Peer::kPS_CONNECTING;
    insert(internal::Peer::LoopData::ATTEMPTING_TO_CONNECT);

    VLOG(1)
        << this
        << " issued a pipe connect request: " << socketName_
    ;

}
Пример #23
0
void SysProcess::invoke()
{ 
    int r;
    char** args = NULL;

    //if ( this->directory_ == nullptr )
    //{
    //    char path[512] = { 0 };
    //    getcwd( path , 512 );
    //    int path_len = strlen( path );
    //    this->directory_ = new char[path_len + 1];
    //    memset( this->directory_ , 0 , path_len + 1 );
    //    memcpy( this->directory_ , path , strlen( path ) );
    //}
    printf( "File:%s\r\n" , this->file_ );
    if ( args_ == nullptr )
    {
        //char path[512] = { 0 };
        //getcwd( path , 512 );
        //args = new char*[2];
        //args[0] = ' ';
        //args[1] = NULL;
        //args[0] = new char[strlen( path ) + 1];
        //memset( args[0] , 0 , strlen( path ) + 1 );
        //memcpy( args[0] , path , strlen( path ) );
        //args[1] = NULL;
    } 
    else
    {
        args = new char*[64];
        for ( size_t i = 0; i < 64; i++ )
        {
            args[i] = new char[512];
            memset( args[i] , 0 , 512 );
            args[i][0] = ' ';
        }
        auto raw_args = this->args_;
        size_t len = strlen( this->args_ );

        int start_pos = 0; 

#ifdef _WIN32
        int row = 0;
#else
        int row = 0;
#endif
        int col = 0;
        bool has_dot = false;
        for ( int e = start_pos; e < len; e++ )
        {
            if ( raw_args[e] == '\'')
            {
                if ( has_dot )
                    has_dot = false;
                else
                    has_dot = true;
            }

            if ( raw_args[e] == ' ' && !has_dot)
            {
                printf( "Args:%s\r\n", args[row] );
                col = 0;
                row++; 
                args[row][col] = ' ';
                col = 1;
            }
            else 
            {
                args[row][col] = raw_args[e];
                col++;
            }
        }
         
        printf( "Args:%s\r\n" , args[row] );
        args[row+1] = NULL;
    }
    auto loop = uv_default_loop();
    this->pipe_ = { 0 };

    r = uv_pipe_init( loop , &this->pipe_ , 0 );
     
    this->pipe_.data = this;
    
    this->options.exit_cb = SysProcess::uv_process_exit_callback;
    this->options.file = this->file_;
    this->options.args = args;
    this->options.cwd = this->directory_;
    this->child_req.data = this;

    this->options.stdio_count = 3;
    uv_stdio_container_t child_stdio[3];

    // ( uv_stdio_flags )( UV_CREATE_PIPE | UV_READABLE_PIPE );
    child_stdio[0].flags = UV_IGNORE;

    child_stdio[1].flags = ( uv_stdio_flags )( UV_CREATE_PIPE | UV_WRITABLE_PIPE );
    child_stdio[1].data.stream = ( uv_stream_t* )&this->pipe_;

    child_stdio[2].flags = UV_IGNORE;

    this->options.stdio = child_stdio;
    
    r  = uv_spawn( loop , &this->child_req , &this->options );
    if ( r != 0 )
    {
        printf( "uv_spawn: %s\r\n" , uv_strerror( r ) );
    }

    r = uv_read_start( ( uv_stream_t* )&this->pipe_ ,
                       SysProcess::uv_process_alloc_buffer , 
                       SysProcess::uv_prcoess_read_stream );
    if ( r != 0 )
    {
        printf( "uv_read_start: %s\r\n" , uv_strerror( r ) );
    }

    delete[] args;
}