SUMMARY: suspended output in tcsh

From: Amir Katz (matis!amir@uunet.UU.NET)
Date: Mon May 11 1992 - 13:59:12 CDT


Recently, I posted a tcsh-related question:

: Sometimes (I can't figure out under what circumstances) this command is
: suspended by the shell.
: Typing 'jobs' says:
: [1] + Suspended (tty output) ls-F -Agl | more
:
: Does anyone have any clue why this happens?

The responses so far:
- A few people said it happened to them too (and wanted to know why),
- One condemned me for posting it to sun-managers,
- Two people had the answers. Both said that this is a race condition in
  tcsh under SunOS (and possibly other operating systems).

Thanks for everybody who responded:

dworkin dworkin@merlin.rootgroup.com
Andrew Benson aabenson@mtu.edu
Ted Rodriguez-Bell ted@ssl.Berkeley.EDU

----------------------------------------------------------------
The most detailed response came from Dworkin [dworkin@rootgroup.com]:

It's not specific to tcsh 6.*. You can also see it in version 5.*.
If you try *real* *hard*, you can get the stock csh to do it also.
The problem is a race condition in the shell code that sets up a
pipeline.

What happens is that a pipeline is created from the last command to
the first command (i.e., cmd1 | cmd2 | cmd3 results in cmd3 being
created, then cmd2, then cmd1). This is the easy way to do things --
the processes farther down the pipe simply block waiting for input to
arrive. No inter-process synchronization need be done to avoid
writing to a pipe with no reader (which gets you killed with a
SIGPIPE).

Each child process, soon after it has been created, sets the
terminal's process group to its pid. Way back in the dim dark ages
(circa 4.1 BSD), this was a perfectly reasonable thing to do. Why?
Because the scheduling algorithm the kernel used tended to block a
newly-created child and let the parent continue running -- all the
children would get created before any of them could run, and then
they'd tend to run in reverse order of creation (another undocumented
feature of the scheduling algorithm). Each one would set the
terminal's process group to itself, and then exec. The last one to do
so was always the last process in the pipeline, so everything worked
as expected.

In these more modern times, the scheduling algorithm used by various
kernels (and SunOS in particular) has become less deterministic.
Usually, a newly-created child process will run before its parent.
Given a set of new children, which one goes first depends on the
filesystem, the paging system, memory availability, and (effectively)
the phase of the moon.

The up-shot of all of this is that pipelines created by csh (and tcsh,
which uses substantially identical code) depend on undocumented and
unguaranteed kernel behaviour that is, in fact, no longer provided.
The net result is that sometimes the terminal's process group is set
to some process other than the last one in the pipeline, so when that
last process tries to write to the terminal, it gets stopped by a
SIGTTOU.

The correct fix is to remove the dependency in csh/tcsh. This is not
a practical solution, as there are some deeply-buried assumptions
about the way things work (I've tried -- it's a lot more painful than
it ought to be).

There are a couple of incorrect fixes: when creating pipelines via
aliases, include a sleep before the last element (something like

        alias gerbil "(sleep 1; ls \!*) | more"

), or get good at typing "fg" whenever you get the message about the
command you just typed getting stopped for tty output.

----------------------------------------------------------------

Ted Rodriguez-Bell [ted@ssl.Berkeley.EDU] says:

There's a race condition somewhere in tcsh in which the more process
gets started before the ls. I believe that you get this much more
often if you use the "#define vfork fork" that the config.h file
recommends, but I'm not positive. My memories of this are foggy, so I
recommend you contact someone at Cornell if you need details that
other mail messages can't provide.

I believe this problems harms only your blood pressure.

----------------------------------------------------------------

-- 
/* Amir J. Katz          | UUCP:     uunet!ingr!matis!amir               */
/* System Specialist     | Internet: amir%matis.UUCP@ingr.COM            */
/* SEE Technologies Ltd. | Voice:    +972 52-584684, Fax: +972 52-543917 */



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:06:42 CDT