Commit Diff


commit - 28125cbd4c7d937278d838f1e375ee0763019d0d
commit + 4a6237114063e9cc3d7a3b544f9477d93738c1a0
blob - 653606a16034166f749c87b342b9d3ff787902da
blob + 6e1aa95724381b4589a4a38c1d7465dbc437f6f4
--- include/libc.h
+++ include/libc.h
@@ -390,6 +390,7 @@ extern	int	postnote(int, int, char *);
 extern	double	p9pow10(int);
 /* extern	int	putenv(char*, char*); <stdlib.h. */
 /* extern	void	qsort(void*, long, long, int (*)(void*, void*)); <stdlib.h> */
+extern	char*	searchpath(char*);
 /* extern	int	p9setjmp(p9jmp_buf); */
 #define p9setjmp(b)	sigsetjmp((void*)(b), 1)
 /*
blob - 34faf95c38040c8e15dbc0df9a033818991fb695
blob + 361ab5b78241bacc7a0fc90030963d8c4b694dba
--- src/lib9/mkfile
+++ src/lib9/mkfile
@@ -131,6 +131,7 @@ LIB9OFILES=\
 	read9pmsg.$O\
 	readn.$O\
 	rfork.$O\
+	searchpath.$O\
 	seek.$O\
 	sendfd.$O\
 	sleep.$O\
blob - /dev/null
blob + 3b8e7daab10700c8c723a0f24479cc5f99df4cb6 (mode 644)
--- /dev/null
+++ src/lib9/searchpath.c
@@ -0,0 +1,62 @@
+#include <u.h>
+#include <libc.h>
+
+/*
+ * Search $PATH for an executable with the given name.
+ * Like in rc, mid-name slashes do not disable search.
+ * Should probably handle escaped colons,
+ * but I don't know what the syntax is.
+ */
+char*
+searchpath(char *name)
+{
+	char *path, *p, *next;
+	char *s, *ss;
+	int ns, l;
+
+	s = nil;
+	ns = 0;
+	if((name[0] == '.' && name[1] == '/')
+	|| (name[0] == '.' && name[1] == '.' && name[2] == '/')
+	|| (name[0] == '/')){
+		if(access(name, AEXEC) >= 0)
+			return strdup(name);
+		return nil;
+	}
+
+	path = getenv("PATH");
+	for(p=path; p && *p; p=next){
+		if((next = strchr(p, ':')) != nil)
+			*next++ = 0;
+		if(*p == 0){
+			if(access(name, AEXEC) >= 0){
+				free(s);
+				free(path);
+				return strdup(name);
+			}
+		}else{
+			l = strlen(p)+1+strlen(name)+1;
+			if(l > ns){
+				ss = realloc(s, l);
+				if(ss == nil){
+					free(s);
+					free(path);
+					return nil;
+				}
+				s = ss;
+				ns = l;
+			}
+			strcpy(s, p);
+			strcat(s, "/");
+			strcat(s, name);
+			if(access(s, AEXEC) >= 0){
+				free(path);
+				return s;
+			}
+		}
+	}
+	free(s);
+	free(path);
+	return nil;
+}
+