lua-users home
lua-l archive

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


Ah, see, we've got completely opposite views there. If the user *has*
screwed with the io library, then I WANT to support the changes
they've made! They've surely got a good reason for it, and if you want
Lua to manage your file handles instead of managing them opaquely,
then trust the user (who isn't an end user -- the user of your library
is a developer and therefore (probably) isn't a complete numbskull
when it comes to making engineering decisions).

/s/ Adam

On Fri, Nov 15, 2013 at 12:45 PM, Sir Pogsalot <sir.pogsalot@gmail.com> wrote:
> That is what I initially tried for -- I had a function called something like
> `void push_ref_to(luaL_State *, char *)'  that I would call like
> push_ref_to("io.close") and it would leave the function on the stack.  The
> problem was I got paranoid thinking about dumb end-users messing up the io
> table -- then require()'ing in my project and my code hoping that io.close
> was still where it ought to be.
>
> I tend to avoid relying on where things should be on the Lua side unless I'm
> starting the interpreter and setting up the env before the user gets to it
> -- otherwise I can't sleep at night :(
>
>
> On Fri, Nov 15, 2013 at 8:18 PM, Coda Highland <chighland@gmail.com> wrote:
>>
>> 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
>> >>
>> >>
>> >
>>
>