c - 使用 dup2 和 execv 在 C 中获取文件夹内容

标签 c linux fork pipe dup

我编写了一个程序,在 Linux 终端中使用 ls 命令读取文件夹的内容,并使用我的 C 程序将 ls 中的文本写入屏幕。这是我写的代码:

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

int main()
{
    int pipe_ends[2];
    if(pipe(pipe_ends)) 
    {
        printf("Could not create pipe\n");
        return -1;
    }
    pid_t pid = fork();
    if(pid < 0)
    {
        perror("fork");
        exit(1);
    }
    if(!pid)
    {
        dup2(pipe_ends[0],1);
        char* args[3];
        args[0] = "/bin/ls";
        args[1] = "-l";
        args[2] = NULL;
        execv("/bin/ls",args);
        printf("something went wrong\n");
    }

    char buff[10240];
    int count = read(pipe_ends[1],buff,10240);
    buff[count] = '\0';
    printf("here goes nothing......\n");
    printf("%s",buff);
    return 0;   
}

我得到的这个程序的输出是:

here goes nothing......
od@od-Inspiron-N5110:~/Documents/work/new/CO/project1$ /bin/ls: write error: Bad file descriptor

od@od-Inspiron-N5110:~/Documents/work/new/CO/project1$

看来先读后写。但我认为 read 正在阻塞。请帮我找出这里的错误。

提前致谢。

最佳答案

您必须关闭管道未使用的末端——尤其是父进程中管道的写入端,因为父进程中的 read() 不会获得 EOF 而父进程具有写入管道的末端仍然打开。此外,您需要从管道的读取端 (pipe_ends[0]) 读取,并将管道的写入端复制到 ls 的标准输出。

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

int main(void)
{
    int pipe_ends[2];
    if (pipe(pipe_ends))
    {
        printf("Could not create pipe\n");
        return -1;
    }
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork");
        exit(1);
    }
    if (pid == 0)
    {
        dup2(pipe_ends[1], 1);
        close(pipe_ends[0]);
        close(pipe_ends[1]);
        char *args[3];
        args[0] = "/bin/ls";
        args[1] = "-l";
        args[2] = NULL;
        execv("/bin/ls", args);
        printf("something went wrong\n");
        return 1;
    }

    close(pipe_ends[1]);
    char buff[10240];
    int count = read(pipe_ends[0], buff, 10240);
    buff[count] = '\0';
    printf("here goes nothing (count = %d)......\n", count);
    printf("%s", buff);
    return 0;
}

代码应该更一致地报告错误(有时它使用printf() 写入标准输出;有时它使用perror() 写入标准输出错误),然后退出(有时使用 return -1;,有时使用 exit(1); — 我添加了一个 return 1; 到确保子进程在执行 ls 失败时不会结束读取内容。

关于c - 使用 dup2 和 execv 在 C 中获取文件夹内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21213525/

相关文章:

linux - 运行时 : failed to create new OS thread with Docker

c - 在 C 中使用 fork()、pipe()、dup2() 和 exec() 时遇到问题

c - 为什么 C 中的指针减法会产生一个整数?

c - SuperFastHash 为相同的字符串返回不同的哈希值,但前提是由不同的函数调用确定

c - 如何初始化 Bison 的 %union 值?

c - 为什么我看不到我在 linux top 命令中创建的 fork 函数的进程

c - parent 试图读取 child 退出状态(或返回值), fork 并等待

c++ - Wii MotionPlus 支持

linux - grep 一些单词,其前 10 个字符是从 20 个字符中已知的,最后 10 个字符是动态的

c - UNIX 发送 CR 而不是 LF