C Test for file existence before execvp call

I am writing a UNIX mini browser on ubuntu and am trying to add inline commands now. When this is not a built-in command, I fork, and then it executes, but for built-in commands, I just execute it in the current process.

So, I need a way to see if the files exist (if they do it is not a built-in command), however execvp uses the PATH environment variable to automatically search for them, so I have no idea how I would manually check in advance.

So, you guys know how I can test an argument to see if there is a built-in command by just providing a name?

Thanks guys.

+4
source share
4 answers

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
+3
source

You can iterate through PATH directories and for each entry in PATH (you need to divide PATH by : possibly using strtok ), merge the name of the command to be called at the end of each path. When you create this path, check if the file exists and if it is being executed using access .

 int is_built_in(char *path, char *name) { char *item = strtok(path, ":"); do { char real_path[4096] = strcat(item, name); // you would normally alloc exactly the size needed but lets stick to it for the sake of the example if (!access(real_path, F_OK) && !access(real_path, X_OK)) // check if the file exists and is executable return 0; } while ((item = strtok(NULL, ":")) != NULL); return 1; } 
+1
source

What you can do is change the path to a specific directory and then use the #include<dirent.h> header file and its readdir and scandir functions to view the directory structure or stat to see if the directory exists or not.

+1
source

Why do you want to test before execvp ? This is the wrong approach. Just call execvp and it will tell you if the program exists.

+1
source

Source: https://habr.com/ru/post/1438203/


All Articles