execl()似乎没有从stdin中读取 [英] execl() does not seem to read from stdin

查看:166
本文介绍了execl()似乎没有从stdin中读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用C语言重现此命令:

I'm trying to reproduce this command in c language:

ls | wc > output.txt

为此,我编写了以下程序:

So, to do that, I wrote the following program:

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>

int main()
{
    pid_t lsFork, wcFork;
    int tube[2];
    pipe(tube);

    lsFork = fork();
    if(lsFork == 0) // ls command
    {
        close(tube[0]);
        dup2(tube[1], STDOUT_FILENO);
        close(tube[1]);
        if(execl("/usr/bin/ls", "ls", NULL) == -1)
            perror("Cannot execute ls");
    }
    else
    {
        wcFork = fork();
        if(wcFork == 0)  // wc command
        {
            sleep(1);
            int file = open("output.txt", O_WRONLY | O_CREAT);
            if(file == -1)
                perror("Cannot open output.txt");

            close(tube[1]);
            dup2(tube[0], STDIN_FILENO);
            close(tube[0]);
            dup2(file, STDOUT_FILENO);
            close(file);

            /*char buffer[BUFSIZ];
            read(STDIN_FILENO, buffer, BUFSIZ);
            write(STDOUT_FILENO, buffer, BUFSIZ);*/

            if(execl("/usr/bin/wc", "wc", NULL) == -1)
                perror("Cannot execute wc");

            close(STDOUT_FILENO);
        }
        else // parent
        {
            int status;
            waitpid(lsFork, &status, 0);
            waitpid(wcFork, &status, 0);
        }
    }

    return EXIT_SUCCESS;
}

但是,该程序不会退出.根据htop的说法,wc命令正在阻止该程序.为了理解这种行为,我编写了一段代码(在execl()之前的行注释了),但我不理解它的工作原理,而不是execl().调用此函数时我会忘记一些东西吗?

But, the program does not exit. According to htop, the wc command is blocking the program. To understand this behaviour, I wrote a piece of code (the lines commented before execl()) and I don't understand what this works and not execl(). Am I forgetting something when calling this function?

推荐答案

在您可以轻松完成时不要使事情复杂化.请尝试以下& ;;中的简单代码看看您是否能听懂任何内容.

Don't complicate things when you can do it easily.. Try the simpler code below & see if you can understand anything or not.

int main(){
    int tube[2];
    int fID;
    pipe(tube);
    if (fork() == 0){
      // this is the child process
      close(tube[0]); // reading end of the pipe
      dup2(tube[1], 1); // stdout ---> pipe writing end
      execlp("ls", "ls", NULL);
    }else{
      if (fork() == 0){
        //umask(0022);
        fID = open("sample.txt", O_WRONLY | O_CREAT, 0644);
        close(tube[1]); // writing end of the pipe
        dup2(tube[0], 0);  // stdin ----> pipe reading end
        dup2(fID, 1);
        execlp("wc", "wc", NULL);
      }
    }
  return 0;
}

注意如果代码的目的是仅实现上述管道,那么您无需实现任何等待机制.操作系统将自动杀死所有僵尸孩子(如果有).此外, execlp("wc","wc",NULL); 将自动阻止程序结束.因此它不会提早退出

Note If the purpose of the code is to solely implement the above mentioned piping, then you don't need to implement any waiting mechanisms. The OS will auto-kill all the zombie child, if any. Moreover execlp("wc", "wc", NULL); will auto block the program to end. Hence it will not exit early

这篇关于execl()似乎没有从stdin中读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