[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: eval doesn't close file descriptor?
From: |
Matei David |
Subject: |
Re: eval doesn't close file descriptor? |
Date: |
Wed, 13 Feb 2013 12:06:02 -0500 |
Thank you for the explanation.
On Tue, Feb 12, 2013 at 8:32 PM, Chet Ramey <chet.ramey@gmail.com> wrote:
> On 2/12/13 11:40 AM, Pierre Gaston wrote:
> > On Tue, Feb 12, 2013 at 6:07 PM, Matei David <matei.david@gmail.com>
> wrote:
> >
> >> Ok, but I see the same behaviour when eval runs in a subshell:
> >>
> >> $ bash -c 'llfd () { echo "pid:$BASHPID" >&2; ls -l /proc/$BASHPID/fd/
> >>> &2; }; x=3; eval "exec $x>/dev/null"; llfd; echo | eval "llfd $x>&-"'
> >> [same output, fd 10 open, pointing to /dev/null, even though it's a
> >> subshell]
> >>
> >
> > eval runs in a subshell, but it's the same thing inside this subshell.
> > eg you could have: echo | { eval "llfd "$x>&-"; echo blah >&3; }
> >
> > Bash could optimize this once it realizes there's only one command, but
> > it's probably not that simple to implement.
>
> The basic flow is like this for any builtin command or shell function that
> has a redirection (let's choose 'llfd 3>&-').
>
> 1. The redirection is performed in the current shell, noting that it
> should be `undoable'. That takes three steps:
>
> 1a. In this case, since fd 3 is in use, we dup it (to fd 10) and mark fd
> 10 as close-on-exec. We add a separate redirection to an internal
> list that basically says "close fd 10". Then we add another
> redirection to the front of the same internal list that says "dup fd
> 10 back to fd 3". Let's call this list "redirection_undo_list". We
> will use it to restore the original state after the builtin or
> function completes.
>
> 1b. Take the first redirection from step 1a and add it to a separate
> internal list that will clean up internal redirections in the case
> that exec causes the redirections to be preserved, and not undone.
> Let's call this list "exec_redirection_undo_list".
>
> 1c. Perform the redirection. Here, that means close fd 3.
>
> [perform step 1 for each redirection associated with the command]
>
> 2. If we're running the exec builtin, throw away the list from 1a. If
> we're not running the exec builtin, throw away the list from 1b. Save
> a handle to the list we didn't discard.
>
> 3. Run the function or builtin.
>
> 4. Take the list saved in step 2 and perform the redirections to
> restore the previous state. Here, that means we dup fd 10 back to fd
> 3, then close fd 10.
>
> If you look at the steps, it should be clear why fd 10 is still open when
> llfd executes.
>
> Bash `cheats' when running builtins or shell functions in pipelines or
> other subshells. It knows it's already going to be in a child process
> when it performs the redirections, so it doesn't bother setting up the
> structures to undo them.
>
> Chet
>
> --
> ``The lyf so short, the craft so long to lerne.'' - Chaucer
> ``Ars longa, vita brevis'' - Hippocrates
> Chet Ramey, ITS, CWRU chet@case.edu
> http://cnswww.cns.cwru.edu/~chet/
>
- Re: eval doesn't close file descriptor?, (continued)
- Re: eval doesn't close file descriptor?, Matei David, 2013/02/12
- Re: eval doesn't close file descriptor?, Pierre Gaston, 2013/02/12
- Re: eval doesn't close file descriptor?, Matei David, 2013/02/12
- Re: eval doesn't close file descriptor?, Chet Ramey, 2013/02/12
- Re: eval doesn't close file descriptor?, Matei David, 2013/02/12
- Re: eval doesn't close file descriptor?, Ken Irving, 2013/02/12
- Re: eval doesn't close file descriptor?, Chet Ramey, 2013/02/12
- Re: eval doesn't close file descriptor?, Chet Ramey, 2013/02/12
- Re: eval doesn't close file descriptor?,
Matei David <=
- Re: eval doesn't close file descriptor?, Matei David, 2013/02/13
- Re: eval doesn't close file descriptor?, Chet Ramey, 2013/02/17