[net.unix] perror

decot@cwruecmp.UUCP (Dave Decot) (03/01/84)

Why does csh give the message

    % foo
    foo: Command not found.

when foo is an executable (by me) shell file on my path?

Because the first line of foo says

    #! csh -f

And, of course, "csh" is not a full pathname (why does it have to be!?),
so poor exec*(2) can't find it.

What I want to know is, why in blazes doesn't somebody tell me that 
*csh* is the "Command not found" and not my innocent (at least "found")
shell file?

And why do protected directories refuse to acknoledge that they exist
when I try to cd to them?  I can find out the name and that it is indeed
a directory by doing ls(1), so I keep checking my spelling and doing pwd's
and all sorts of things when the real problem is that the message

    % pwd
    /usr
    % cd src
    src: No such file or directory.

is simply WRONG.  And who said ANYTHING about a file?  If the kernel
can't give more accurate messages, perror shouldn't be used.

Dave Decot		 "Programmers are people, too."
decvax!cwruecmp!decot    (Decot.Case@rand-relay)

decot@cwruecmp.UUCP (Dave Decot) (03/01/84)

Addendum to my complaints about cd'ing to protected directories:
A more correct message (src: Permission denied) is given when I
unset my cdpath variable.  However, none of the directories in
the cdpath were unreadable, and the problem still exists when
I set my cdpath to nothing.

Dave Decot
decvax!cwruecmp!decot

rcd@opus.UUCP (03/04/84)

(Re:  command "foo" gives message "foo: command not found" when foo is
executable)
 > Because the first line of foo says
 >     #! csh -f
 > And, of course, "csh" is not a full pathname (why does it have to be!?),
 > so poor exec*(2) can't find it.
 > 
 > What I want to know is, why in blazes doesn't somebody tell me that 
 > *csh* is the "Command not found" and not my innocent (at least "found")
 > shell file?
...and later...
 > If the kernel can't give more accurate messages, perror shouldn't be used.

The kernel ISN'T IN THE BUSINESS OF GIVING "ERROR MESSAGES"!  The fact that
the kernel handles "#!" in a shell script is a major blunder.  The kernel
has no business opening shell scripts and poking around in them.  It costs
a bunch of kernel code (expensive non-pagable, non-swappable memory on
almost all UN*CES) to do this dubious optimization, and the result is that
the error conditions are discovered in a place where there's no reasonable
way to handle them.  What happens is that the kernel discovers that it has
found a semantic error in a command file.  Why should the kernel know
ANYthing about the semantics of command files?  Leave it to a program (say,
csh or sh, radical suggestion!) to parse command files.

Yours for making kernels be kernels again...
{hao,ucbvax,allegra}!nbires!rcd

decot@cwruecmp.UUCP (Dave Decot) (03/05/84)

    D	Command "foo" gives message "foo: command not found" when foo
    A	is executable because the first line of foo says
    V
    E	     #! csh -f

    D	and "csh" is not a full pathname so exec*(2) can't find it.
    E	What I want to know is, why in blazes doesn't somebody tell me that 
    C	*csh* is the "Command not found" and not my innocent (at least "found")
    O	shell file?
    T
    .	If the kernel can't give more accurate messages, perror
    .	shouldn't be used.

    The kernel ISN'T IN THE BUSINESS OF GIVING "ERROR MESSAGES"!  The fact that
    the kernel handles "#!" in a shell script is a major blunder.  The kernel
    has no business opening shell scripts and poking around in them.  It costs
    a bunch of kernel code (expensive non-pagable, non-swappable memory on
    almost all UN*CES) to do this dubious optimization, and the result is that
    the error conditions are discovered in a place where there's no reasonable
    way to handle them.  What happens is that the kernel discovers that it has
    found a semantic error in a command file.  Why should the kernel know
    ANYthing about the semantics of command files?  Leave it to a program (say,
    csh or sh, radical suggestion!) to parse command files.

I, Dave Decot, *agree* with most everything you say.  The kernel HAS, however,
gotten into the business of setting a variable indicating a vague "error
status code" that is intended to be used by calls to perror().  I don't
think this is wise, unless the codes can be made more descriptive and
unambiguous.  By the way, the kernel already has to look for the "magic number"
at the beginning of executables that distinguishes binary programs from
shell files, anyway.  That's probably why they extended the idea to "well,
ok, csh is just another variety of "program" executors, so exec(2) should
make that differentiation, too."

