bug-bash
[Top][All Lists]
Advanced

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

Re: leaks fd for internal functions but not external command


From: Sam Liddicott
Subject: Re: leaks fd for internal functions but not external command
Date: Tue, 23 Jul 2019 17:12:00 +0100

On Tue, 23 Jul 2019 at 16:45, Chet Ramey <chet.ramey@case.edu> wrote:

> On 7/23/19 11:40 AM, Sam Liddicott wrote:
> >
> > On Tue, 23 Jul 2019 at 16:35, Chet Ramey <chet.ramey@case.edu
> > <mailto:chet.ramey@case.edu>> wrote:
> >
> >     On 7/23/19 11:20 AM, Sam Liddicott wrote:
> >     >
> >     > On Tue, 23 Jul 2019 at 16:15, Sam Liddicott <sam@liddicott.com
> >     <mailto:sam@liddicott.com>
> >     > <mailto:sam@liddicott.com <mailto:sam@liddicott.com>>> wrote:
> >     >
> >     >
> >     >
> >     >     On Tue, 23 Jul 2019 at 16:13, Chet Ramey <chet.ramey@case.edu
> >     <mailto:chet.ramey@case.edu>
> >     >     <mailto:chet.ramey@case.edu <mailto:chet.ramey@case.edu>>>
> wrote:
> >     >
> >     >         On 7/23/19 11:11 AM, Sam Liddicott wrote:
> >     >
> >     >         > The report concerns the different behaviour with
> internal and
> >     >         external
> >     >         > operations.
> >     >
> >     >         Right. The close-on-exec is deliberate. That's how it was
> >     intended.
> >     >
> >     >
> >     >     Doesn't close-on-exec usually takes effect only on the process
> that
> >     >     does the exec?
> >     >     i.e. the fork that does the exec, not the parent process?
> >     >
> >     >
> >     > It got closed in the parent. The lsof is running for the parent,
> the main
> >     > process. /bin/echo has quit before the lsof runs.
> >
> >     You mean case 2 in your original post? That's because redirections
> are
> >     performed in the child process forked to run /bin/echo, so the fd
> never
> >     exists in the parent process. I thought you were talking about case
> 1,
> >     with the builtin echo.
> >
> >
> > No doubt, but this report concerns the inconsistency.
> >
> > Is using {xxx}>... suppose to give me a file handle I can use as I wish
> (as
> > you say), or not?
>
> So the difference is between cases 1 and 3? That's the difference between
> using the {var} syntax and using an explicit file descriptor.
>

Given what you have explained as intentional, it the difference between 1
and 2, but it is best understood as a 4-way difference, outlined here:

1. {var} internal: fd remains open in parent
2. {var} external: fd closed in parent
3. numeric internal: fd closed in parent
4. numeric external: fd closed in parent

1. {var} internal: fd remains open in parent
bash -c 'echo 1 {_}>&2 2>&1 1>&${_} {_}<&- ;
        echo done ; lsof -p $$ | grep CHR'

2. {var} external: fd closed in parent
bash -c '/bin/echo 1 {_}>&2 2>&1 1>&${_} {_}<&- ;
        echo done ; lsof -p $$ | grep CHR'

3. numeric internal: fd closed in parent
bash -c 'echo 1 10>&2 2>&1 1>&10 10<&- ;
        echo done ; lsof -p $$ | grep CHR'

4. numeric external: fd closed in parent
bash -c '/bin/echo 1 10>&2 2>&1 1>&10 10<&- ;
        echo done ; lsof -p $$ | grep CHR'

You've indicated that {var} syntax leaves me an fd to do with what I wish.

You've also explained what bash is doing that makes this untrue if the
command was an external command.

I don't believe that this behaviour is *intended( to depend on the
non-obvious detail of whether or not the command is external.

Given the coding pattern of wrapping external commands with functions that
re-invoke using bash "command"; this can lead to unpredictable behaviours
when such wrappers are active.

e.g. openssl() { LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/extra" *command*
openssl "$@"; }

If that function is defined, I get a handle leak*, if it isn't and main
openssl is called, I don't -- or from the other of view my handle got
closed without my knowledge, so I can't use it as I wish.

Personally I would wish that "{var} internal" would also close the fd as it
does for numeric fd and for external {var} fd, because if I really wanted
to open an fd and have it hang around I would do a naked: exec {xxx}>&2 ;
type of thing.

I also think that based on your description of what bash is doing, it might
be easier to fix by also closing in the parent, as I describe.

It would bring full consistency and avoid hard to detect and hard to
code-around bugs.

Ultimately, unless {var} external is intended to behave different to {var}
internal, then we have a consistency bug.
If it is intended to be different, then we have a documentation bug, this
intended inconsistency would need documenting.

Sam


reply via email to

[Prev in Thread] Current Thread [Next in Thread]