简体   繁体   English

C - 管道不使用popen

[英]C - pipe without using popen

how can I transform this: 我怎么能改变这个:

FILE *f;
char in_buffer[80];
f=popen("command","r");
fgets(in_buffer,sizeof(in_buffer),f)

without using popen() , but only pipe() or other instruction? 不使用popen() ,而只使用pipe()或其他指令?

Here's my simple implementation, with comments explaining what's being done. 这是我的简单实现,其中的注释解释了正在做什么。

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

FILE *
my_popen (const char *cmd)
{
    int fd[2];
    int read_fd, write_fd;
    int pid;               

    /* First, create a pipe and a pair of file descriptors for its both ends */
    pipe(fd);
    read_fd = fd[0];
    write_fd = fd[1];

    /* Now fork in order to create process from we'll read from */
    pid = fork();
    if (pid == 0) {
        /* Child process */

        /* Close "read" endpoint - child will only use write end */
        close(read_fd);

        /* Now "bind" fd 1 (standard output) to our "write" end of pipe */
        dup2(write_fd,1);

        /* Close original descriptor we got from pipe() */
        close(write_fd);

        /* Execute command via shell - this will replace current process */
        execl("/bin/sh", "sh", "-c", cmd, NULL);

        /* Don't let compiler be angry with us */
        return NULL;
    } else {
        /* Parent */

        /* Close "write" end, not needed in this process */
        close(write_fd);

        /* Parent process is simpler - just create FILE* from file descriptor,
           for compatibility with popen() */
        return fdopen(read_fd, "r");
    }
}

int main ()
{
    FILE *p = my_popen ("ls -l");
    char buffer[1024];
    while (fgets(buffer, 1024, p)) {
        printf (" => %s", buffer);
    }
    fclose(p);
}

Notes: 笔记:

  1. Thir code supports only "r" mode of popen . Thir代码仅支持popen "r"模式。 Implementing other modes, namely "w" mode is left as an exercise for the reader. 实现其他模式,即"w"模式留给读者练习。
  2. System functions used in this example may fail - error handling is left as an exercise for the reader. 此示例中使用的系统函数可能会失败 - 错误处理留给读者练习。
  3. Implementation of pclose is left as an exercise for the reader - see close , waiptid , and fclose . pclose实现留给读者练习 - 见closewaiptidfclose

If you want to look at real impementations, you can look into sources of OSX , GNU glibc and OpenSolaris , among others. 如果你想看看真正的需求,你可以查看OSXGNU glibcOpenSolaris等来源。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM