[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

patches to es-0.8



please install these patches to es-0.8 before installing.  it should
fix the three bugs i know about (two reported and one discovered along
the way to fixing the others) in 0.8.  there'll be a new release in
a few days which i hope to release to the world after i get some feedback
on 0.8, but i don't plan on making any changes other than bug fixes
between now and then.

paul

*** CHANGES	Sat Mar 20 18:24:52 1993
--- ../es/CHANGES	Mon Mar 22 17:46:28 1993
***************
*** 1,8 ****
  CHANGES
  =======
  
! since 0.79
! ----------
  
  there's now a man page.  i believe that it's up to date.
  
--- 1,21 ----
  CHANGES
  =======
  
! since 0.8
! ---------
! 
! access -l will now report true for symbolic links;  it used to always
! report false.  oops.
! 
! whatis was broken and accepted any executable filename as a valid without
! checking the executable bit.  fixed.
! 
! when the wait builtin was made interruptible, it broke the handling
! of control-c.  that's fixed now.
! 
! 
! 0.79 to 0.8
! -----------
  
  there's now a man page.  i believe that it's up to date.
  
*** access.c	Sat Mar 20 18:24:54 1993
--- ../es/access.c	Mon Mar 22 17:45:49 1993
***************
*** 1,4 ****
! /* access.c -- access testing and path searching ($Revision: 1.7 $) */
  
  #define	REQUIRE_STAT	1
  #define	REQUIRE_PARAM	1
--- 1,4 ----
! /* access.c -- access testing and path searching ($Revision: 1.8 $) */
  
  #define	REQUIRE_STAT	1
  #define	REQUIRE_PARAM	1
***************
*** 55,62 ****
  
  static int testfile(char *path, int perm, int type) {
  	struct stat st;
! 	if (stat(path, &st) == -1)
! 		return errno;
  	if (type != 0 && (st.st_mode & S_IFMT) != type)
  		return EACCES;		/* what is an appropriate return value? */
  	return testperm(&st, perm);
--- 55,68 ----
  
  static int testfile(char *path, int perm, int type) {
  	struct stat st;
! #ifdef S_IFLNK
! 	if (type == S_IFLNK) {
! 		if (lstat(path, &st) == -1)
! 			return errno;
! 	} else
! #endif
! 		if (stat(path, &st) == -1)
! 			return errno;
  	if (type != 0 && (st.st_mode & S_IFMT) != type)
  		return EACCES;		/* what is an appropriate return value? */
  	return testperm(&st, perm);
***************
*** 167,170 ****
--- 173,181 ----
  extern Dict *initprims_access(Dict *primdict) {
  	X(access);
  	return primdict;
+ }
+ 
+ extern char *checkexecutable(char *file) {
+ 	int err = testfile(file, EXEC, S_IFREG);
+ 	return err == 0 ? NULL : strerror(err);
  }
*** es.h	Sat Mar 20 18:25:00 1993
--- ../es/es.h	Mon Mar 22 17:45:54 1993
***************
*** 1,4 ****
! /* es.h -- definitions for higher order shell ($Revision: 1.11 $) */
  
  #include "config.h"
  #include "stdenv.h"
--- 1,4 ----
! /* es.h -- definitions for higher order shell ($Revision: 1.13 $) */
  
  #include "config.h"
  #include "stdenv.h"
***************
*** 198,209 ****
  extern void printstatus(int pid, int status);
  
  
  /* proc.c */
  
  extern Boolean hasforked;
  extern int efork(Boolean parent, Boolean background);
! extern int ewaitfor2(int pid, void *rusage);
! #define	ewaitfor(pid)	ewaitfor2(pid, NULL)
  
  
  /* dict.c */
--- 198,214 ----
  extern void printstatus(int pid, int status);
  
  
+ /* access.c */
+ 
+ extern char *checkexecutable(char *file);
+ 
+ 
  /* proc.c */
  
  extern Boolean hasforked;
  extern int efork(Boolean parent, Boolean background);
! extern int ewait(int pid, Boolean interruptible, void *rusage);
! #define	ewaitfor(pid)	ewait(pid, FALSE, NULL)
  
  
  /* dict.c */
*** eval.c	Sat Mar 20 18:24:54 1993
--- ../es/eval.c	Mon Mar 22 17:45:56 1993
***************
*** 1,4 ****
! /* eval.c -- evaluation of lists and trees ($Revision: 1.11 $) */
  
  #include "es.h"
  
--- 1,4 ----
! /* eval.c -- evaluation of lists and trees ($Revision: 1.12 $) */
  
  #include "es.h"
  
***************
*** 146,151 ****
--- 146,154 ----
  	/* the logic here is duplicated in $&whatis */
  
  	if (isabsolute(lp->term->str)) {
+ 		char *error = checkexecutable(lp->term->str);
+ 		if (error != NULL)
+ 			fail("$&whatis", "%s: %s", lp->term->str, error);
  		lp = forkexec(lp->term->str, lp, flags & eval_inchild);
  		goto done;
  	}
*** prim-etc.c	Sat Mar 20 18:24:57 1993
--- ../es/prim-etc.c	Mon Mar 22 17:45:58 1993
***************
*** 1,4 ****
! /* prim-etc.c -- miscellaneous primitives ($Revision: 1.11 $) */
  
  #define	REQUIRE_PWD	1
  
--- 1,4 ----
! /* prim-etc.c -- miscellaneous primitives ($Revision: 1.12 $) */
  
  #define	REQUIRE_PWD	1
  
***************
*** 119,126 ****
  	if (term->closure == NULL) {
  		Ref(char *, prog, term->str);
  		assert(prog != NULL);
! 		if (!isabsolute(prog) && (list = varlookup2("fn-", prog)) == NULL)
! 			list = pathsearch(term);
  		RefEnd(prog);
  	}
  	RefEnd(term);
--- 119,133 ----
  	if (term->closure == NULL) {
  		Ref(char *, prog, term->str);
  		assert(prog != NULL);
! 		if (isabsolute(prog)) {
! 			char *error = checkexecutable(prog);
! 			if (error != NULL)
! 				fail("$&whatis", "%s: %s", prog, error);
! 		} else {
! 			list = varlookup2("fn-", prog);
! 			if (list == NULL)
! 				list = pathsearch(term);
! 		}
  		RefEnd(prog);
  	}
  	RefEnd(term);
*** prim-sys.c	Sat Mar 20 18:24:57 1993
--- ../es/prim-sys.c	Mon Mar 22 17:04:03 1993
***************
*** 1,4 ****
! /* prim-sys.c -- system call primitives ($Revision: 1.10 $) */
  
  #define	REQUIRE_IOCTL	1
  
--- 1,4 ----
! /* prim-sys.c -- system call primitives ($Revision: 1.11 $) */
  
  #define	REQUIRE_IOCTL	1
  
***************
*** 273,279 ****
  	pid = efork(TRUE, FALSE);
  	if (pid == 0)
  		exit(exitstatus(eval(lp, NULL, evalflags | eval_inchild)));
! 	status = ewaitfor2(pid, &r);
  	t1 = time(NULL);
  	SIGCHK();
  	printstatus(0, status);
--- 273,279 ----
  	pid = efork(TRUE, FALSE);
  	if (pid == 0)
  		exit(exitstatus(eval(lp, NULL, evalflags | eval_inchild)));
! 	status = ewait(pid, FALSE, &r);
  	t1 = time(NULL);
  	SIGCHK();
  	printstatus(0, status);
*** proc.c	Sat Mar 20 18:24:58 1993
--- ../es/proc.c	Mon Mar 22 17:04:26 1993
***************
*** 1,4 ****
! /* proc.c -- process control system calls ($Revision: 1.5 $) */
  
  #include "es.h"
  
--- 1,4 ----
! /* proc.c -- process control system calls ($Revision: 1.6 $) */
  
  #include "es.h"
  
***************
*** 74,81 ****
  static struct rusage wait_rusage;
  #endif
  
! /* ewait -- a wait wrapper that interfaces with signals */
! static int ewait(int *statusp) {
  	int n;
  	interrupted = FALSE;
  	if (!setjmp(slowlabel)) {
--- 74,81 ----
  static struct rusage wait_rusage;
  #endif
  
! /* dowait -- a wait wrapper that interfaces with signals */
! static int dowait(int *statusp) {
  	int n;
  	interrupted = FALSE;
  	if (!setjmp(slowlabel)) {
***************
*** 111,118 ****
  		}
  }
  
! /* ewaitfor2 -- wait for a specific process to die, or any process if pid == 0 */
! extern int ewaitfor2(int pid, void *rusage) {
  	Proc *proc;
  top:
  	for (proc = proclist; proc != NULL; proc = proc->next)
--- 111,118 ----
  		}
  }
  
! /* ewait -- wait for a specific process to die, or any process if pid == 0 */
! extern int ewait(int pid, Boolean interruptible, void *rusage) {
  	Proc *proc;
  top:
  	for (proc = proclist; proc != NULL; proc = proc->next)
***************
*** 120,132 ****
  			int status;
  			if (proc->alive) {
  				int deadpid;
! 				while ((deadpid = ewait(&proc->status)) != pid)
  					if (deadpid != -1)
  						reap(deadpid, proc->status);
! 					else if (errno == EINTR)
  						SIGCHK();
- 					else
- 						fail("es:ewaitfor2", "wait: %s", strerror(errno));
  				proc->alive = FALSE;
  #if BSD_LIMITS
  				proc->rusage = wait_rusage;
--- 120,132 ----
  			int status;
  			if (proc->alive) {
  				int deadpid;
! 				while ((deadpid = dowait(&proc->status)) != pid)
  					if (deadpid != -1)
  						reap(deadpid, proc->status);
! 					else if (errno != EINTR)
! 						fail("es:ewait", "wait: %s", strerror(errno));
! 					else if (interruptible)
  						SIGCHK();
  				proc->alive = FALSE;
  #if BSD_LIMITS
  				proc->rusage = wait_rusage;
***************
*** 152,166 ****
  		}
  	if (pid == 0) {
  		int status;
! 		while ((pid = ewait(&status)) == -1)
! 			if (errno == EINTR)
  				SIGCHK();
! 			else
! 				fail("es:ewaitfor2", "wait: %s", strerror(errno));
  		reap(pid, status);
  		goto top;
  	}
! 	fail("es:ewaitfor2", "wait: %d is not a child of this shell", pid);
  	NOTREACHED;
  }
  
--- 152,167 ----
  		}
  	if (pid == 0) {
  		int status;
! 		while ((pid = dowait(&status)) == -1) {
! 			if (errno != EINTR)
! 				fail("es:ewait", "wait: %s", strerror(errno));
! 			if (interruptible)
  				SIGCHK();
! 		}
  		reap(pid, status);
  		goto top;
  	}
! 	fail("es:ewait", "wait: %d is not a child of this shell", pid);
  	NOTREACHED;
  }
  
***************
*** 192,198 ****
  		fail("$&wait", "usage: wait [pid]");
  		NOTREACHED;
  	}
! 	return mklist(mkterm(mkstatus(ewaitfor(pid)), NULL), NULL);
  }
  
  extern Dict *initprims_proc(Dict *primdict) {
--- 193,199 ----
  		fail("$&wait", "usage: wait [pid]");
  		NOTREACHED;
  	}
! 	return mklist(mkterm(mkstatus(ewait(pid, TRUE, NULL)), NULL), NULL);
  }
  
  extern Dict *initprims_proc(Dict *primdict) {