c - Check if file exists, including on PATH -
given filename in c, want determine whether file exists , has execute permission on it. i've got is:
if( access( filename, x_ok) != 0 ) {
but wont search path files , match directories (which don't want). please help?
edit:
as alternative, seeing i'm running execvp() in child process, there way check return value of execvp() , signal parent process die error message?
this code's not quite want, blindly executes first thing comes to. can modify search code instead of calling execve
call access
, stat
find out if it's not directory. think last function, execvepath
, has replaced.
in best unix tradition, code "self-documenting" (i.e., undocumented).
#include <string.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include "shellpath.h" static void *malloc_check(const char *what, size_t n) { void *p = malloc(n); if (p == null) { fprintf(stderr, "cannot allocate %zu bytes %s\n", n, what); exit(2); } return p; } static char *strsave(const char *s, const char *lim) { if (lim == null) lim = s + strlen(s); char *p = malloc_check("save string", lim - s + 1); strncpy(p, s, lim-s); p[lim-s] = '\0'; return p; } char ** shellpath(void) { const char *path = getenv("path"); if (!path) path = "/bin:/usr/bin:/usr/local/bin"; char **vector = // size overkill malloc_check("hold path elements", strlen(path) * sizeof(*vector)); const char *p = path; int next = 0; while (p) { char *q = strchr(p, ':'); vector[next++] = strsave(p, q); p = q ? q + 1 : null; } vector[next] = null; return vector; } void freeshellpath (char *shellpath[]) { (int = 0; shellpath[i]; i++) free(shellpath[i]); free(shellpath); } unsigned maxpathlen(char *path[], const char *base) { unsigned blen = strlen(base); unsigned n = 0; (int = 0; path[i]; i++) { unsigned pn = strlen(path[i]); if (pn > n) n = pn; } return blen+n+1; } void execvepath(char *path[], const char *base, char *const argv[], char *const envp[]) { if (strchr(base, '/')) execve(base, argv, envp); else { size_t maxlen = maxpathlen(path, base)+1; char *buf = malloc_check("hold path", maxlen); (int = 0; path[i]; i++) { snprintf(buf, maxlen, "%s/%s", path[i], base); execve(buf, argv, envp); } } }
Comments
Post a Comment