linux fcntl-флаг сброса

Как снять уже установленный флаг с помощью fcntl?

например, я могу установить сокет в неблокирующий режим с помощью

fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)

теперь я хочу снять флаг O_NONBLOCK.

я попробовал fcntl (sockfd, F_SETFL, flags | ~O_NONBLOCK). Это дало мне ошибку EINVAL

4 ответов


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

непроверенный, но надеюсь, что это поможет. :-)


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

Если вам это нравится, уже установленный O_NONBLOCK будет снят. здесь flags содержит флаги, которые вы хотите отменить. После завершения операции AND(&) вам снова нужно установить флаг,используя значение в val. Надеюсь, это вам поможет.


в следующем коде будет снят флаг, например флаг 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 */
        }
}

в отношении


пробовал сбросить все флаги:

fcntl(sockfd, F_SETFL, 0);

Также или-ing флаги с ~O_NONBLOCK бесполезно, вам нужно и это, так как вы хотите, чтобы отключить бит(ы) O_NONBLOCK.