[comp.sources.bugs] another tcsh bug

mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) (08/30/87)

I accidentally pressed ^C twice (SIGINT) at the tcsh prompt just a few
moments ago, and it spat out "Faulty alias 'periodic' removed."  Normally,
I have "periodic" aliased to "checknews" and tperiod unset.  After the
message, sure enough, "periodic" was no longer one of my aliases.

This is repeatable on my system (Ultrix 1.2).  If I set tperiod to a *nonzero*
value, this doesn't happen.

Mike Khaw
-- 
internet:  mkhaw@teknowledge-vaxc.arpa
usenet:	   {hplabs|sun|ucbvax|decwrl|sri-unix}!mkhaw%teknowledge-vaxc.arpa
USnail:	   Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303

karl@tut.cis.ohio-state.edu (Karl Kleinpaste) (09/04/87)

mkhaw@teknowledge-vaxc.ARPA writes:
>I accidentally pressed ^C twice (SIGINT) at the tcsh prompt just a few
>moments ago, and it spat out "Faulty alias 'periodic' removed."  Normally,
>I have "periodic" aliased to "checknews" and tperiod unset.  After the
>message, sure enough, "periodic" was no longer one of my aliases.
>
>This is repeatable on my system (Ultrix 1.2).  If I set tperiod to a *nonzero*
>value, this doesn't happen.

It is quite repeatable with a nonzero $tperiod; you just have to catch
it when the time period has passed the point where periodic has to be
re-executed.  If you happen to catch it at that point, the same thing
will happen again.  It should be reproducible in a manner like this:
	% alias periodic checknews
	[checknews executes once right away due to no $tperiod.]
	% set tperiod=1
	[now checknews doesn't execute; 1 minute hasn't expired.]
	[so sit there for 61 seconds, and then:]
	% <CR>
	[checknews now re-executes since the $tperiod has expired.]
	^C
	Faulty alias 'periodic' removed.
	%

I put periodic/$tperiod in my version of csh several years ago; a lot
of it has been absorbed by Paul into tcsh.  The reason for the
catch-and-remove-alias is to prevent the halt-and-catch-fire bug which
it fixes; consider the following:
	% alias periodic 'bad double quote"'
Given that execution of the periodic alias happens just before the
printing of your prompt, right after executing this alias, the
newly-created periodic alias will attempt to execute before printing
another "%" prompt.  But it will catch a quoting error in the process,
resulting in a call to bferr() [builtin function error], which will
toss the csh back to a point just before the printing of the prompt,
where it will execute the periodic alias...ad infinitum.  The catch
code is there to annihilate a (supposedly) failing periodic alias.  A
side effect of this is that an interruption of a valid periodic alias
will leave the flag set that the csh uses to determine a faulty
periodic alias.  Poof - your periodic alias is blown away.

I haven't any good ideas for how to get around this problem.  The code
is sh.c; if you're feeling motivated, look it over and see if you can
improve on it.

[By the way, checknews is an *awfully* expensive periodic alias to be
running before every single prompt (which is what happens when there
is no $tperiod).]
-- 
Karl

allbery@ncoast.UUCP (09/07/87)

As quoted from <24@tut.cis.ohio-state.edu> by karl@tut.cis.ohio-state.edu (Karl Kleinpaste):
+---------------
| mkhaw@teknowledge-vaxc.ARPA writes:
| >I accidentally pressed ^C twice (SIGINT) at the tcsh prompt just a few
| >moments ago, and it spat out "Faulty alias 'periodic' removed."  Normally,
| >I have "periodic" aliased to "checknews" and tperiod unset.  After the
| >message, sure enough, "periodic" was no longer one of my aliases.
| 
| I put periodic/$tperiod in my version of csh several years ago; a lot
| of it has been absorbed by Paul into tcsh.  The reason for the
| catch-and-remove-alias is to prevent the halt-and-catch-fire bug which
| it fixes; consider the following:
| 	% alias periodic 'bad double quote"'
| Given that execution of the periodic alias happens just before the
| printing of your prompt, right after executing this alias, the
| newly-created periodic alias will attempt to execute before printing
| another "%" prompt.  But it will catch a quoting error in the process,
| resulting in a call to bferr() [builtin function error], which will
| toss the csh back to a point just before the printing of the prompt,
| where it will execute the periodic alias...ad infinitum.  The catch
| code is there to annihilate a (supposedly) failing periodic alias.  A
| side effect of this is that an interruption of a valid periodic alias
| will leave the flag set that the csh uses to determine a faulty
| periodic alias.  Poof - your periodic alias is blown away.
| 
| I haven't any good ideas for how to get around this problem.  The code
| is sh.c; if you're feeling motivated, look it over and see if you can
| improve on it.
+---------------

It occurs to me that a better way to handle this is to set a flag "did the
periodic alias" immediately before doing it, and clear it immediately after
printing the prompt.  If the flag is already set, don't execute the alias.
Is there some valid reason (bad coding is _not_ a valid reason!) why this
can't be done?  (NB:  I have neither SVR2 nor BSD source licenses, so I can't
check it myself.)
-- 
	    Brandon S. Allbery, moderator of comp.sources.misc
  {{harvard,mit-eddie}!necntc,well!hoptoad,sun!mandrill!hal}!ncoast!allbery
ARPA: necntc!ncoast!allbery@harvard.harvard.edu  Fido: 157/502  MCI: BALLBERY
   <<ncoast Public Access UNIX: +1 216 781 6201 24hrs. 300/1200/2400 baud>>
All opinions in this message are random characters produced when my cat jumped
(-:		      up onto the keyboard of my PC.			   :-)

karl@tut.UUCP (09/07/87)

allbery@ncoast.UUCP writes:
> It occurs to me that a better way to handle this is to set a flag "did the
> periodic alias" immediately before doing it, and clear it immediately after
> printing the prompt.  If the flag is already set, don't execute the alias.
> Is there some valid reason (bad coding is _not_ a valid reason!) why this
> can't be done?

On the one hand, I remember considering that solution when I first
realized the halt-and-catch-fire bug was there; on the other hand, I
believe I couldn't do that due to the nature of the parse/execute
routines which I used (the calling sequence for which I borrowed from
process()).  There isn't any way to stop it at that particular point,
as I recall.  But I will check into it again.

As it is, the flag is set just before attempting alias resolution, and
cleared after execution.
-- 
Karl