linux fcntl - unsetting flag

时间:2008-12-23 08:50:44

标签: linux fcntl

如何使用fcntl取消已设置的标志?

例如我可以使用

将套接字设置为非阻塞模式
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)

现在,我想取消设置O_NONBLOCK标志。

我尝试了fcntl(sockfd,F_SETFL,flags | ~O_NONBLOCK)。它给了我错误EINVAL

4 个答案:

答案 0 :(得分:4)

int oldfl;
oldfl = fcntl(sockfd, F_GETFL);
if (oldfl == -1) {
    /* handle error */
}
fcntl(sockfd, F_SETFL, oldfl & ~O_NONBLOCK);

未经测试,但希望这会有所帮助。 : - )

答案 1 :(得分:3)

val = fcntl(fd, F_GETFL, 0);
flags = O_NONBLOCK;
val &= ~flags;
fcntl(fd,F_SETFL,val);

如果你喜欢这样,已经设置的O_NONBLOCK将被取消设置。 这里,flags包含您要取消设置的标志。 完成AND(&)操作后,您必须再次使用val中的值设置标志。 我希望这会对你有所帮助。

答案 2 :(得分:1)

以下代码将取消设置标志,例如O_NONBLOCK标志:

if ((flags = fcntl(fileno(sockfd), F_GETFL, 0)) < 0) {
    perror("error on F_GETFL");
}
else {
    flags &= ~O_NONBLOCK;
    if (fcntl(fileno(sockfd), F_SETFL, flags) < 0) {
        perror("error on F_SETFL");
    }
    else {
        /* O_NONBLOCK set without errors. continue from here */
        }
}

此致

答案 3 :(得分:0)

试图取消所有旗帜:

fcntl(sockfd, F_SETFL, 0);

将标志与~O_NONBLOCK进行OR运算是没有用的,你需要AND它,因为你想要的是取消设置O_NONBLOCK位。