Dave Decot		 "Yet another victim of YASEM."
decvax!cwruecmp!decot    (Decot.Case@rand-relay)

guy@rlgvax.UUCP (Guy Harris) (03/06/84)

> The fact that the kernel handles "#!" in a shell script is a major blunder.
> The kernel has no business opening shell scripts and poking around in them.
> It costs a bunch of kernel code (expensive non-pagable, non-swappable memory
> on almost all UN*CES) to do this dubious optimization, and the result is that
> the error conditions are discovered in a place where there's no reasonable
> way to handle them.  What happens is that the kernel discovers that it has
> found a semantic error in a command file.  Why should the kernel know
> ANYthing about the semantics of command files?  Leave it to a program (say,
> csh or sh, radical suggestion!) to parse command files.

Well, it's not actually *that* much extra code; I pulled the code out, tweaked
it to compile independently, and it came to 236 bytes on our VAX-11.  Doing this
a lot mounts up, but it's not a gigantic amount.  It's already been pointed out
that the kernel *already* has to open up executable files and poke around in
them, and it *does* have to know something about the format of executable files
already (i.e., the executable file header in A.OUT(5) must be known to the
kernel).  The kernel *doesn't* parse much of the command file at all; it knows
nothing about the semantics of "sh" or "csh" or "awk" or ... files, just
about the semantics of the "#!" header.  And I suspect the original intent
was not to provide an optimization; it was to generalize the notion of
"executable file" and provide services such as set-UID behavior to programs
written in interpretive languages such as "sh", "csh", and "awk" (note the
"awk"; it's not just a hack for shell files).

Besides, you'd probably be *very* surprised to know whose idea it was...
Given its relative simplicity and its generalization of the concept of
"executable file", I'd say it was somewhat in the spirit of the creators
of UNIX.  Admittedly, I don't use it much, but I don't think it's a bad
idea.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

edhall%rand-unix@sri-unix.UUCP (03/09/84)

From:  Ed_Hall <edhall@rand-unix>

>                                                            ...The fact that
> the kernel handles "#!" in a shell script is a major blunder.  The kernel
> has no business opening shell scripts and poking around in them...
>                                         ...Why should the kernel know
> ANYthing about the semantics of command files?  Leave it to a program (say,
> csh or sh, radical suggestion!) to parse command files.

I suspect that you've never made a SUID shell script.  It is impossible
without putting #! implementation in the kernel (unless you want to
eliminate system security).  The few hundred bytes of code needed to
implement #! in the kernel is code well spent, in my opinion.

Incidently, let me remind anyone who wants to make a SUID shell script
to *always* explicitly set the search path ($PATH or $path) at the
beginning of the script, and to *never* include the current directory
(or any relative pathname) in that path.  To do otherwise is to leave
a security hole a mile wide.

		-Ed Hall
ARPA:           edhall@rand-unix
UUCP:           decvax!randvax!edhall

emjej@uokvax.UUCP (03/09/84)

#R:cwruecmp:-106100:uokvax:6100023:000:875
uokvax!emjej    Mar  7 13:17:00 1984

/***** uokvax:net.unix / cwruecmp!decot /  5:51 am  Mar  5, 1984 */
I, Dave Decot, *agree* with most everything you say.  The kernel HAS, however,
gotten into the business of setting a variable indicating a vague "error
status code" that is intended to be used by calls to perror().  I don't
think this is wise, unless the codes can be made more descriptive and
unambiguous.  By the way, the kernel already has to look for the "magic number"
at the beginning of executables that distinguishes binary programs from
shell files, anyway.  That's probably why they extended the idea to "well,
ok, csh is just another variety of "program" executors, so exec(2) should
make that differentiation, too."

Dave Decot		 "Yet another victim of YASEM."
decvax!cwruecmp!decot    (Decot.Case@rand-relay)
/* ---------- */

Agreed--this is why OS-9 modules are so nice...

						James Jones

ka@hou3c.UUCP (Kenneth Almquist) (03/14/84)

To get a setuid shell procedure, just write a little C program to invoke
the shell on the script and make the C program setuid.  The #! hack may
make things simpler, but considering the number of setuid shell procedures
that most people write I hardly consider it worth while.
					Kenneth Almquist