libroot: Add a private __look_up_in_path function.
Refactored out of execvpe. Originally I did this for my attempted change to posix_spawn, but that change turned out to be wrong and actually not that beneficial. This bit seems potentially useful, though, so here it is.
This commit is contained in:
@@ -23,6 +23,7 @@ extern int __gABIVersion;
|
|||||||
extern char _single_threaded;
|
extern char _single_threaded;
|
||||||
/* This determines if a process runs single threaded or not */
|
/* This determines if a process runs single threaded or not */
|
||||||
|
|
||||||
|
status_t __look_up_in_path(const char *name, char *buffer);
|
||||||
status_t __parse_invoke_line(char *invoker, char ***_newArgs,
|
status_t __parse_invoke_line(char *invoker, char ***_newArgs,
|
||||||
char * const **_oldArgs, int32 *_argCount, const char *arg0);
|
char * const **_oldArgs, int32 *_argCount, const char *arg0);
|
||||||
status_t __get_next_image_dependency(image_id id, uint32 *cookie,
|
status_t __get_next_image_dependency(image_id id, uint32 *cookie,
|
||||||
|
|||||||
@@ -314,6 +314,55 @@ clear_caches(void *address, size_t length, uint32 flags)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
__look_up_in_path(const char *file, char *buffer)
|
||||||
|
{
|
||||||
|
// get the PATH
|
||||||
|
const char* paths = getenv("PATH");
|
||||||
|
if (paths == NULL)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
int fileNameLen = strlen(file);
|
||||||
|
|
||||||
|
// iterate through the paths
|
||||||
|
const char* pathEnd = paths - 1;
|
||||||
|
while (pathEnd != NULL) {
|
||||||
|
paths = pathEnd + 1;
|
||||||
|
pathEnd = strchr(paths, ':');
|
||||||
|
int pathLen = (pathEnd ? pathEnd - paths : strlen(paths));
|
||||||
|
|
||||||
|
// We skip empty paths and those that would become too long.
|
||||||
|
// The latter is not really correct, but practically irrelevant.
|
||||||
|
if (pathLen == 0
|
||||||
|
|| pathLen + 1 + fileNameLen >= B_PATH_NAME_LENGTH) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// concatinate the program path
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
memcpy(path, paths, pathLen);
|
||||||
|
path[pathLen] = '\0';
|
||||||
|
|
||||||
|
if (path[pathLen - 1] != '/')
|
||||||
|
strcat(path, "/");
|
||||||
|
strcat(path, file);
|
||||||
|
|
||||||
|
// check whether it is a file
|
||||||
|
struct stat st;
|
||||||
|
if (stat(path, &st) != 0 || !S_ISREG(st.st_mode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if executable, we've found what we are looking for
|
||||||
|
if (access(path, X_OK) == 0) {
|
||||||
|
strlcpy(buffer, path, B_PATH_NAME_LENGTH);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
next_argument(char **_start, bool separate)
|
next_argument(char **_start, bool separate)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -157,50 +157,14 @@ execvpe(const char* file, char* const argv[], char* const environment[])
|
|||||||
|
|
||||||
// file is just a leaf name, so we have to look it up in the path
|
// file is just a leaf name, so we have to look it up in the path
|
||||||
|
|
||||||
// get the PATH
|
char path[B_PATH_NAME_LENGTH];
|
||||||
const char* paths = getenv("PATH");
|
status_t status = __look_up_in_path(file, path);
|
||||||
if (paths == NULL) {
|
if (status != B_OK) {
|
||||||
__set_errno(B_ENTRY_NOT_FOUND);
|
__set_errno(status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fileNameLen = strlen(file);
|
return do_exec(path, argv, environment, true);
|
||||||
|
|
||||||
// iterate through the paths
|
|
||||||
const char* pathEnd = paths - 1;
|
|
||||||
while (pathEnd != NULL) {
|
|
||||||
paths = pathEnd + 1;
|
|
||||||
pathEnd = strchr(paths, ':');
|
|
||||||
int pathLen = (pathEnd ? pathEnd - paths : strlen(paths));
|
|
||||||
|
|
||||||
// We skip empty paths and those that would become too long.
|
|
||||||
// The latter is not really correct, but practically irrelevant.
|
|
||||||
if (pathLen == 0
|
|
||||||
|| pathLen + 1 + fileNameLen >= B_PATH_NAME_LENGTH) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// concatinate the program path
|
|
||||||
char path[B_PATH_NAME_LENGTH];
|
|
||||||
memcpy(path, paths, pathLen);
|
|
||||||
path[pathLen] = '\0';
|
|
||||||
|
|
||||||
if (path[pathLen - 1] != '/')
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, file);
|
|
||||||
|
|
||||||
// check whether it is a file
|
|
||||||
struct stat st;
|
|
||||||
if (stat(path, &st) != 0 || !S_ISREG(st.st_mode))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// if executable, execute it
|
|
||||||
if (access(path, X_OK) == 0)
|
|
||||||
return do_exec(path, argv, environment, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
__set_errno(B_ENTRY_NOT_FOUND);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user