[net.bugs.4bsd] csh script interruptability

jeff (11/12/82)

Suppose you invoke vi from within a csh script, and suppose that you send
an intr signal (usually ^C or `#') to abort the script while you're in vi.

Surprise!
  - Vi drops into the background and develops an enormous appetite for
    cpu cycles.
  - Your terminal characteristics are munged up.

Question of the day:
  How to undo this mess?  You can catch the signal within the
  script and try to put things back in order.  But why can't you kill vi?

For example:

	#! /bin/csh -f
	onintr egress	# Catch them signals and head for the egress.
	vi foo		# Now give a ^C to vi and you'll land
	egress:		# here...
	reset		# Un-mung the terminal.
	echo 'aborting'	# This is important - you'll see later.
	jobs 		# Shows vi chugging away...
	kill -9 %vi	# This ought to blast it.
	echo $status	# Shows that kill ``worked'', but...
	jobs 		# it's still there!

Now you can alter the behavior in significant and interesting ways by changing
the echo statement!
  Exercise 1: Change ``echo ...'' to ``/bin/echo ...''.  Why does this keep vi
  from going bonkers? Note that this doesn't fix everything.  Would you say
  this is an improvement?

P.S. I don't want to place all the blame on vi - you can substitute other
interesting programs as well - such as mail(1).  (Hmmm... what gives, Berkeley?)

	- jeff stearns, john fluke mfg co., everett wa
	  ...!decvax!microsoft!fluke!jeff

thomas (11/12/82)

I've seen this problem before.  It seems to be that the 'scripting' shell
is too anxious to respond to the ^C, without realizing that the underlying
program might catch the ^C.  It should presumably ensure that the program
has indeed exited before continuing.  It's even easier to make it happen,
try
	(vi;echo foo)
then hit ^C while in vi.

The reason that vi is eating cycles at a tremendous rate is probably that
it is getting EOFs or something by virtue of being unable to read the tty.
(Not the right pgrp?)

=Spencer

ecn-pa:bruner (11/13/82)

Another problem which I've experienced, which may or may not be
related, is the inability to correctly do "cmd1 && cmd2".  For
instance, if I type "sleep 100 && who" and don't touch my
terminal, it will indeed sleep for 100 seconds and then run
"who".  If, however, I type a ^Z, the "sleep" is stopped (even
though it hasn't finished running yet) and the "who" runs
immediately.  The signal processing code in "csh" is definitely not
doing something correctly.

An even worse problem is running such a command in the background.
For instance "sleep 100 && who &" locks up my terminal for 100
seconds because the CSH apparently waits for the spawned commands
to finish, and the commands run in a different process group than
the base level shell (hence interrupt, quit, and stop signals that
the tty driver generates are ineffective).  I can use the syntax
I'd use in the Bourne shell: "(sleep 100 && who)&" -- this works, but
when I type "jobs" it prints garbage for the command name.

--John Bruner
  Purdue/EE

thomas (11/15/82)

Re: cmd1 && cmd2 &

The reason that the csh waits for the first to finish is that & binds
more tightly than && (i.e., it only applies to cmd2, not to cmd1 && cmd2).
Putting it in () is indeed the correct thing to do.  Why it prints garbage
for the command name, I don't know, I've never had this problem.
=Spencer