0

代码如下。

Q1:

如果dup2(fd3, STDOUT_FILENO),string2将在 log.txt 中。

如果dup2(g_ctl[0], STDOUT_FILENO),string2将不会被g_ctl[1]. string1并且ls -al会收到输出,为什么?

Q2:

第三个库有一些 stdout/stderr 日志,如果使用dup2(socket_fd, STDOUT_FILENO),所有日志都将通过套接字收集。但我也想同时将所有日志打印到屏幕上,怎么做?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>

static pthread_t g_pid;
static int g_ctl[2] = {-1, -1};

void *_run_loop(void *args) {
    char buf[1024];
    int n;
    while (1) {
        n = recv(g_ctl[1], buf, 1024, 0);
        if (n > 0) {
            fprintf(stderr, "%.*s\n", n, buf);
        }
    }
}

int main(int argc, char const *argv[])
{
    int fd3 = open("./log.txt", O_CREAT | O_RDWR | O_APPEND, 0666);

    int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, g_ctl);
    assert(ret == 0);

    ret = dup2(g_ctl[0], STDOUT_FILENO);
    assert(ret > 0);

    pthread_create(&g_pid, NULL, _run_loop, NULL);

    send(STDOUT_FILENO, "string1", 5, 0);
    system("ls -al");

    printf("string2\n");

    sleep(5);

    return 0;
}
4

1 回答 1

0

Q1:你需要fflush(stdout);在你的 printf 之后。否则 printf 可能会缓冲您的输出。如果您的程序尚未退出,它将在您的程序退出时写入,但到那时您的阅读线程已经被取消,因此您无法阅读它。

Q2:据我所知,将输出写入两个文件的唯一方法是将其实际写入两个文件描述符。在 Unix 中没有办法“双重复制”文件描述符。即使是像这样的命令tee实际上也只是write()为读取的每个数据块调用两次。您可以手动执行,也可以在函数内部或线程中执行此操作,但您必须执行此操作。

于 2019-05-06T03:50:51.233 回答