lua-users home
lua-l archive

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


If you need to share file objects between C code and Lua code I for
one would consider just grabbing open() from the global scope and
invoking that using lua_pcall. This would guarantee that both sides
have equivalent behavior as well as allowing Lua code to monkey-patch
open() to expand on the functionality (e.g. for an embedded resource
system that's transparent to application code).

/s/ Adam

On Fri, Nov 15, 2013 at 12:08 PM, Sir Pogsalot <sir.pogsalot@gmail.com> wrote:
> 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
>>
>>
>