lua-users home
lua-l archive

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


This is my first venture into lua and I'm very impressed.  Right now
I'm porting it to a Linksys WRT54G router (Broadcomm mips processor,
Linux 2.4.20, mipsel-uclibc, BusyBox 1.0) with good results.  I've
encountered one problem so far which I've fixed, and I have a related
question about the new 5.1 development.

The problem is a segfault with io.close().  Here's an example:

ewrt ~# lua
Lua 5.0.2  Copyright (C) 1994-2004 Tecgraf, PUC-Rio
> a = io.open("any existing regular file or directory")
> a:close()
Segmentation fault
ewrt ~#

Digging into the lua-5.0.2 sources I've found the problem in liolib.c.
 It is here in aux_close:

static int aux_close (lua_State *L) {
  FILE *f = tofile(L, 1);
  if (f == stdin || f == stdout || f == stderr)
    return 0;  /* file cannot be closed */
  else {
    int ok = (pclose(f) != -1) || (fclose(f) == 0);     // <<<---
PROBLEM IS HERE
    if (ok)
      *(FILE **)lua_touserdata(L, 1) = NULL;  /* mark file as closed */
    return ok;
  }
}

On my router the pclose doesn't fall through gracefully if 'f' is in
fact a regular file or directory, instead it rudely segfaults.

My workaround is to stat the underlying file descriptor and then use
pclose only if the i/o stream is a pipe, like this:

#include <sys/stat.h> //WTrenker
<snip>
static int aux_close (lua_State *L) {
  FILE *f = tofile(L, 1);
  if (f == stdin || f == stdout || f == stderr)
    return 0;  /* file cannot be closed */
  else {
    //WTrenker ...
    //was: int ok = (pclose(f) != -1) || (fclose(f) == 0);
    struct stat st;
    if (fstat(fileno(f), &st) == -1)
      luaL_error(L, "stat error in io.close");
    int ok;
    if ((st.st_mode & __S_IFIFO))
      ok = (pclose(f) != -1);
    else
      ok = (fclose(f) == 0);
    //... WTrenker
    if (ok)
      *(FILE **)lua_touserdata(L, 1) = NULL;  /* mark file as closed */
    return ok;
  }
}

This works fine.  My question is does this solution make sense within
the design intent of Lua, or is there a better way?

Regarding the new 5.1 work, I see there is no explicit io.popen()
function anymore ('grep popen *' in the 'src' sub-directory turns up
nothing).  The mailing-list archives allude to a new, generalized i/o
system.  Then I came  across this quote from lhf - "Support for pipes
has been removed because it's not ANSI."

Gasp! Wheeze! Choke!  No pipes?  (I got into lua just because it
supports pipes!)  Do you know how important pipes are for using Lua
from the command prompt?  It opens the door to all sorts of
system-admin automation.  (Yes, I use Lua more as a scripting tool
than an embedded language.)  Let me remind readers that the support
for pipes in Python has always been strong and that new, better
implementations of popen continue to be developed in that language --
and the Python folks are strong on standards too.  But popen is just
too useful in the practical world of scripting tools to be abandoned
just because of 'standards'.  Am I overreacting -- are there better
alternatives?  What light can others shed on this?

Thanks very much
Bill Trenker
OkWireless.ca
Kelowna, BC