shell 尝试使用execv函数执行man命令时出错:"男人:不能处决猫:没有这样的文件或目录"

tf7tbtn2  于 2023-01-05  发布在  Shell
关注(0)|答案(1)|浏览(143)

我正在用C语言编写简单shell的代码,由于一些未知的原因,我在尝试执行man命令时出错,而像ls,cat或其他命令工作正常。我想有搜索命令路径的功能。
这是错误:

man: can't execute cat: No such file or directory
man: command exited with status 255: (cd /usr/share/man && /usr/lib/man-db/zsoelim) | (cd /usr/share/man && /usr/lib/man-db/manconv -f UTF-8:ISO-8859-1 -t ISO-8859-1//IGNORE) | (cd /usr/share/man && tbl) | (cd /usr/share/man && nroff -mandoc -rLL=88n -rLT=88n -Tutf8)
#include<string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdio.h>

char *searchPath(char *cmd) {
    int poljelen = 2;
    char **stringovi = malloc(poljelen * sizeof(char*));
    char *path = getenv("PATH");

    int i = 0;
    while((stringovi[i] = strsep(&path, ":")) != NULL) {
        i++;
        if (i >= poljelen) {
            poljelen = poljelen + i;
            stringovi = realloc(stringovi, poljelen * sizeof(char*));
            if (stringovi == NULL) {
                fprintf(stderr, "%s", "Alloc error\n");
                exit(0);
            }
        }
    }

    stringovi[i] = '\0';
    i = 0;
    while(*stringovi[i] != '\0') {
        int pathlen = strlen(stringovi[i]);
        int cmdlen = strlen(cmd);
        char path[pathlen + cmdlen + 2];

        strcpy(path, stringovi[i]);
        strcat(path, "/");
        strcat(path, cmd);
        if (access(path, F_OK) == 0) {
            char *pathname = malloc(sizeof(char) * (pathlen + cmdlen + 2));
            if (!pathname) {
                return NULL;
            }
            strcpy(pathname, path);
            pathname[strlen(pathname)] = '\0';
            return pathname;
        }
        else {
            i++;
            continue;
        }
    }

    return NULL;
}

int main() {
    char *tokens[3];
    tokens[0] = "man"; //if you put here "ls"
    tokens[1] = "ls";  // and here "-al" its working
    tokens[2] = NULL;
    char *pathh = searchPath(tokens[0]);

    if (pathh == NULL) {
        fprintf(stderr, "Error: command not found\n");
        return 1;
    }

    char stringg[strlen(pathh) + 1];
    strcpy(stringg, pathh);

    pid_t childP;
    int status = 0;
    childP = fork();
    if (childP == 0) {
        if (execv(stringg, tokens) == -1) {
            fprintf(stderr, "Error: execv failed: %s\n", strerror(errno));
            exit(1);
        }
    }
    else if (childP == -1) {
        fprintf(stderr, "Error: fork failed: %s\n", strerror(errno));
        return 1;
    }
    else {
        waitpid(childP, &status, WUNTRACED);
    }
}
mefy6pfw

mefy6pfw1#

使用strsep()会损坏PATH环境变量。
根据the Linux strsep() man page
...此函数查找字符串*stringp中的第一个标记,该标记由字符串delim中的一个字节分隔。此标记通过用空字节('\0')覆盖分隔符而终止...
使用getenv("PATH")返回的值调用strsep()会损坏PATH环境变量,使其仅作为原始值的第一个组成部分。
您应该对getenv("PATH")返回的值进行 * 复制 *,并将其拆分为令牌。

相关问题