[comp.unix.questions] Weird things in csh

maart@cs.vu.nl (Maarten Litmaath) (02/25/88)

Has anyone noticed the following oddities?
1)
	% a.out < a.out
	a.out: Text file busy.
	%

Why shouldn't a process be able to read its text file?
2)
	% cat ~/.cshrc
	echo echo hello
	% cp /bin/echo .
	% ./echo > echo
	hello: Command not found.
	% cat echo
	echo hello
	hello
	%

What kinda weird thing is going on here?
Shouldn't there be an error message "Text file busy."
in this case?
-- 
"Brothers & sisters, praise the Lord, |Maarten Litmaath @ Free U Amsterdam:
send your money, Rolls Royce > Ford." |maart@cs.vu.nl, mcvax!botter!ark!maart

sjoerd@cs.vu.nl (Sjoerd Mullender) (02/25/88)

In article <1193@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Has anyone noticed the following oddities?
>1)
>	% a.out < a.out
>	a.out: Text file busy.
>	%
>
If you are debugging a.out then this could happen.  Especially if you have set
breakpoints.

>Why shouldn't a process be able to read its text file?
It can!

>2)
>	% cat ~/.cshrc
>	echo echo hello
>	% cp /bin/echo .
>	% ./echo > echo
>	hello: Command not found.
>	% cat echo
>	echo hello
>	hello
>	%
When executing the command "./echo > echo" the shell will first create the
file echo.  It then tries to exec ./echo.  The kernel refuses (it's not an
object anymore, it an empty file) and the shell will start interpreting the
script.  The shell will fork off a new shell to do the work.  This new shell
will first execute ~/.cshrc which contains the command "echo echo hello".
So the string "echo hello" is echoed into the output file (echo).  Then the
shell really starts executing the script.  It now contians the string
"echo hello", so that command is executed.  The result (the string "hello")
is appended to the output file (that file was never closed or re-created).
After that the next line of the script is "hello" and the shell is not able
to find the command.  Hence the error message.

>
>What kinda weird thing is going on here?
>Shouldn't there be an error message "Text file busy."
>in this case?
Nothing that cannot be explained.

Why was this cross-posted to comp.unix.wizards?
-- 
Sjoerd Mullender
sjoerd@cs.vu.nl
When this doesn't work try sending via seismo.css.gov or mcvax.uucp.

maart@cs.vu.nl (Maarten Litmaath) (02/26/88)

In article <662@sjoerd.cs.vu.nl> sjoerd@cs.vu.nl (Sjoerd Mullender) writes:
\In article <1193@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
\>	% a.out < a.out
\>	a.out: Text file busy.
\>	%
\If you are debugging a.out then this could happen.  Especially if you have set
\breakpoints.

I was NOT debugging a.out...

\>...
\>	% ./echo > echo
\>...
\When executing the command "./echo > echo" the shell will first create the
\file echo.  It then tries to exec ./echo.  The kernel refuses (it's not an
\object anymore, it an empty file) and the shell will start interpreting the
\script.  The shell will fork off a new shell to do the work.  This new shell
\will first execute ~/.cshrc which contains the command "echo echo hello".

Isn't it a BOURNE shell that is forked off, which won't execute ~/.cshrc?

\Why was this cross-posted to comp.unix.wizards?

Possible kernel bugs are detected by wizards only, I guess.
-- 
"Brothers & sisters, praise the Lord, |Maarten Litmaath @ Free U Amsterdam:
send your money, Rolls Royce > Ford." |maart@cs.vu.nl, mcvax!botter!ark!maart

ugfailau@sunybcs.uucp (Fai Lau) (02/27/88)

In article <1193@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Has anyone noticed the following oddities?
>1)
>	% a.out < a.out
>	a.out: Text file busy.
>	%
>
	This is not as bad as this,

	cat file | grep john > file

	There will be nothing withsoever in file "file". UNIX is kinds
strange when you put the same file name at both "ends" of a pipeline or
redirect. Aviod doing it or sooner or later you'll find out some files
you're working on would be strangely deleted against your wish. Speaking
from experience here.

>Why shouldn't a process be able to read its text file?
>2)
>	% cat ~/.cshrc
>	echo echo hello
>	% cp /bin/echo .
>	% ./echo > echo
>	hello: Command not found.
>	% cat echo
>	echo hello
>	hello
>	%
>
	Find the source code echo.c, compile it, put the executable in you
directory, and the problem would go away. The only explanation
I can give for the phenomonen is that for some reason csh wants to
parse .cshrc, and somehow thinks hello is a command. I'm using
tcsh in /usr/local/bin and I got the error message "/bin/tcsh: not
found" until I restarted with csh did I got the behavior you
described.

Fai Lau
SUNY at Buffalo (The Arctic Wonderland)
UU: ..{rutgers,ames}!sunybcs!ugfailau
BI: ugfailau@sunybcs INT: ugfailau@joey.cs.buffalo.EDU

pdb@sei.cmu.edu (Patrick Barron) (02/27/88)

In article <1193@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Has anyone noticed the following oddities?
>1)
>	% a.out < a.out
>	a.out: Text file busy.
>	%
>Why shouldn't a process be able to read its text file?

   I can't reproduce this under Ultrix 1.2.

>2)
>	% cat ~/.cshrc
>	echo echo hello
>	% cp /bin/echo .
>	% ./echo > echo
>	hello: Command not found.
>	% cat echo
>	echo hello
>	hello
>	%
>
>What kinda weird thing is going on here?
>Shouldn't there be an error message "Text file busy."
>in this case?

