9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

searchpath.c (1094B)


      1 #include <u.h>
      2 #include <libc.h>
      3 
      4 /*
      5  * Search $PATH for an executable with the given name.
      6  * Like in rc, mid-name slashes do not disable search.
      7  * Should probably handle escaped colons,
      8  * but I don't know what the syntax is.
      9  */
     10 char*
     11 searchpath(char *name)
     12 {
     13 	char *path, *p, *next;
     14 	char *s, *ss;
     15 	int ns, l;
     16 
     17 	s = nil;
     18 	ns = 0;
     19 	if((name[0] == '.' && name[1] == '/')
     20 	|| (name[0] == '.' && name[1] == '.' && name[2] == '/')
     21 	|| (name[0] == '/')){
     22 		if(access(name, AEXEC) >= 0)
     23 			return strdup(name);
     24 		return nil;
     25 	}
     26 
     27 	path = getenv("PATH");
     28 	for(p=path; p && *p; p=next){
     29 		if((next = strchr(p, ':')) != nil)
     30 			*next++ = 0;
     31 		if(*p == 0){
     32 			if(access(name, AEXEC) >= 0){
     33 				free(s);
     34 				free(path);
     35 				return strdup(name);
     36 			}
     37 		}else{
     38 			l = strlen(p)+1+strlen(name)+1;
     39 			if(l > ns){
     40 				ss = realloc(s, l);
     41 				if(ss == nil){
     42 					free(s);
     43 					free(path);
     44 					return nil;
     45 				}
     46 				s = ss;
     47 				ns = l;
     48 			}
     49 			strcpy(s, p);
     50 			strcat(s, "/");
     51 			strcat(s, name);
     52 			if(access(s, AEXEC) >= 0){
     53 				free(path);
     54 				return s;
     55 			}
     56 		}
     57 	}
     58 	free(s);
     59 	free(path);
     60 	return nil;
     61 }
     62