lua-users home
lua-l archive

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


Sometime on 7/10/2007, steve donovan wrote:
>Any extensions out there that create Lua files? I know that liolib
>defines a special environment, but that seems basically for private
>static variables?

I looked into this when I wanted to be able to use some of the
Windows serial port API, and somewhat foolishly decided that the
only difference between a file handle to a serial port and a
normal file was in the name passed to CreateFileA(). My
implementation creates its own namespace for its capabilities,
but borrows the function tofile() from liolib.c and includes
lualib.h to get the definition of LUA_FILEHANDLE for use by
tofile()'s call to luaL_checkudata().

Doing it this way, I did not need to clone liolib.c's io_open().

If I did my own open variant (say to be more paranoid about
making sure that only true serial ports are used for the serial
port API), the right thing to do would probably be to clone
liolib.c's newfile(), which manages the creation of the right
kind of userdata in a known state for use by io_open() and
io_popen().

But that won't be sufficient, as you've noticed.

The io module's environment serves to provide a reference to a
default __close method, which is used later to call the correct
file close function. The function io_popen() is given its own
separated function environment so that it can have a different
__close method.

Your extension module should probably be built to share the same
environment as the io module, and your specific popen
implementation should have a private function environment that
hooks __close just like io_popen() has a reference to
io_pclose(). Look at luaopen_io() to see how it manages the
environments.

Without this, there are several places in liolib.c will
confidently look in the environment when called for methods of a
LUA_FILEHANDLE that will cause various amounts of havoc if the
environment is missing the expected elements.

It may be easier to copy liolib.c into your project and change
the names of the userdata type LUA_FILEHANDLE and the top level
library object to avoid conflicts with the "real" io module.
Then you should be able to just modify io_popen() and io_pclose()
to make them do what you need.

Ross Berteig                               Ross@CheshireEng.com
Cheshire Engineering Corp.           http://www.CheshireEng.com/