linux fcntl - unsetting flag
Asked Answered
S

4

10

How do i unset a already set flag using fcntl?

For e.g. I can set the socket to nonblocking mode using

fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)

Now, i want to unset the O_NONBLOCK flag.

I tried fcntl(sockfd, F_SETFL, flags | ~O_NONBLOCK). It gave me error EINVAL

Schwaben answered 23/12, 2008 at 8:50 Comment(2)
Try flags & ~O_NONBLOCK. i.e., &, not |.Empire
Yeah, you are right. Copy, paste problem. :-). Need to think while coding.Schwaben
E
9
int oldfl;
oldfl = fcntl(sockfd, F_GETFL);
if (oldfl == -1) {
    /* handle error */
}
fcntl(sockfd, F_SETFL, oldfl & ~O_NONBLOCK);

Untested, but hope this helps. :-)

Empire answered 23/12, 2008 at 8:55 Comment(4)
Sure. Read my comment to your question too. Namely, unless you had a typo in your edit, you must use & to clear flags, not |.Empire
Daniel thanks for pointing that out. Sometimes I think the abundance of useless error checking like this is what discourages new programmers from doing important error checking where it's actually needed.Mahau
@DanielTrebbien: wrong. Only non-error value is not negative. fcntl(fd, F_GETFL) may fail i.e., it can return -1 e.g., invalid fd may cause EBADF.Ogletree
@J.F.Sebastian: Oops, my mistake. You are correct. In fact, the spec says "Otherwise, -1 shall be returned and errno set to indicate the error." and gives an example: flags = fcntl(fd, F_GETFD); if (flags == -1) /* Handle error */; Chris, I hope you don't mind, but I restored your original code.Flatling
E
3
val = fcntl(fd, F_GETFL, 0);
flags = O_NONBLOCK;
val &= ~flags;
fcntl(fd,F_SETFL,val);

If you do like this,The already set O_NONBLOCK will unset. here,flags contains the which flags you want to unset. After finishing the AND(&) operation,again you have to set the flag using the value in val. I hope this will help you.

Expedition answered 7/10, 2011 at 6:30 Comment(0)
E
1

The following code will unset a flag, for example, the O_NONBLOCK flag:

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 */
        }
}

Regards

Extrusion answered 22/3, 2012 at 10:32 Comment(0)
W
0

Tried unsetting all flags:

fcntl(sockfd, F_SETFL, 0);

Also OR-ing the flags with ~O_NONBLOCK is of no use, you need to AND it, since what you want is to unset the O_NONBLOCK bit(s).

Wallaby answered 23/12, 2008 at 9:7 Comment(1)
Unsetting all flags is a bit overkill if you just want to unset the nonblocking flag. :-)Empire

© 2022 - 2024 — McMap. All rights reserved.