From 4a6237114063e9cc3d7a3b544f9477d93738c1a0 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 23 Jan 2005 22:33:59 +0000 Subject: Add searchpath(). --- include/libc.h | 1 + src/lib9/mkfile | 1 + src/lib9/searchpath.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 src/lib9/searchpath.c diff --git a/include/libc.h b/include/libc.h index 653606a1..6e1aa957 100644 --- a/include/libc.h +++ b/include/libc.h @@ -390,6 +390,7 @@ extern int postnote(int, int, char *); extern double p9pow10(int); /* extern int putenv(char*, char*); */ +extern char* searchpath(char*); /* extern int p9setjmp(p9jmp_buf); */ #define p9setjmp(b) sigsetjmp((void*)(b), 1) /* diff --git a/src/lib9/mkfile b/src/lib9/mkfile index 34faf95c..361ab5b7 100644 --- a/src/lib9/mkfile +++ b/src/lib9/mkfile @@ -131,6 +131,7 @@ LIB9OFILES=\ read9pmsg.$O\ readn.$O\ rfork.$O\ + searchpath.$O\ seek.$O\ sendfd.$O\ sleep.$O\ diff --git a/src/lib9/searchpath.c b/src/lib9/searchpath.c new file mode 100644 index 00000000..3b8e7daa --- /dev/null +++ b/src/lib9/searchpath.c @@ -0,0 +1,62 @@ +#include +#include + +/* + * 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; +} + -- cgit v1.2.3