mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
libports: add poll() to libc
Implements poll() via select() for certain programs like OpenSSH which need it. (This implementation is actually based OpenSSHp's compat function.)
This commit is contained in:
parent
ced77c5403
commit
a6917d982a
@ -14,7 +14,7 @@ SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc readlink.cc munmap.cc \
|
||||
issetugid.cc errno.cc gai_strerror.cc clock_gettime.cc \
|
||||
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
|
||||
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
|
||||
libc_mem_alloc.cc pread_pwrite.cc readv_writev.cc
|
||||
libc_mem_alloc.cc pread_pwrite.cc readv_writev.cc poll.cc
|
||||
|
||||
#
|
||||
# Files from string library that are not included in libc-raw_string because
|
||||
|
130
libports/src/lib/libc/poll.cc
Normal file
130
libports/src/lib/libc/poll.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* \brief poll() implementation
|
||||
* \author Josef Soentgen
|
||||
* \date 2012-07-12
|
||||
*
|
||||
* this 'poll()' implementation is based on OpenSSHp's and
|
||||
* uses our 'select()' function internally.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2012 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <os/timed_semaphore.h>
|
||||
|
||||
#include <libc-plugin/plugin_registry.h>
|
||||
#include <libc-plugin/plugin.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/poll.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace Libc;
|
||||
|
||||
|
||||
/**
|
||||
* The poll function was taken from OpenSSH portable (bsd-poll.c) and adepted
|
||||
* to better fit within Genode's libc.
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au).
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
extern "C" int
|
||||
__attribute__((weak))
|
||||
poll(struct pollfd fds[], nfds_t nfds, int timeout)
|
||||
{
|
||||
nfds_t i;
|
||||
int saved_errno, ret, fd, maxfd = 0;
|
||||
fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
|
||||
size_t nmemb;
|
||||
struct timeval tv, *tvp = NULL;
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
fd = fds[i].fd;
|
||||
if (fd >= FD_SETSIZE) {
|
||||
/*errno = EINVAL;*/
|
||||
return -1;
|
||||
}
|
||||
maxfd = MAX(maxfd, fd);
|
||||
}
|
||||
|
||||
nmemb = howmany(maxfd + 1 , NFDBITS);
|
||||
if ((readfds = (fd_set *) calloc(nmemb, sizeof(fd_mask))) == NULL ||
|
||||
(writefds = (fd_set *) calloc(nmemb, sizeof(fd_mask))) == NULL ||
|
||||
(exceptfds = (fd_set *) calloc(nmemb, sizeof(fd_mask))) == NULL) {
|
||||
/*saved_errno = ENOMEM;*/
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* populate event bit vectors for the events we're interested in */
|
||||
for (i = 0; i < nfds; i++) {
|
||||
fd = fds[i].fd;
|
||||
if (fd == -1)
|
||||
continue;
|
||||
if (fds[i].events & POLLIN) {
|
||||
FD_SET(fd, readfds);
|
||||
FD_SET(fd, exceptfds);
|
||||
}
|
||||
if (fds[i].events & POLLOUT) {
|
||||
FD_SET(fd, writefds);
|
||||
FD_SET(fd, exceptfds);
|
||||
}
|
||||
}
|
||||
|
||||
/* poll timeout is msec, select is timeval (sec + usec) */
|
||||
if (timeout >= 0) {
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
tvp = &tv;
|
||||
}
|
||||
|
||||
ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp);
|
||||
/*saved_errno = errno;*/
|
||||
|
||||
/* scan through select results and set poll() flags */
|
||||
for (i = 0; i < nfds; i++) {
|
||||
fd = fds[i].fd;
|
||||
fds[i].revents = 0;
|
||||
if (fd == -1)
|
||||
continue;
|
||||
if (FD_ISSET(fd, readfds)) {
|
||||
fds[i].revents |= POLLIN;
|
||||
}
|
||||
if (FD_ISSET(fd, writefds)) {
|
||||
fds[i].revents |= POLLOUT;
|
||||
}
|
||||
if (FD_ISSET(fd, exceptfds)) {
|
||||
fds[i].revents |= POLLERR;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (readfds != NULL)
|
||||
free(readfds);
|
||||
if (writefds != NULL)
|
||||
free(writefds);
|
||||
if (exceptfds != NULL)
|
||||
free(exceptfds);
|
||||
/*
|
||||
if (ret == -1)
|
||||
errno = saved_errno;
|
||||
*/
|
||||
return ret;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user