[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Creating LUA_FILEHANDLES is causing seg faults
- From: Sean Bolton <sean@...>
- Date: Fri, 10 May 2013 19:28:37 -0700
Hi Sean,
On Fri May 10 2013, Sean Conner wrote:
> I wrote a function that calls pipe() [1]. Once that succeeds, I call
> fdopen() [2] on each file descriptor, and then I create
> LUA_FILEHANDLES from these and return both of them (in a table). The
> create portion is fine, but when I try to close one of the pipes:
>
> [spc]lucy:/tmp>lua luafilehandle.lua
> 2011
> about to create
>
> file (0x96647e8) file (0x967b148)
> about to close read
>
> Segmentation fault (core dumped)
[snip]
> Is there something I should be doing? Code below.
Yes, you're not setting the environment of the file handle userdata, or
better yet, of my_pipe() (so that all userdata created by it inherit
the correct environment). It's from the file handle object's environment
that Lua 5.1.x gets the function to use to close the handle. Since your
userdata don't have that set, the close crashes. Grep for 'fenv' in
liolib.c for more information. (Note that 5.2 uses a different
scheme.) HTH,
-Sean
> -- ************* [ Code starts here ] **********************
>
> cc = require "org.conman.cc"
>
> getpid = cc.compile("my_getpid",[[
> #include <unistd.h>
> #include <lua.h>
>
> int my_getpid(lua_State *L)
> {
> lua_pushnumber(L,getpid());
> return 1;
> }
> ]])
>
> pipe = cc.compile("my_pipe",[[
> #include <stdio.h>
> #include <errno.h>
> #include <unistd.h>
> #include <lua.h>
> #include <lauxlib.h>
> #include <lualib.h>
>
> int my_pipe(lua_State *L)
> {
> FILE **pfpread;
> FILE **pfpwrite;
> FILE *fpr;
> FILE *fpw;
> int fh[2];
> char *rm;
> char *wm;
>
> if (lua_isboolean(L,1))
> {
> rm = "rb";
> wm = "wb";
> }
> else
> {
> rm = "r";
> wm = "w";
> }
>
> if (pipe(fh) < 0)
> {
> lua_pushnil(L);
> lua_pushinteger(L,errno);
> return 2;
> }
>
> fpr = fdopen(fh[0],rm);
> if (fpr == NULL)
> {
> lua_pushnil(L);
> lua_pushinteger(L,errno);
> close(fh[0]);
> close(fh[1]);
> return 2;
> }
>
> fpw = fdopen(fh[1],wm);
> if (fpw == NULL)
> {
> lua_pushnil(L);
> lua_pushinteger(L,errno);
> fclose(fpr);
> close(fh[1]);
> return 2;
> }
>
> lua_createtable(L,0,2);
>
> pfpread = lua_newuserdata(L,sizeof(FILE *));
> *pfpread = fpr;
> luaL_getmetatable(L,LUA_FILEHANDLE);
> lua_setmetatable(L,-2);
> lua_setfield(L,-2,"read");
>
> pfpwrite = lua_newuserdata(L,sizeof(FILE *));
> *pfpwrite = fpw;
> luaL_getmetatable(L,LUA_FILEHANDLE);
> lua_setmetatable(L,-2);
> lua_setfield(L,-2,"write");
>
> lua_pushinteger(L,0);
> return 2;
> }
> ]])
>
> print(getpid())
>
> print("about to create") io.stdin:read()
> x = pipe()
> print(x.read,x.write)
> print("about to close read") io.stdin:read()
> print(x.read:close())
> print("about to close write") io.stdin:read()
> print(x.write:close())
> print("about to exit") io.stdin:read()
>