From: kuku@acds.physik.rwth-aachen.de (Christoph Kukulies)
Newsgroups: comp.unix.bsd
Subject: kern_execve.c (patch)
Date: 11 Jan 1993 18:54:19 GMT
Organization: I.Physikalisches Institut RWTH-Aachen
Distribution: world
Reply-To: kuku@acds.physik.rwth-aachen.de
NNTP-Posting-Host: acds.physik.rwth-aachen.de
Keywords: patch kern_execve.c #!


There is a patch for kern_execve.c (PATCH00024+PATCH00025) in the patchkit
which fixes the missing #!/bin/sh feature to execute shell scripts or whatever.

The current implementation of this feature is not completely correct. It fails
in cases where another argument has to be passed to the invoked program
like it is the case in TK/TCL's wish  script which are invoked like

#!/usr/local/bin/wish -f
# the script follows.
#
#

The executed program should receive argv[0]="/usr/local/bin/wish",
argv[1]="-f" and argv[2]="<name-of-the-script>".

In fact the present version of kern_execve.c (with the above mentioned patches
applied) makes the invoked program to receive: argv[9]="/usr/local/bin/wish",
argv[1]="<name-of-the-script>", the switches or any parameters are missing.

The patch below fixes this - at least I hope so. Please excuse me for not
supplying the diffs to the original distribution.

------------------------ 8< snip snip snip     -------------------------

*** /sys/kern/kern_execve.c		Sat Jan  8 16:26:50 1993
--- /sys/kern/NEWkern_execve.c		Sat Jan  9 10:58:56 1993
***************
*** 101,106 ****
--- 101,107 ----
  	struct vmspace *vs;
  	caddr_t newframe;
  	char shellname[MAXINTERP];
+ 	char rest_of_line[MAXINTERP];
  	union {
  		char	ex_shell[MAXINTERP];	/* #! and interpreter name */
  		struct	exec ex_hdr;
***************
*** 186,193 ****
  		while (*cp && *cp != ' ')
  			*sp++ = *cp++;
  		*sp = '\0';
! 
! 		indir = 1;		/* indicate this is a script file */
  		vput(ndp->ni_vp);
  		FREE(ndp->ni_pnbuf, M_NAMEI);
  
--- 187,204 ----
  		while (*cp && *cp != ' ')
  			*sp++ = *cp++;
  		*sp = '\0';
! 		
! 		if(*cp) { /* if there is something following the #!/shell */
! 			while ( *cp == ' ' )
! 				cp++;
! 			sp = rest_of_line;
! 			while (*cp)
! 				*sp++ = *cp++;
! 			*sp = '\0';
! 			indir = 2; /* indicate this is a script file */
! 		}
! 		else 
! 			indir = 1;
  		vput(ndp->ni_vp);
  		FREE(ndp->ni_pnbuf, M_NAMEI);
  
***************
*** 260,266 ****
  	/* first, do (shell name if any then) args */
  	if (indir)  {
  		ep = shellname;
! twice:
  		if (ep) {
  			/* did we outgrow initial argbuf, if so, die */
  			if (argbufp >= (char **)stringbuf) {
--- 271,277 ----
  	/* first, do (shell name if any then) args */
  	if (indir)  {
  		ep = shellname;
! threetimes:
  		if (ep) {
  			/* did we outgrow initial argbuf, if so, die */
  			if (argbufp >= (char **)stringbuf) {
***************
*** 280,290 ****
  			limitonargs -= stringlen;
  		}
  
! 		if (indir) {
  			indir = 0;
  			/* orginal executable is 1st argument with scripts */
  			ep = uap->fname;
! 			goto twice;
  		}
  		/* terminate in case no more args to script */
  		suword(argbufp, 0);
--- 291,306 ----
  			limitonargs -= stringlen;
  		}
  
! 		if (indir == 2) {
! 			indir = 1;
! 			ep = rest_of_line;
! 			goto threetimes;
! 		}
! 		if (indir == 1) {
  			indir = 0;
  			/* orginal executable is 1st argument with scripts */
  			ep = uap->fname;
! 			goto threetimes;
  		}
  		/* terminate in case no more args to script */
  		suword(argbufp, 0);
*** /sys/sys/param.h		Sat Jan  8 16:27:01 1993
--- /sys/sys/NEWparam.h		Sat Jan  9 10:59:30 1993
***************
*** 56,62 ****
  #include <sys/syslimits.h>
  
  #define	MAXCOMLEN	16		/* max command name remembered */
! #define	MAXINTERP	32		/* max interpreter file name length */
  #define	MAXLOGNAME	12		/* max login name length */
  #define	MAXUPRC		CHILD_MAX	/* max simultaneous processes */
  #define	NCARGS		ARG_MAX		/* max bytes for an exec function */
--- 56,62 ----
  #include <sys/syslimits.h>
  
  #define	MAXCOMLEN	16		/* max command name remembered */
! #define	MAXINTERP	80		/* max interpreter file name length */
  #define	MAXLOGNAME	12		/* max login name length */
  #define	MAXUPRC		CHILD_MAX	/* max simultaneous processes */
  #define	NCARGS		ARG_MAX		/* max bytes for an exec function */

--------------------------8< snip snip snip ------------------------------------


The patch for param.h may not be necessary - one might leave the value for MAXINTERP at 32 avoiding to have to rebuild a lot of kernel modules. This would only require kern_execve.c be rebuilt and for a quick test this would suffice.

--
--Chris
Christoph P. U. Kukulies
kuku@acds.physik.rwth-aachen.de
*** Error code 1
 
Stop.