Commit ef3dd5c0 authored by Jan Kiszka's avatar Jan Kiszka
Browse files

cobalt/select: Add proper handling of EADV

Since rtdm_fd_select started to return EADV for unknown fds

), we were returning that code to applications in case a
selector had been allocated for the caller already. That was because
libcobalt lacked handling of this error.

This fixes it and also establish proper signaling of EBADF in case the
is a real error related to an RTDM fd. For that purpose, detect if
__cobalt_select_bind_all got EADV for the first fd or for a succeeding
one, i.e. on an unsupported mixed fd set.

Also return EADV if the early __cobalt_first_fd_valid_p test fails. That
ensures that we only retry with the regular Linux call when it makes
Signed-off-by: Jan Kiszka's avatarJan Kiszka <>
parent 3b7f4bc4
......@@ -183,6 +183,7 @@ int __cobalt_first_fd_valid_p(fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
int __cobalt_select_bind_all(struct xnselector *selector,
fd_set *fds[XNSELECT_MAX_TYPES], int nfds)
bool first_fd = true;
unsigned fd, type;
int err;
......@@ -193,8 +194,16 @@ int __cobalt_select_bind_all(struct xnselector *selector,
fd < nfds;
fd = find_next_bit(set->fds_bits, nfds, fd + 1)) {
err = rtdm_fd_select(fd, selector, type);
if (err)
if (err) {
* Do not needlessly signal "retry
* under Linux" for mixed fd sets.
if (err == -EADV && !first_fd)
return -EBADF;
return err;
first_fd = false;
......@@ -275,7 +284,7 @@ COBALT_SYSCALL(select, primary,
simple test: test if the first file descriptor we find in the
fd_set is an RTDM descriptor or a message queue descriptor. */
if (!__cobalt_first_fd_valid_p(in_fds, nfds))
return -EBADF;
return -EADV;
selector = xnmalloc(sizeof(*curr->selector));
if (selector == NULL)
......@@ -796,7 +796,7 @@ COBALT_SYSCALL32emu(select, nonrestartable,
if (selector == NULL) {
/* Bail out if non-RTDM fildes is found. */
if (!__cobalt_first_fd_valid_p(in_fds, nfds))
return -EBADF;
return -EADV;
selector = xnmalloc(sizeof(*curr->selector));
if (selector == NULL)
......@@ -36,7 +36,7 @@ COBALT_IMPL(int, select, (int __nfds, fd_set *__restrict __readfds,
pthread_setcanceltype(oldtype, NULL);
if (err == -EBADF || err == -EPERM || err == -ENOSYS)
if (err == -EADV || err == -EPERM || err == -ENOSYS)
return __STD(select(__nfds, __readfds,
__writefds, __exceptfds, __timeout));
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment