在调用execvp之前测试文件是否存在

我正在ubuntu上编写一个UNIX minishell,我正在尝试添加内置命令.当它不是内置命令时我会fork,然后子进程执行它,但是对于内置命令,我只是在当前进程中执行它.

所以,我需要一种方法来查看文件是否存在(如果它们不是内置命令),但是execvp使用环境PATH变量来自动查找它们,所以我不知道如何事先手动检查.

所以,你们知道如何通过提供名称来测试一个参数,看看它是否是一个内置命令?

多谢你们.

最佳答案
我已经测试了汤姆的答案

它包含许多问题.我已在这里修复它们并提供了一个测试程序.

#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");
}

笔记

>访问返回值的测试被反转
>第二次strtok调用有错误的分隔符
> strtok改变了路径论点.我的示例使用了副本
>在连接的real_path中没有任何东西可以保证正确的路径分隔符
>没有检查匹配的文件是否实际上是一个文件(目录也可以是’可执行’).这会导致奇怪的事情.被识别为外部二进制文件

转载注明原文:在调用execvp之前测试文件是否存在 - 代码日志