lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hmm, alright -- "it's by design".  I copied out newfile() and io_closef() in my own project I wanted to be sure that I would not invite potential problems by rolling my own.

https://github.com/Pogs/lsock/blob/master/lsock.c#L800

Not sure what I meant by manipulating file handle objects really, it's just important to be able to create files and close them.  Because luaL_Stream/LStream wasn't in the manual and I had to go digging into the source it felt like something that was intended to not be used.

My point is that it might be nice to have these function to make sure that everyone creates their file handle userdatas in the same way (maybe it belongs it would go in the auxiliary lib?):

void * luaL_newfile(lua_State *);
void luaL_closefile(lua_State *);

extra?
FILE * luaL_getFILE(void *);
void luaL_setFILE(void *);

You're telling me I should perform those 4 steps (create the userdata, set the metatable, assign the stream to f, roll my own closef() and assign it) -- I'm saying this basic procedure will be done improperly by someone and we'll have the same issue.  Instead of people rolling their own different file handle type we'll have the same userdata but improperly "formed". :>

newfile() should take care of assigning the internal io_fclose() function address, closefile() would be for closing the file without the user knowing how luaL_Stream is defined.  getFile()/setFile() are just extras -- unnecessary of the LStream structure were documented in the manual...

I obsess too much, I think :\  Bad ideas?


On Fri, Nov 15, 2013 at 4:31 PM, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
> LUA_FILEHANDLE is a preprocessor definition in lauxlib.h, which is just
> "FILE*"
>
> So what this means is luaL_checkudata() gets the metatable of the userdata
> object (if it has one), and checks to see that it matches the table
> referenced by the key "FILE*" in the registry table.
>
> Lua file handles themselves are called luaL_Stream's or just LStream's
> (there's a typedef in liolib.c[2]).
>
> typedef struct luaL_Stream {
>   FILE *f;  /* stream (NULL for incompletely created streams) */
>   lua_CFunction closef;  /* to close stream (NULL for closed streams) */
> } luaL_Stream;
>
> ^ found in lauxlib.h[3]
>
> Lua file handles, in their C form are just ANSI C FILE *'s and a pointer to
> the function to close them (io_fclose() in liolib.c[4]).
>
> To create a Lua file handle you would need to call newfile() in
> liolib.c[5], but this function is static and therefore not exposed.

You do not need to call newfile. Lua exports everything you need to create
your own files. All you have to do is this:

- call lua_newuserdata(L, sizeof(LStream)) to create a userdata
- set its metatable with luaL_setmetatable(L, LUA_FILEHANDLE)
- set its 'f' to your stream
- set its 'closef' to the function that will close your stream

Everything here (lua_newuserdata, LStream, luaL_setmetatable,
and LUA_FILEHANDLE) is public on purpose. Because LUA_FILEHANDLE and
LStream are public, you can also write your own functions to manipulate
files (and they will work with native Lua files too).

-- Roberto