lua-users home
lua-l archive

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


Methinks the intent was to place popen() support in an addon
library like the posix library supplied by Luiz.
However I do agree with you that removal of popen is a 
backward step.

DB

On 5/23/05, William Trenker <wtrenker@gmail.com> wrote:
> 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
>