在Linux中如何确定文件描述符是连接到文件还是套接字

4

在Linux中使用C语言,如何确定文件描述符是否连接到文件或套接字?

3个回答

7

使用getsockopt函数在文件描述符上获取SO_TYPE。如果它不是一个套接字,将返回错误ENOTSOCK并且值为-1

int fd = /* ... */;
bool is_socket;
int socket_type;
socklen_t length = sizeof(socket_type);

if(getsockopt(fd, SOL_SOCKET, SO_TYPE, &socket_type, &length) != -1) {
    is_socket = true;
} else {
    if(errno == ENOTSOCK) {
        is_socket = false;
    } else {
        abort();  /* genuine error */
    }
}

/* whether it is a socket will be stored in is_socket */

看起来我可以在这个fd上进行一些套接字操作。如果它不是套接字fd,操作将会导致错误。 - RandyTek

7

或者,您可以使用fstatS_ISSOCK宏。

int main(int argc, char *argv[])
{
    int fds[2];

    fds[0] = 0; //stdin
    fds[1] = socket(AF_INET,SOCK_STREAM, 0);

    for (int i = 0; i < 2; ++i)
    {
        struct stat statbuf;

        if (fstat(fds[i], &statbuf) == -1)
        {
            perror("fstat");
            exit(1);
        }

        if (S_ISSOCK(statbuf.st_mode))
            printf("%d is a socket\n", fds[i]);
        else
            printf("%d is NOT a socket\n", fds[i]);
    }

    return(0);
}

0
根据socket(7) man page

在套接字上不支持寻找或使用非零位置调用pread(2)或pwrite(2)。

因此,另一个选项是执行这些不支持的操作并查看是否出现错误。如果您成功寻找,则FD可能是文件(或设备)。否则它可能是套接字。或者是管道。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接