dup2() POSIX函数的第二个参数等于零的含义。

问题描述 投票:0回答:1

有时我看到一些奇怪的用法 dup2() 功能。比如说,它甚至不检查返回值。

    if ((sock= accept(sockfd, (struct sockaddr *)&s_addr, &namelen)) == -1){
                syslog(LOG_ERR, "in accept: %m");
                exit(3);

    }
            dup2(sock, 0);
            close(sockfd);
            sock = 0;

它甚至不检查返回值。它到底对这样的参数做了什么?这个 man dup2 说,如果 newfd (second argument of dup2) was previously open, it is silently closed before being reused. 但是0是stdin,为什么我们还要这样做呢?

c linux function unix posix
1个回答
3
投票

这实际上是一个相当常见的范式,用来配置一个程序以socket作为标准输入来操作。

它本身可能看起来毫无意义--为什么不直接在任何socket描述符上操作呢?- 但在实践中,它的后面几乎总是跟着一个 fork() 操作,运行一些期望从标准输入读取的子进程。

- 现在它可以和socket一起工作了。

很可能你会看到stdout以类似的方式进行操作。

编辑:一个超级简单的例子是一个网络服务,它在你接受TCP连接后为你提供一个shell。

    ...
    if ((sock= accept(sockfd, (struct sockaddr *)&s_addr, &namelen)) == -1){
        syslog(LOG_ERR, "in accept: %m");
        exit(3);
    }
    dup2(sock, 0); // stdin
    dup2(sock, 1); // stdout
    dup2(sock, 2); // stderr
    close(sock);

    system("/bin/sh");  // terrible security

所以现在当你连接到它的时候--也许是用客户端的telnet--你就有了一个看起来像传统的stdinouterr的shell,所有的shell都连接到socket上。

重点是你看到这个主要是在一些 子程序 必须执行,其中它假定文件描述符012是以某种方式设置的。

注意:这是个糟糕的想法,而且 高度 不安全,只有在恶意软件中才能看到这种真实的情况。 我犹豫要不要在这里加入这个例子,但它是如此清晰的说明,我认为值得。

© www.soinside.com 2019 - 2024. All rights reserved.