使用dup2重定向stdin和stdout

发布于 2025-01-24 02:52:35 字数 2704 浏览 3 评论 0原文

我正在编写自己的自定义外壳,作为我项目的一部分,当该程序读取“<”或“>”从用户输入中的字符需要将stdin和stdout重定向到自定义文件。我为此写了一个功能。我正在努力的部分是,即使我以相同的方式编写了输入和输出重定向的代码,但输出重定向似乎是按预期工作的,而输入重定向却没有。请参阅下面的代码:

void inOutReDirector(char **toks, char *inputFile, char *outputFile, int *fd0, int *fd1, int *in, int *out) {
    fflush(0);
    for (int i = 0; toks[i] != NULL; i++) {
        if (strcmp(toks[i], "<") == 0) {
            toks[i] = NULL;
            strcpy(inputFile, toks[i + 1]);
            toks[i + 1] = NULL;
            *in = 1;
        }

        if (strcmp(toks[i], ">") == 0) {
            toks[i] = NULL;
            strcpy(outputFile, toks[i + 1]);
            toks[i + 1] = NULL;
            *out = 1;
        }
    }
    //input redirection
    if (*in == 1) {

        if ((*fd0 = open(inputFile, O_RDONLY, 0)) < 0) {
            printf("Couldn't open input file: %s", strerror(errno));
            exit(1);
        }
        dup2(*fd0, STDIN_FILENO);
        close(*fd0);
    }
    //output redirection
    if (*out == 1) {

        if ((*fd1 = creat(outputFile, 0644)) < 0) {
            printf("Couldn't open output file: %s", strerror(errno));
            exit(1);
        }
        dup2(*fd1, STDOUT_FILENO);
        close(*fd1);
    }
}

这是我从主我的主要调用此函数的方式:

int main() {
    char *toks[STD_INPUT_SIZE] = {0};
    int fd0, fd1, in = 0, out = 0;
    char inputFile[64], outputFile[64];
    pid_t pid;
    while (1) {

//print prompt
//get user input

        pid = fork();

        if (pid < 0) {
            printf("%s \n", strerror(errno));
            exit(1);
        }
        int stopNeeded = strcmp(toks[0], "exit") == 0;

        if (pid == 0 && !stopNeeded) {

            pathFinder(toks, shellInput, currentDir); //finding path for execv input
            inOutReDirector(toks, inputFile, outputFile, &fd0, &fd1, &in, &out); // I/O redirection

            if (execv(shellInput, toks) != 0) {
                char *errMsg = strerror(errno);
                printf("%s \n", errMsg);
                //clean the old contents of toks
                for (int i = 0; i < STD_INPUT_SIZE; ++i) {
                    free(toks[i]);
                    toks[i] = NULL;
                }
                exit(1);
            }
        }

        if (pid > 0) {
            pid_t childPid = waitpid(pid, NULL, 0);
            (void) childPid;
        }
    }
    return 0;
}

是从我的终端屏幕上重定向的示例

$ ls > output.txt
$ 

这 在当前目录中文件。

这是我终端屏幕输入重定向重定向输入重定向的示例

$ cat < output.txt
$ 

。它打印提示并等待输入,而不是在我的终端中显示output.txt的内容。

感谢您提前提供的任何帮助!

I'm writing my own custom shell, and as a part of my project, when the program reads either "<" or ">" character from user input, it needs to redirect stdin and stdout to a custom file. I wrote a function for this below. The part where I'm struggling is that even though I wrote the code for input and output redirections pretty much in the same manner, output redirection seems to work as expected, while input redirection does not. See the code below:

void inOutReDirector(char **toks, char *inputFile, char *outputFile, int *fd0, int *fd1, int *in, int *out) {
    fflush(0);
    for (int i = 0; toks[i] != NULL; i++) {
        if (strcmp(toks[i], "<") == 0) {
            toks[i] = NULL;
            strcpy(inputFile, toks[i + 1]);
            toks[i + 1] = NULL;
            *in = 1;
        }

        if (strcmp(toks[i], ">") == 0) {
            toks[i] = NULL;
            strcpy(outputFile, toks[i + 1]);
            toks[i + 1] = NULL;
            *out = 1;
        }
    }
    //input redirection
    if (*in == 1) {

        if ((*fd0 = open(inputFile, O_RDONLY, 0)) < 0) {
            printf("Couldn't open input file: %s", strerror(errno));
            exit(1);
        }
        dup2(*fd0, STDIN_FILENO);
        close(*fd0);
    }
    //output redirection
    if (*out == 1) {

        if ((*fd1 = creat(outputFile, 0644)) < 0) {
            printf("Couldn't open output file: %s", strerror(errno));
            exit(1);
        }
        dup2(*fd1, STDOUT_FILENO);
        close(*fd1);
    }
}

And here is how I call this function from my main:

int main() {
    char *toks[STD_INPUT_SIZE] = {0};
    int fd0, fd1, in = 0, out = 0;
    char inputFile[64], outputFile[64];
    pid_t pid;
    while (1) {

//print prompt
//get user input

        pid = fork();

        if (pid < 0) {
            printf("%s \n", strerror(errno));
            exit(1);
        }
        int stopNeeded = strcmp(toks[0], "exit") == 0;

        if (pid == 0 && !stopNeeded) {

            pathFinder(toks, shellInput, currentDir); //finding path for execv input
            inOutReDirector(toks, inputFile, outputFile, &fd0, &fd1, &in, &out); // I/O redirection

            if (execv(shellInput, toks) != 0) {
                char *errMsg = strerror(errno);
                printf("%s \n", errMsg);
                //clean the old contents of toks
                for (int i = 0; i < STD_INPUT_SIZE; ++i) {
                    free(toks[i]);
                    toks[i] = NULL;
                }
                exit(1);
            }
        }

        if (pid > 0) {
            pid_t childPid = waitpid(pid, NULL, 0);
            (void) childPid;
        }
    }
    return 0;
}

And here is an example of output redirection from my terminal screen

$ ls > output.txt
$ 

This creates "output.txt" file and prints the result inside this file in the current directory.

And here is an example of input redirection from my terminal screen

$ cat < output.txt
$ 

Input redirection does not work correctly. It prints the prompt and waits for the input instead of showing the contents of output.txt in my terminal.

I appreciate any help you can provide in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北陌 2025-01-31 02:52:35

问题应该在函数的这一行inoutredireter

if (strcmp(toks[i], ">") == 0) {

时,应更改为

else if (strcmp(toks[i], ">") == 0) {

toks [i]等于“&lt;”,toks [i] <等于/code>将设置为上方,此行调用strcmp将导致sigsegv,因此子进程将退出,并且随后的execv 将不会执行。

The problem should be on this line of the function inOutReDirector

if (strcmp(toks[i], ">") == 0) {

should be changed to

else if (strcmp(toks[i], ">") == 0) {

When toks[i] is equal to "<", toks[i] will be set to NULL above, this line calling strcmp will cause SIGSEGV, so the child process will exit, and the subsequent execv will not be executed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文