Пример #1
0
static void LuaIO_process_onexit(uv_process_t* handle, int64_t status, int signal) {
  if (handle->data) {
    LuaIO_process_data_t* data = handle->data;
    fprintf(stderr,
            "process[%d] exit. status: %" PRId64 ", signal: %d, file: %s\n",
            handle->pid,
            status,
            signal,
            data->options->args[1]);

    data->options->file = LuaIO_process_exepath_ptr;
    data->options->args[0] = LuaIO_process_exepath_ptr;

    uv_process_t* process = (uv_process_t*) LuaIO_malloc(sizeof(uv_process_t));
    if (!process) {
      LuaIO_process_free_options(data->options);
      luaL_unref(LuaIO_get_main_thread(), LUA_REGISTRYINDEX, data->options_ref);
      LuaIO_free(data);
      fprintf(stderr,
              "process[%s] restart failed. no more memory for process\n", 
              data->options->args[1]);
    }
    LuaIO_memzero(process, sizeof(uv_process_t));
    process->data = data;

    int ret = uv_spawn(uv_default_loop(), process, data->options);
    if (ret < 0) {
      LuaIO_process_free_options(data->options);
      luaL_unref(LuaIO_get_main_thread(), LUA_REGISTRYINDEX, data->options_ref);
      LuaIO_free(data);
      uv_close((uv_handle_t*)process, NULL);
      fprintf(stderr,
              "process[%s] restart failed. uv_spawn() error: %s\n",
              data->options->args[1],
              uv_strerror(ret));
    }

    if (data->cpu >= 0) LuaIO_set_affinity(process->pid, data->cpu);

    return;
  }
    
  fprintf(stderr, 
          "process[%d] exit. status: %" PRId64 ", signal: %d\n",
          handle->pid,
          status,
          signal);
  
  uv_close((uv_handle_t*)handle, NULL);
}
Пример #2
0
static int LuaIO_process_exec(lua_State* L) {
  const char* cmd;
  if (lua_type(L, 1) == LUA_TSTRING) {
    cmd = lua_tostring(L, 1);
  } else {
    return luaL_argerror(L, 2, "process.exec(cmd) error: cmd is required and must be [string]\n"); 
  }

  /*shell, -c, cmd, null*/
  char** args = LuaIO_malloc(sizeof(char*) * 4);
  args[0] = "/bin/sh";
  args[1] = "-c";
  args[2] = (char*)cmd;
  args[3] = NULL;

  if (!LuaIO_process_stdio_ptr) { 
    LuaIO_process_stdio[0].flags = UV_INHERIT_FD;
    LuaIO_process_stdio[0].data.fd = 0;
    LuaIO_process_stdio[1].flags = UV_INHERIT_FD;
    LuaIO_process_stdio[1].data.fd = 1;
    LuaIO_process_stdio[2].flags = UV_INHERIT_FD;
    LuaIO_process_stdio[2].data.fd = 2;
    LuaIO_process_stdio_ptr = LuaIO_process_stdio;
  }

  uv_process_options_t* options = LuaIO_malloc(sizeof(uv_process_options_t));
  if (!options) {
    LuaIO_free(args);
    return luaL_error(L, "process.exec(cmd) error: no memory for uv_process_options_t options\n");
  }
  LuaIO_memzero(options, sizeof(uv_process_options_t));
  options->exit_cb = LuaIO_process_onexit;
  options->file = "/bin/sh";
  options->args = args;
  options->stdio_count = 3;
  options->stdio = LuaIO_process_stdio_ptr;

  uv_process_t* handle = LuaIO_malloc(sizeof(uv_process_t));
  if (!handle) {
    LuaIO_process_free_options(options);
    return luaL_error(L, "process.exec(cmd) error: no memory for uv_process_t handle\n");
  }
  LuaIO_memzero(handle, sizeof(uv_process_t));

  int ret = uv_spawn(uv_default_loop(), handle, options);
  if (ret < 0) {
    LuaIO_process_free_options(options);
    uv_close((uv_handle_t*)handle, NULL);
    return luaL_error(L, "process.exec(cmd) uv_spawn() error: %s\n", uv_strerror(ret));
  }

  if (!LuaIO_process_signal_ptr) {
    uv_signal_init(uv_default_loop(), &LuaIO_process_signal);
    LuaIO_process_signal_ptr = &LuaIO_process_signal;
    uv_signal_start(LuaIO_process_signal_ptr, LuaIO_process_signal_callback, SIGQUIT);
  }

  lua_pushinteger(L, handle->pid);
  return 1;
}
Пример #3
0
Файл: timer.c Проект: ifzz/LuaIO
void LuaIO_timer_free(uv_timer_t* timer) {
  if (timer != NULL) {
    LuaIO_timer_t* LuaIO_timer = LuaIO_list_entry(timer, LuaIO_timer_t, timer);

    if (LuaIO_timer_pool.free_timers < LuaIO_timer_pool.max_free_timers) {
      LuaIO_list_insert_head(&LuaIO_timer->list, &(LuaIO_timer_pool.free_list));
      LuaIO_timer_pool.free_timers++;
    } else {
      LuaIO_free(LuaIO_timer);
    }
  }
}
Пример #4
0
void LuaIO_pool_free(LuaIO_pool_t* pool, void* p) {
  if (p != NULL) {
    LuaIO_pool_chunk_t* chunk = (LuaIO_pool_chunk_t*)((char*)p - sizeof(LuaIO_pool_chunk_t));
    
    if (pool->free_chunks < pool->max_free_chunks) {
      LuaIO_list_insert_head(&chunk->list, &pool->free_list);
      pool->free_chunks++;
    } else {
      LuaIO_free(chunk);
    }
  }
}
Пример #5
0
void LuaIO_pmemory__free(void *p) {
  if (p != NULL) {
    LuaIO_pool_chunk_t *chunk = (LuaIO_pool_chunk_t*)((char*)p - sizeof(LuaIO_pool_chunk_t));
    if (chunk->magic == LUAIO_PMEMORY_MAGIC) {
      LuaIO_free(chunk);
      return;
    }
   
    assert(chunk->magic != LUAIO_POOL_MAGIC);
    assert(chunk->magic < LUAIO_PMEMORY_SLOT_SIZE);

    LuaIO_pool_free(&LuaIO_pmemory_slots[chunk->magic], p);
  }
}
Пример #6
0
static int LuaIO_process_fork(lua_State* L) {
  if (lua_type(L, 1) != LUA_TTABLE) {
    return luaL_argerror(L, 1, "process.fork(options) error: options must be [table]\n"); 
  }

  if (!LuaIO_process_exepath_ptr) {
    size_t length = sizeof(LuaIO_process_exepath);
    int err = uv_exepath(LuaIO_process_exepath, &length);
    if (err < 0) {
      return luaL_error(L, "process.fork(options) uv_exepath() error: %s\n", uv_strerror(err));
    }

    LuaIO_process_exepath_ptr = LuaIO_process_exepath;
  }

  lua_getfield(L, 1, "file");
  const char* file;
  if (lua_type(L, -1) == LUA_TSTRING) {
    file = lua_tostring(L, -1);
  } else {
    return luaL_argerror(L, 2, "process.fork(options) error: options.file is required and must be [string]\n"); 
  }
  lua_pop(L, 1);

  lua_getfield(L, 1, "args");
  size_t args_length = 0;
  char** args = NULL;
  if (lua_type(L, -1) == LUA_TTABLE) {
    args_length = lua_rawlen(L, -1);
    /*execpath, file, null => args_length + 3*/
    args = LuaIO_malloc(sizeof(char*) * (args_length + 3));
    if (!args) {
      return luaL_error(L, "process.fork(options) error: no memory for args\n");
    }

    for (size_t i = 1; i <= args_length; ++i) {
      lua_rawgeti(L, -1, i);
      args[i + 1] = (char*)luaL_checkstring(L, -1);
      lua_pop(L, 1);
    }
  } else if (lua_type(L, -1) == LUA_TNIL) {
    /*execpath, file, null => args_length + 3*/
    args = LuaIO_malloc(sizeof(char*) * 3);
    if (!args) {
      return luaL_error(L, "process.fork(options) error: no memory for args\n");
    }
  } else {
    return luaL_argerror(L, 2, "process.fork(options) error: options.args must be [table]\n"); 
  }
  lua_pop(L, 1);

  args[0] = LuaIO_process_exepath_ptr;
  args[1] = (char*)file;
  args[args_length + 2] = NULL;

  if (!LuaIO_process_stdio_ptr) { 
    LuaIO_process_stdio[0].flags = UV_INHERIT_FD;
    LuaIO_process_stdio[0].data.fd = 0;
    LuaIO_process_stdio[1].flags = UV_INHERIT_FD;
    LuaIO_process_stdio[1].data.fd = 1;
    LuaIO_process_stdio[2].flags = UV_INHERIT_FD;
    LuaIO_process_stdio[2].data.fd = 2;
    LuaIO_process_stdio_ptr = LuaIO_process_stdio;
  }

  uv_process_options_t* options = LuaIO_malloc(sizeof(uv_process_options_t));
  if (!options) {
    LuaIO_free(args);
    return luaL_error(L, "process.fork(options) error: no memory for uv_process_options_t options\n");
  }
  LuaIO_memzero(options, sizeof(uv_process_options_t));
  options->exit_cb = LuaIO_process_onexit;
  options->file = LuaIO_process_exepath_ptr;
  options->args = args;
  options->stdio_count = 3;
  options->stdio = LuaIO_process_stdio_ptr;

  lua_getfield(L, 1, "uid");
  if (lua_type(L, -1) == LUA_TNUMBER) {
    options->uid = lua_tointeger(L, -1);
    options->flags |= UV_PROCESS_SETUID;
  } else if (lua_type(L, -1) != LUA_TNIL) {
    LuaIO_process_free_options(options);
    return luaL_argerror(L, 2, "process.fork(options) error: options.uid must be [number]\n"); 
  }
  lua_pop(L, 1);

  lua_getfield(L, 1, "gid");
  if (lua_type(L, -1) == LUA_TNUMBER) {
    options->gid = lua_tointeger(L, -1);
    options->flags |= UV_PROCESS_SETGID;
  } else if (lua_type(L, -1) != LUA_TNIL) {
    LuaIO_process_free_options(options);
    return luaL_argerror(L, 2, "process.fork(options) error: options.gid must be [number]\n"); 
  }
  lua_pop(L, 1);

  lua_getfield(L, 1, "detached");
  if (lua_toboolean(L, -1)) {
    options->flags |= UV_PROCESS_DETACHED;
  }
  lua_pop(L, 1);

  lua_getfield(L, 1, "forever");
  int forever = lua_toboolean(L, -1);
  lua_pop(L, 1);
  
  int cpu = -1; 
  lua_getfield(L, 1, "cpu");
  if (lua_type(L, -1) == LUA_TNUMBER) {
    cpu = lua_tointeger(L, -1);
  } else if (lua_type(L, -1) != LUA_TNIL) {
    LuaIO_process_free_options(options);
    return luaL_argerror(L, 2, "process.fork(options) error: options.cpu must be [number]\n"); 
  }
  lua_pop(L, 1);

  uv_process_t* handle = LuaIO_malloc(sizeof(uv_process_t));
  if (!handle) {
    LuaIO_process_free_options(options);
    return luaL_error(L, "process.fork(options) error: no memory for uv_process_t handle.\n");
  }
  LuaIO_memzero(handle, sizeof(uv_process_t));

  LuaIO_process_data_t* data = NULL;
  if (forever) {
    data = LuaIO_malloc(sizeof(LuaIO_process_data_t));
    if (!data) {
      LuaIO_process_free_options(options);
      return luaL_error(L, "process.fork(options) error:no memory for LuaIO_process_data_t data.\n");
    }
    
    lua_pushvalue(L, 1);
    data->options_ref = luaL_ref(L, LUA_REGISTRYINDEX);
    data->options = options;
    data->cpu = cpu;
    handle->data = data;
  }

  int ret = uv_spawn(uv_default_loop(), handle, options);
  if (ret < 0) {
    LuaIO_process_free_options(options);
    luaL_unref(L, LUA_REGISTRYINDEX, data->options_ref);
    LuaIO_free(data);
    uv_close((uv_handle_t*)handle, NULL);
    return luaL_error(L, "process.fork(options) uv_spawn() error: %s\n", uv_strerror(ret));
  }
  if (cpu >= 0) LuaIO_set_affinity(handle->pid, cpu);

  if (!LuaIO_process_signal_ptr) {
    uv_signal_init(uv_default_loop(), &LuaIO_process_signal);
    LuaIO_process_signal_ptr = &LuaIO_process_signal;
    uv_signal_start(LuaIO_process_signal_ptr, LuaIO_process_signal_callback, SIGQUIT);
  }

  lua_pushinteger(L, handle->pid);

  return 1;
}
Пример #7
0
static void LuaIO_timer_onclose(uv_handle_t *handle) {
  LuaIO_timer_t *LuaIO_timer = container_of(handle, LuaIO_timer_t, timer);
  LuaIO_free(LuaIO_timer);
}