This is actually pretty simple.  When you redirect output to "echo",
the file gets overwritten *before* "./echo" is executed.  So, it ends
up trying to execute an empty file.  Since it doesn't have a valid
magic number, and the execute bits are set (copying /bin/echo left
them set, and overwriting the file didn't change that), it's assumed
to be a shell script.  Your .cshrc file gets executed, echoing
"echo hello" using the C-shell's built-in echo.  That goes into
the file "./echo", and the shell then starts to execute commands from
"./echo".  (Why isn't the Bourne shell used to do this?  The file does
not start with "#!/bin/csh")  That file now contains "echo hello", so
the shell's "echo" echoes "hello".  Remember, standard output is still
the "./echo" file, so that gets tacked on to the end.  The shell then
reads the next command, which is "hello", and it complains "Command not
found."

--Pat.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/28/88)

In article <1195@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Isn't it a BOURNE shell that is forked off, which won't execute ~/.cshrc?

It ought to be (since otherwise the behavior of a shell script would
depend on which shell the invoker happened to be using), but most Cshell
implementations I've run across think that anonymous scripts should be
interpreted by (an instance of) them.

ka@june.cs.washington.edu (Kenneth Almquist) (02/29/88)

> % a.out < a.out
> a.out: Text file busy.
> %

The basic problem that the "text file busy" error was designed to solve
is this.  When several copies of the same program are run concurrently,
UNIX will only create a text segment for the first copy.  Subsequent
invocations of the program will reuse this text segment rather than
creating a new one.  The problem with this approach is that if a program
is modified, the system may continue to reuse the old version of the
text segment rather than using the new version.  This problem was avoided
by making the following actions illegal:

	1)  Opening a file that is being executed.
	2)  Executing an open file.
	3)  Deleting the last link to a file that is being executed.

So when you say "a.out < a.out", the shell opens a.out and then tries
to execute it.  The attempt to execute it fails due to rule 2.  You
are presumably running some version of 2 BSD; both 4 BSD and System V
have relaxed rules 1 and 2 to allow files that are being executed to
be opened for reading and vice versa.

My view is that these rules should be eliminated all together.  They are
inconvenient, since they make program installation harder.  They are
inconsistent with the rest of the design of the UNIX file system calls,
which permits any operation to be performed at any time (even operations
like deleting other people's current working directories).  It is a
bit simpler to enforce these rules than to design things so that they
are unnecessary, but given the growth of the kernel in recent years it
is hard to justify taking some of the complexity of supporting shared
text out of the kernel and pushing it onto the users.
				Kenneth Almquist
				ka@june.cs.washington.edu

root@uokmet.UUCP (03/01/88)

>Has anyone noticed the following oddities?
>1)
>	% a.out < a.out
>	a.out: Text file busy.

It is behaving that way because it was loaded that way.  On our 11/44,
running 2.9bsd, any program compiled with "-i" or "-n" will display that
behavior.  Try looking at the man entry of "ld" to get hints on what
options might do this.

	== kwthomas ==

maart@cs.vu.nl (Maarten Litmaath) (03/01/88)

In article <7368@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
\In article <1195@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
\>Isn't it a BOURNE shell that is forked off, which won't execute ~/.cshrc?
\
\It ought to be (since otherwise the behavior of a shell script would
\depend on which shell the invoker happened to be using), but most Cshell
\implementations I've run across think that anonymous scripts should be
\interpreted by (an instance of) them.

% cat gnome
alias	l	ls -l
% ls -l gnome
-rwxr-xr-x 1 3754         14 Mar  1 14:20 gnome
% gnome
gnome: alias: not found
%

This shows that normally a Bourne shell indeed is forked off...
-- 
Which of Santa Claus and God          |Maarten Litmaath @ Free U Amsterdam:
             is more likely to exist? |maart@cs.vu.nl, mcvax!botter!ark!maart

maart@cs.vu.nl (Maarten Litmaath) (03/01/88)

In article <4320@june.cs.washington.edu> ka@june.cs.washington.edu (Kenneth Almquist) writes:
\> % a.out < a.out
\> a.out: Text file busy.
\> %
\
\...  You
\are presumably running some version of 2 BSD; both 4 BSD and System V
\have relaxed rules 1 and 2 to allow files that are being executed to
\be opened for reading and vice versa.

Our version is 4.1BSD!
-- 
Which of Santa Claus and God          |Maarten Litmaath @ Free U Amsterdam:
             is more likely to exist? |maart@cs.vu.nl, mcvax!botter!ark!maart

rml@hpfcdc.HP.COM (Bob Lenk) (03/03/88)

>Isn't it a BOURNE shell that is forked off, which won't execute ~/.cshrc?

Based on experimentation, csh's test is something like:

	if I can read from the file and the first character is not #
		give it to sh
	else
		give it to csh

Thus a zero-length file, as a degenerate case, is run by the csh.
The only difference between csh and sh for a zero-length file is,
of course, that .cshrc is sourced.

		Bob Lenk
		{ihnp4, hplabs}!hpfcla!rml

richard@aiva.ed.ac.uk (Richard Tobin) (03/03/88)

In article <1198@ark.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
   [discussion of which shell csh uses to run a script]

Csh [BSD 4.2] assumes that it should run /bin/sh if and only if
(1) exec() fails with ENOEXEC
(2) there isn't an alias for shell
(3) it can read the first character of the file
(4) that character isn't '#'

Thus empty files get run with csh, because (3) is violated.

-- Richard
-- 
Richard Tobin,                         JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,             ARPA:  R.Tobin%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.                  UUCP:  ...!ukc!ed.ac.uk!R.Tobin