Check if file exists, including on PATH

Check if file exists, including on PATH

Given a filename in C, I want to determine whether this file exists and has execute permission on it. All I've got currently is:

if( access( filename, X_OK) != 0 ) { 

But this wont search the PATH for files and will also match directories (which I don't want). Could anyone please help?


As an alternative, seeing as I'm running execvp() in a child process, is there a way to check the return value of execvp() and signal the parent process to die with an error message?

Displaying an image from the tmp directory


How do they read clusters/cylinders/sectors from the disk?
This code's not quite what you want, as it simply blindly executes the first thing it comes to.

Use OpenBSD's malloc, realloc and free in my program
But you can modify the search code so that instead of calling execve you call access and then stat to find out if it's not a directory.

Strange results while measuring delta time on Linux
I think only the last function, execvepath, has to be replaced..
Java OutOfMemoryError due to Linux RAM disk cache not freed
In the best Unix tradition, the code is "self-documenting" (i.e., undocumented)..
Spring ResourceServlet throws too many open files exception in jetty and tomcat under linux
#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 to %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 is 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[]) {   for (int i = 0; shellpath[i]; i++)     free(shellpath[i]);   free(shellpath); } unsigned maxpathlen(char *path[], const char *base) {   unsigned blen = strlen(base);   unsigned n = 0;   for (int i = 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);     for (int i = 0; path[i]; i++) {       snprintf(buf, maxlen, "%s/%s", path[i], base);       execve(buf, argv, envp);     }   } } 

compile with -ansi -pedantic -Wall switches automatically with gcc

bluetooth application devlopment


You can use the following functions.


the following codes contains some pseudo codes, but should be easy to implement.
if the given path contains the current directory path, like /root/a or ./abc, then         return access( filename, X_OK) == 0;  Else - if the given path only contains the filename, {         getenv( "PATH" );         while( iterate the directories in PATH )         {                 if( search( PATH_directory, filename ) )                 {                         // create the full path string with strcat, strcpy, and/or etc. 

full_path = blabla if( !is_directory( full_path ) && access( filename, X_OK ) == 0 ) return 1; // Yeah~~ We got it!!! } } return 0; // Nah, I don't think there is any of such a file.

} int is_directory( const char* path ) { struct stat file_info; return ( stat( path, &file_info ) == 0 ) ? S_ISDIR( file_info.st_mode ) : 0; } int search( const char* file_name, const char* path ) { struct dirent* dptr; DIR* dirp; if( (dirp = opendir( path )) == NULL ) return 0; while( dptr = readdir( dirp ) ) { if( strcmp( file_name, dptr->d_name ) == 0 ) { closedir( dirp ); return 1; } } closedir( dirp ); return 0; }


Ended up having to set the FD_CLOEXEC flag on a new pipe and writing an error message through it after the exec if it had failed.

I could then read the error message from the parent and determine whether exec was successful or not.. Thanks for your effort though guys, upvoted for the help.

50 out of 100 based on 45 user ratings 1120 reviews