[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: luajit fdopen luaposix
- From: William Ahern <william@...>
- Date: Wed, 25 Nov 2015 15:52:07 -0800
On Wed, Nov 25, 2015 at 12:54:25PM +0100, Mike Belopuhov wrote:
> Hi,
>
> As many of you have most probably stumbled upon the problem with fdopen
> from the luaposix package on luajit and some of you have most probably
> solved it one way or another, I'd like to post my solution to this problem
> just for the purpose of archiving it and hopefully helping others.
>
> But first a bit of a disclaimer: I do not consider myself an experienced
> Lua programmer and perhaps there are better solutions to this problem (-;
>
> local stdio = require("posix.stdio")
> local unistd = require("posix.unistd")
>
> function mikes_fdopen(fd)
> local fh, rv
>
> fh = io.tmpfile()
> if (not fh) then
> return nil
> end
> fh:flush()
> rv = unistd.dup2(fd, stdio.fileno(fh))
> if (not rv) then
> fh:close()
> return nil
> end
> unistd.close(fd)
> return fh
> end
<snip>
> I'm open to any public criticism or a public discussion regarding this.
> Let me also say sorry in advance if this has already been presented
> before, that would just mean that my google-fu wasn't strong enough.
Several people have come up with similar solutions, but I don't think that
fact reflects poorly on your google-fu. ;)
Some comments:
1) POSIX fdopen takes a mode argument. You're only partially implementing
the interface by dup'ing the descriptor over the pre-existing descriptor.
2) In jailed environments there may be no /tmp or even any writable
directories at all.
The solution I arrived at in my own C-based Unix bindings module[1] is here
https://github.com/wahern/lunix/blob/tag-20150923/src/unix.c#L3642
It attempts to open "." or "/dev/null" to get a blessed LuaJIT object using
io.open. Visibility or read permissions aren't guaranteed, but more likely
to work in a jailed environment. Then it replaces that FILE handle
completely with a newly fdopen'd handle rather than dup'ing over the
descriptor.
[1] lunix is thread-safe[2], provides common extensions not defined by POSIX
(with custom implementations if needed to make them "portable"), and is
regularly tested on many non-Linux platforms--AIX, OS X, Solaris, and
several different BSDs.
[2] At least as much as possible. The LuaJIT hack, for example, doesn't
permit properly emulating the "x" (O_CLOEXEC) flag to fdopen, which could
allow the temporary descriptor to be unintentionally inherited if another
thread calls forks at the same time. Although I just realized that LuaJIT
doesn't appear to check the contents of mode, so I should probably try to
pass it through. (And maybe also add a runtime check to see if the x flag is
supported by libc.)