Skip to content
Permalink
Browse files
Bug fix for pipe:out_get() and variants
I didn't know userdata get a default environment table and
my assumptions made every pipe userdata share the same
table... This fixes issue #1 reported by Alex Bradbury.
  • Loading branch information
xolox committed Dec 1, 2010
1 parent fb29d9b commit 14efa65
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 18 deletions.
@@ -3,10 +3,10 @@
Lua source code for the Lua/APR binding.
Author: Peter Odding <peter@peterodding.com>
Last Change: October 27, 2010
Last Change: December 1, 2010
Homepage: http://peterodding.com/code/lua/apr/
License: MIT
Version: 0.9.5
Version: 0.9.6
This Lua script is executed on require("apr"), loads the binary module using
require("apr.core"), defines several library functions implemented on top of
@@ -15,7 +15,7 @@
--]]

local apr = require 'apr.core'
apr._VERSION = '0.9.5'
apr._VERSION = '0.9.6'

-- apr.filepath_which(program [, find_all]) -> pathname {{{1
--
@@ -1,7 +1,7 @@
/* Initialization and miscellaneous routines for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: October 26, 2010
* Last Change: December 1, 2010
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/
@@ -277,15 +277,32 @@ int push_error_status(lua_State *L, apr_status_t status)

void *new_object(lua_State *L, lua_apr_type *T)
{
void *object = lua_newuserdata(L, T->objsize);
void *object;

object = lua_newuserdata(L, T->objsize);
if (object != NULL) {
memset(object, 0, T->objsize);
get_metatable(L, T);
lua_setmetatable(L, -2);
getdefaultenv(L);
lua_setfenv(L, -2);
}
return object;
}

void getdefaultenv(lua_State *L) /* {{{1 */
{
const char *key = "Lua/APR default environment for userdata";

lua_getfield(L, LUA_REGISTRYINDEX, key);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
lua_newtable(L);
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, key);
}
}

/* check_object() validates objects created by new_object(). {{{1 */

void *check_object(lua_State *L, int idx, lua_apr_type *T)
@@ -1,7 +1,7 @@
/* Header file for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: October 26, 2010
* Last Change: December 1, 2010
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/
@@ -177,6 +177,7 @@ int status_to_message(lua_State*, apr_status_t);
int push_status(lua_State*, apr_status_t);
int push_error_status(lua_State*, apr_status_t);
void *new_object(lua_State*, lua_apr_type*);
void getdefaultenv(lua_State*);
void *check_object(lua_State*, int, lua_apr_type*);
int get_metatable(lua_State*, lua_apr_type*);

@@ -1,7 +1,7 @@
/* Process handling module for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: October 23, 2010
* Last Change: December 1, 2010
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/
@@ -46,18 +46,22 @@ static lua_apr_proc *proc_check(lua_State *L, int i)
return check_object(L, i, &lua_apr_proc_type);
}

/* getoenv(L) -- get/create environment table for userdata {{{2 */
/* getuenv(L) -- get/create environment table for userdata {{{2 */

static int getoenv(lua_State *L)
static int getuenv(lua_State *L)
{
lua_getfenv(L, 1); /* get environment table */
if (lua_type(L, -1) == LUA_TTABLE)
lua_getfenv(L, 1); /* get current environment table */
getdefaultenv(L); /* get default environment table */
if (!lua_equal(L, -1, -2)) {
lua_pop(L, 1);
return 1;
lua_pop(L, 1); /* pop nil result from lua_getfenv() */
lua_newtable(L); /* create environment table */
lua_pushvalue(L, -1); /* copy reference to table */
lua_setfenv(L, 1); /* install environment table */
return 0;
} else {
lua_pop(L, 2);
lua_newtable(L); /* create environment table */
lua_pushvalue(L, -1); /* copy reference to table */
lua_setfenv(L, 1); /* install environment table */
return 0;
}
}

/* get_pipe(L, file, key) -- return standard input/output/error pipe {{{2 */
@@ -66,7 +70,7 @@ static int get_pipe(lua_State *L, apr_file_t *handle, const char *key)
{
lua_apr_file *file;

if (getoenv(L)) {
if (getuenv(L)) {
lua_getfield(L, -1, key); /* get cached pipe object */
if (lua_type(L, -1) == LUA_TUSERDATA)
return 1; /* return cached pipe object */
@@ -98,7 +102,7 @@ static int set_pipe(lua_State *L, const char *ck, const char *pk, lua_apr_setpip
parent = file_check(L, 3, 1)->handle;

/* Make sure pipe(s) aren't garbage collected while process is alive! */
getoenv(L); /* process, child_pipe, parent_pipe, environment */
getuenv(L); /* process, child_pipe, parent_pipe, environment */
lua_insert(L, 1); /* environment, process, child_pipe, parent_pipe */
lua_setfield(L, 1, pk); /* environment, process, child_pipe */
lua_setfield(L, 1, ck); /* environment, process */

0 comments on commit 14efa65

Please sign in to comment.