[comp.unix.questions] #! Processing Problem

lorensen@dwaskill.uucp (Bill Lorensen) (04/13/89)

Sorry if this is a known problem, but here goes.

Any program can be invoked to process an interpreter script by putting
the program name on the first line of a script preceeded by a #!. This
is most often used to invoke a shell such as /bin/csh or /bin/sh.
However, I think I have discovered (probably rediscovered) a bug in
first line processing. There appears to be a hard limit on the length
of the path name. This is 29 characters on a Sun3. I have also found
the same problem on:

	Sun4, Convex C220, Encore Multimax, Stellar GS1000

This seems to happen regardless of the shell you are running. I
suspect the first line processing is handled directly by execve.

Related man sections follow:

From from csh(1)
    "When a pathname is found that  has  proper  execute  permis-
     sions,  the  shell  forks a new process and passes it, along
     with its arguments to the kernel (using the execve(2) system
     call).   The kernel then attempts to overlay the new process
     with the desired program.  If  the  file  is  an  executable
     binary (in a.out(5), the kernel succeeds, and begins execut-
     ing the new process.  If the file is a text  file,  and  the
     first  line begins with #!, the next word is taken to be the
     pathname of a shell (or command) to interpret  that  script.
     Subsequent  words on the first line are taken as options for
     that shell.  The kernel  invokes  (overlays)  the  indicated
     shell, using the name of the script as an argument."

From execve(2)
    "An interpreter file begins with a  line  of  the  form  ``#!
     interpreter  [arg]''.  When an interpreter file is execve'd,
     the system  execve's  the  specified  interpreter.   If  the
     optional  arg is specified, it becomes the first argument to
     the interpreter, and the name  of  the  originally  execve'd
     file becomes the second argument; otherwise, the name of the
     originally execve'd file becomes the  first  argument.   The
     original  argument are shifted over to become the subsequent
     arguments.  The zeroth argument, normally the  name  of  the
     execve'd file, is left unchanged."

The following csh script illustrates the problem:

#! /bin/csh
#
#	illustrate file name length bug during #! processing
#
unset noclobber
set dir = "/tmp/1"
set n = 1
/bin/rm $dir/garf
mkdir $dir
ln -s /bin/cat $dir/garf
while ($n < 256)
	mv  $dir ${dir}1
	set dir = ${dir}1
	echo "#! $dir/garf" >testit
	echo "This is a test, this is only a test" >>testit
	chmod +x testit
	if ( ! { testit } ) then
		echo "********* Fails at length `expr $dir/garf : '.*'`"
		break
	endif
	@ n = $n + 1
end
/bin/rm $dir/garf
rmdir $dir
Bill Lorensen
	US Mail:GE Corporate Research and Development
		P.O. Box 8
		Bldg KW Room C207A

boykin@calliope.Encore.COM (Joseph Boykin) (04/14/89)

In article <7915@vdsvax.steinmetz.ge.com> lorensen@dwaskill.uucp (Bill Lorensen) writes:
>Sorry if this is a known problem, but here goes.
>
>Any program can be invoked to process an interpreter script by putting
>the program name on the first line of a script preceeded by a #!. This
>is most often used to invoke a shell such as /bin/csh or /bin/sh.
>However, I think I have discovered (probably rediscovered) a bug in
>first line processing. There appears to be a hard limit on the length
>of the path name. This is 29 characters on a Sun3. I have also found
>the same problem on:
>
>	Sun4, Convex C220, Encore Multimax, Stellar GS1000
>
>This seems to happen regardless of the shell you are running. I
>suspect the first line processing is handled directly by execve.

I don't remember this being documented anywhere, but you are
exactly correct when you say that this is handled directly by
execve.  Under 4.3BSD (amont others, include our own MACH
implementation) there is a constant called "SHSIZE" defined as
32.  Subtract off two for "#!" and one for '\n' and you're
down to the 29 characters you've noticed.  I wouldn't really
call this a bug, more a poor choice of size limitations.

It would certainly be easy enough to up this limit; the kernel
code would allow just about any reasonable value.  In the
meantime, it is hard coded and without kernel sources you're
not going to be able to change it.

----

Joe Boykin
Encore Computer Corp
Vice-Chair, IEEE Computer Societies'
    Technical Activities Board

UUCP: encore!boykin
ARPA: boykin@encore.com

chris@mimsy.UUCP (Chris Torek) (04/14/89)

In article <7915@vdsvax.steinmetz.ge.com> lorensen@dwaskill.uucp
(Bill Lorensen) writes:
>There appears to be a hard limit on the length of the path name.

/sys/sys/kern_exec.c:

	/*
	 * Read in first few bytes of file for segment sizes, magic number:
	 *	407 = plain executable
	 *	410 = RO text
	 *	413 = demands paged RO text
	 * Also an ASCII line beginning with #! is
	 * the file name of a ``shell'' and arguments may be prepended
	 * to the argument list if given here.
	 *
	 * SHELL NAMES ARE LIMITED IN LENGTH.
	 *
	 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
	 * THE ASCII LINE.
	 */

/sys/h/param.h:

	#define	NCARGS	20480		/* # characters in exec arglist */
	#define	MAXINTERP	32	/* maximum interpret file name length */
	#define	NGROUPS	16		/* max number groups */
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris