* Point one: Sharp-bang is not recursive
----------------------------------------
From: Marc Feeley <xxxxxx@IRO.UMontreal.CA>
Well it could be the executable for the interpreter, but it could also
be a shell script that execs the appropriate underlying interpreter
(Gambit, Scheme48, etc) after doing some administrative checks (that
the user has permission to run the interpreter, logging the use of
a Scheme script, or whatever). For example, I can perfectly imagine
Gambit's interpreter to reside in "gsi" and "scheme-script"
is a shell script like this
#! /bin/sh
... parse command line options BUT DON'T CHANGE THE ENVIRONMENT!
exec gsi ...
Unfortunately, Marc, that won't work. It ought to, but it doesn't.
The Unix sharp-bang interpreter escape in the exec(2) system call is *not*
recursive. That is, if you try to exec(2) the file foo with command-line args
of ("foo", "-x") and foo's first few bytes are
#!/usr/bin/bar -y
...
this will turn into an exec of /usr/bin/bar, with command-line args of
("/usr/bin/bar" "-y" "foo" "-x")
At this point, however, file /usr/bin/bar better be a "real" Unix binary. If
it, itself, is a file whose first 16 bits are "#!", the exec() call will lose,
usually with a rather misleading error msg.
What this means is that "scheme-script" *cannot* itself be a #! script,
e.g., a /bin/sh shell script. OK?
Scsh deals with this by having /usr/local/bin/scsh be a tiny little trampoline
program -- native-code executable -- that inserts a few items in front
of the argv[] values and execs the S48 vm. That allows you to do scripts
of the form
#!/usr/local/bin/scsh -s
!#
...
Had /usr/local/bin/scsh itself been a vm heap image as a script, i.e. a file
of the form
#!/usr/local/lib/scsh/scheme48vm -i
...vm image bits here...
then you would lose.
-------------------------------------------------------------------------------
* Point two: 28 is a small number
---------------------------------
While I'm at it, let me remind y'all of another losing feature of Unix'
lame kernel support for #!.
You usually only get 32 chars on that first sharp-bang line, divvied up
between the sharp, the bang, the interpreter filename and the (optional,
single) argument. (Linux gives you 127, but 32 is *very* common on other
systems. I believe Posix only promises you 32, to boot, but i can't swear
to it, since my Posix spec has gone missing.)
Now, remember that you want to put an absolute path name for the
interpreter, since you get no path-search help from the true kernel exec().
Let's do the accounting: 2 chars for sharp & bang. 1 char for the space
separating the interpreter from the argument. N chars for the argument
itself. That leaves 29-N chars for the interpreter, so even if you make the
argument as short as possible -- 1 char -- you still max out at 28 chars for
the interpreter.
Let's see:
/usr/local/bin/scm-ieee-1178-90
That's 31 characters. Oops.
Now you know why I made scsh's meta-switch a single char. Horrible, isn't it?
My advice: make these program names *short* and highly coded, because the
binaries may live in various directories, and you'd like to allow as much
winnage as possible.
-Olin