This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] handle EPROTOTYPE for socket invocations with SOCK_* flags


> since glibc 2.16, Hurd's bits/socket.h provides SOCK_CLOEXEC and 
> SOCK_NONBLOCK (which accept4 handles), but __ASSUME_SOCK_CLOEXEC is not 
> defined since socket and socketpair do not handle them, yet.

Separate from this change, implementing SOCK_CLOEXEC should be very easy.

> The snippets of fallback code that handle failures of invocation of 
> socket with SOCK_CLOEXEC or SOCK_NONBLOCK seem to not correctly disable 
> have_sock_cloexec/__have_sock_cloexec if errno is EPROTOTYPE, as 
> returned when the socket type (like "SOCK_STREAM | SOCK_CLOEXEC" for 
> socket with no handling of flags) is unknown.

There seem to be multiple errno values that could indicate this.  POSIX
specifies that socket shall fail with EPROTOTYPE if "The socket type is not
supported by the protocol."  This could be construed as applying only if
the type value is valid in general and is not supported by the particular
protocol.  By that reading, it still conforms to POSIX if socket uses any
errno code it likes (except those specified for other error cases of
socket, like EAFNOSUPPORT; EINVAL is not specified for socket).

> The attached patch handles EPROTOTYPE as if it was EINVAL, disabling 
> have_sock_cloexec/__have_sock_cloexec if socket does not handle SOCK_* 
> flags.
> 
> (OTOH, it seems that there are few Linux archs -- like mips*, arm, hppa, 
> m68k -- which don't have __ASSUME_SOCK_CLOEXEC enabled in their
> kernel-features.h at all: does it mean the Linux kernel really returns 
> EINVAL for unknown values as socket types?)

It depends on the value.  For large values, it returns EINVAL.  For
unassigned values between the lowest and highest values in use, it returns
ESOCKTNOSUPPORT (a code not specified by POSIX at all).  Since the flags
are in the high bits, any type with flags OR'd in will be seen as "large"
and get EINVAL.

Looking at NetBSD kernel source, I think it will return EPROTOTYPE only if
the protocol argument is zero but the type argument is nonzero (and not
supported).  Otherwise it will return EPROTONOSUPPORT.

It seems wisest to accept all the errors we think could ever be used for
this case: EINVAL, ESOCKTNOSUPPORT, EPROTOTYPE, EPROTONOSUPPORT.

Arguably we should harmonize the Hurd's use of errno codes here either to
Linux or to BSD.  That is, unless someone gets a clarification from the
POSIX committee and that says that the behavior is nonconforming.  (I'm not
really clear on how it could be, since you have to write a nonconforming
program to elicit these errors.)

> 	* nscd/connections.c (nscd_init) [!defined __ASSUME_SOCK_CLOEXEC]:

The format is just [!__ASSUME_SOCK_CLOEXEC], no "defined".
(Yes, it is potentially imprecise.  But that's the convention.)

> -	have_sock_cloexec = sock != -1 || errno != EINVAL ? 1 : -1;
> +	have_sock_cloexec = sock != -1 || (errno != EINVAL && errno != EPROTOTYPE) ? 1 : -1;

This line is now too long and needs to be wrapped.
But we should avoid repeating this knowledge in all these places.
Instead define an inline function somewhere and use that.


Thanks,
Roland


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]