[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: segfault in io.close and a plea for pipes
- From: David Burgess <dburgess@...>
- Date: Mon, 23 May 2005 13:05:19 +1000
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
>