help-bash
[Top][All Lists]
Advanced

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

Re: [Help-bash] Mixing background tasks with input redirection somehow u


From: Bob Proulx
Subject: Re: [Help-bash] Mixing background tasks with input redirection somehow unsets stty's icanon and echo
Date: Thu, 22 Dec 2016 15:02:55 -0700
User-agent: NeoMutt/20161126 (1.7.1)

João Eiras wrote:
> sorry for the lame title but I can't describe this issue simply.

Your title was much better than most.  It is so much more pleasant to
read your title than the lame "help" or "bug" that many people write. :-)

> I wrote a script that runs a bunch of tasks in parallel, but
> serializes their output as it they had ran in sequence.
> 
> Then I hit an weird bug and minified it to a testcase (available below).

Your test case was great.  Small enough to be easily tried.  I tried
it.  I ran probably 20 trials and it never caused my tty to turn off
echo and icanon.

What operating system are you running?

> So, if run nmap in a background process (I couldn't reproduce it just
> with echo and sleep) and do some input redirection, after the script
> quits, the stty's options echo and icanon are off, and as expected the
> terminal does not show me what I'm typing.

Looking at your problem I was surprised to learn that nmap does modify
the tty params at program start and appears to support some type of
interactive mode.  I did not know that before.  Although I did not
figure out how to invoke it.  It appears to be poorly documented and
therefor emay be a deprecated feature.  I don't know.  The nmap
program starts by calling an nmap tty_init() that does exactly as your
problem shows.

    ti.c_lflag &= ~(ICANON | ECHO);
    ...
    tcsetattr(tty_fd, TCSANOW, &ti);

Therefore the reason you needed to include nmap in your test case to
reproduce the bug is almost certainly because nmap is the root cause
of it.

Then nmap attempts to restore the previous settings using atexit().
It also sets up signal handling to restore the tty settings upon
receipt of INT, TERM, QUIT.

It opens the tty from /dev/tty.

    if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;

> I can't understand what it causing the options to toggle. It's not
> 100% reproducible, more like 50%, and I'm a bit afraid it might be
> entirely reliant how nmap behaves on my computer+home network.

I think I see the problem.  Since you are launching background
processes the timing of everything happening will be a large race
condition.

I think what is happening is that you have multiple nmap processes
running in parallel.  At this point and with the above information
most readers will immediately see what is happening.  The order of
operation of everything will be a large race condition.

* An nmap process starts, records tty settings for later restore,
  changes tty settings ti.c_lflag &= ~(ICANON | ECHO);.

* Another nmap process starts, records tty settings for later restore,
  and has saved off ~(ICANON | ECHO) as the current state.

* First nmap process exits and restores the tty state.

* The other nmap process exits and restores the tty state.  But the
  saved state was thes ~(ICANON | ECHO) state.  Therefore it restores
  the changed state and not the state before the first one started.

And there is the problem.

> Any hints ?

I would report the issue to the nmap project.  It was surprising to me
that it set the tty parameters.  They may be in the middle of
deprecating a feature.  It feels that way since this is not
documented.  At least not documented very well that I could see.  At
least the source code was clear enough.

As a workaround for the problem I would the tty init to be avoided.
Which looking at the source I see:

    void tty_init()
    {
    ...
        if(o.noninteractive)
                return;

    {"noninteractive", no_argument, 0, 0},

Since I can't reproduce your problem I can't verify that this works
but by inspection it appears that if you added --noninteractive to
your nmap argument list that you would avoid having it reset your tty
parameters.  There does not appear to be an --interactive option in
my copy of the source.  Therefore it feels like a deprecated feature.
However using --noninteractive was accepted without error.

  nmap --noninteractive

I suggest reporting your problem to to the nmap project.  They will
know what is really going on here with this code.  If they really have
deprecated a feature then this may encourage them to finish the task
and truly avoid this.  Or maybe they will have a different plan in
mind.  I don't know.

I will be interested in hearing from you as to if this option avoids
your problem or not.

Good luck and happy hacking!
Bob



reply via email to

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