Subject: borne shell dot cmd must look at PATH
To: None <netbsd-bugs@sun-lamp.cs.berkeley.edu>
From: Daniel P. Kionka <dkionka@Cadence.COM>
List: netbsd-bugs
Date: 01/21/1994 19:11:11
The "." (dot or source) command in /bin/sh should look at PATH to find
the file to include.  Most Unix systems work this way, and it allows
you to put common shell code in the same arbitrary directory as you
put your set of utilities, and access it with ". common.sh".

Another example of the use of this feature is my "setx" script that
turns on -x for another script:

	#!/bin/sh
	REAL_PROGRAM=$1
	shift
	set -x
	. $REAL_PROGRAM

I made the following change to sh/main.c, and it fixed the problem.

Dan Kionka

*** main.c.O	Tue Jan 18 18:12:42 1994
--- main.c	Thu Jan 20 08:38:27 1994
***************
*** 275,288 ****
  
  /*
   * Take commands from a file.  To be compatable we should do a path
!  * search for the file, but a path search doesn't make any sense.
   */
  
  dotcmd(argc, argv)  char **argv; {
  	exitstatus = 0;
  	if (argc >= 2) {		/* That's what SVR2 does */
! 		setinputfile(argv[1], 1);
! 		commandname = argv[1];
  		cmdloop(0);
  		popfile();
  	}
--- 275,311 ----
  
  /*
   * Take commands from a file.  To be compatable we should do a path
!  * search for the file, which is necessary to find sub-commands.
   */
  
+ #include <stdio.h>
+ #include <sys/stat.h>
+ #include "exec.h"
+ #include "var.h"
+ 
+ static char *find_dot_file(basename) char *basename; {
+ 	static char localname[FILENAME_MAX+1];
+ 	char *fullname;
+ 	char *path = pathval();
+ 	struct stat statb;
+ 
+ 	while ((fullname = padvance(&path, basename)) != NULL) {
+ 		strcpy(localname, fullname);
+ 		stunalloc(fullname);
+ 		if ((stat(fullname, &statb) == 0) &&
+ 		    (! S_ISDIR(statb.st_mode)) &&
+ 		    (statb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ 			return localname;
+ 	}
+ 	return basename;
+ }
+ 
  dotcmd(argc, argv)  char **argv; {
  	exitstatus = 0;
  	if (argc >= 2) {		/* That's what SVR2 does */
! 		char *fullname = find_dot_file(argv[1]);
! 		setinputfile(fullname, 1);
! 		commandname = fullname;
  		cmdloop(0);
  		popfile();
  	}

------------------------------------------------------------------------------