Skip to content

Commit

Permalink
Merge pull request luvit#235 from brimworks/issue-204
Browse files Browse the repository at this point in the history
Fix luvit#204: sparse stdio in process:spawn()
  • Loading branch information
creationix committed May 5, 2017
2 parents 33d33a6 + 291c026 commit 10ba50a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/luv.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@
# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l))
# define lua_resume(L,F,n) lua_resume(L,n)
# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
# define lua_absindex(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? \
(i) : lua_gettop(L) + (i) + 1)
#endif

/* There is a 1-1 relation between a lua_State and a uv_loop_t
Expand Down
25 changes: 24 additions & 1 deletion src/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ static void luv_clean_options(uv_process_options_t* options) {
free(options->env);
}

// iterates over the tbl to find the max integer
// key of the table that is >= 1. If any key is
// NOT an integer, simply call lua_rawlen().
static int sparse_rawlen(lua_State* L, int tbl) {
int len = 0;
tbl = lua_absindex(L, tbl);

lua_pushnil(L);
while (lua_next(L, -2)) {
if (lua_type(L, -2) == LUA_TNUMBER) {
int idx = lua_tonumber(L, -2);
if (floor(idx) == idx && idx >= 1) {
if (idx > len) len = idx;
lua_pop(L, 1);
continue;
}
}
lua_pop(L, 2);
return lua_rawlen(L, tbl);
}
return len;
}

static int luv_spawn(lua_State* L) {
uv_process_t* handle;
uv_process_options_t options;
Expand Down Expand Up @@ -92,7 +115,7 @@ static int luv_spawn(lua_State* L) {
// get the stdio list
lua_getfield(L, 2, "stdio");
if (lua_type(L, -1) == LUA_TTABLE) {
options.stdio_count = len = lua_rawlen(L, -1);
options.stdio_count = len = sparse_rawlen(L, -1);
options.stdio = (uv_stdio_container_t*)malloc(len * sizeof(*options.stdio));
if (!options.stdio) {
luv_clean_options(&options);
Expand Down

0 comments on commit 10ba50a

Please sign in to comment.