I tried the answer tom
It contained a number of problems. I fixed them here and provided a test program.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> int is_file(const char* path) { struct stat buf; stat(path, &buf); return S_ISREG(buf.st_mode); } /* * returns non-zero if the file is a file in the system path, and executable */ int is_executable_in_path(char *name) { char *path = getenv("PATH"); char *item = NULL; int found = 0; if (!path) return 0; path = strdup(path); char real_path[4096]; // or PATH_MAX or something smarter for (item = strtok(path, ":"); (!found) && item; item = strtok(NULL, ":")) { sprintf(real_path, "%s/%s", item, name); // printf("Testing %s\n", real_path); if ( is_file(real_path) && !( access(real_path, F_OK) || access(real_path, X_OK))) // check if the file exists and is executable { found = 1; } } free(path); return found; } int main() { if (is_executable_in_path(".")) puts(". is executable"); if (is_executable_in_path("echo")) puts("echo is executable"); }
Notes
- checking the return value of
access been canceled. - the second call to strtok had the wrong delimiter
- strtok changed the
path argument. My example uses a copy - there was nothing to guarantee the correct char path separator in the combined
real_path - there was no verification that the associated file was indeed a file (directories can also be "executable"). This leads to such strange things as
. recognized as external binaries
source share