NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/47569: SOCK_NONBLOCK flag to socket(2) doesn't work
>Number: 47569
>Category: kern
>Synopsis: SOCK_NONBLOCK flag to socket(2) doesn't work
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Feb 14 21:35:01 +0000 2013
>Originator: Valery Ushakov
>Release: NetBSD 6
>Organization:
>Environment:
>Description:
SOCK_NONBLOCK flag is documented in socket(2) man page to make socket
non-blocking. Unfortunately it doesn't.
A socket created with that flag has O_NONBLOCK in flags (as per fcntl
F_GETFL), but it seems the flag is not reflected as SS_NBIO flag in
socket::so_state correctly.
A socket created without SOCK_NONBLOCK can be made nonblocking with
either fcntl(F_SETFL) that adds O_NONBLOCK, or with ioctl(FIONBIO).
A socket created with SOCK_NONBLOCK is made nonblocking with
ioctl(FIONBIO). On the other hand since O_NONBLOCK is already set in
flags, fcntl(F_SETFL) doesn't help and you would need to do two
F_SETFL once to clear O_NONBLOCK (from SOCK_NONBLOCK) then another to
set it (and correctly push it out to so_state).
>How-To-Repeat:
I don't have a minimized test case handy and don't have time to write
one right now, but it's trivial code along the lines of
s = socket(PF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
status = connect(s, ...);
/* check errno */
where the sockaddr is e.g. some non-assigned IP that would cause
ETIMEDOUT.
This code will be blocked in connect(2) and will eventually return -1
and set ETIMEDOUT instead of returning immediately and setting
EINPROGRESS.
If ioctl(FIONBIO) is added before connect(2), connect(2) does become
nonblocking.
>Fix:
Home |
Main Index |
Thread Index |
Old Index