111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes/* 211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * Copyright (C) 2013 The Android Open Source Project 311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * All rights reserved. 411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * 511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * Redistribution and use in source and binary forms, with or without 611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * modification, are permitted provided that the following conditions 711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * are met: 811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * * Redistributions of source code must retain the above copyright 911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * notice, this list of conditions and the following disclaimer. 1011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * * Redistributions in binary form must reproduce the above copyright 1111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * notice, this list of conditions and the following disclaimer in 1211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * the documentation and/or other materials provided with the 1311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * distribution. 1411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * 1511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes * SUCH DAMAGE. 2711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes */ 2811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 2911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes#include <sys/poll.h> 3011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes#include <sys/select.h> 3111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 3211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes#include "private/bionic_time_conversions.h" 3311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes#include "private/kernel_sigset_t.h" 3411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 3511952073af22568bba0b661f7a9d4402c443a888Elliott Hughesextern "C" int __ppoll(pollfd*, unsigned int, timespec*, const kernel_sigset_t*, size_t); 3611952073af22568bba0b661f7a9d4402c443a888Elliott Hughesextern "C" int __pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*); 3711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 3811952073af22568bba0b661f7a9d4402c443a888Elliott Hughesint poll(pollfd* fds, nfds_t fd_count, int ms) { 3911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec ts; 4011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec* ts_ptr = NULL; 4111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (ms >= 0) { 4211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec_from_ms(ts, ms); 4311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ts_ptr = &ts; 4411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 4511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes return __ppoll(fds, fd_count, ts_ptr, NULL, 0); 4611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes} 4711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 4811952073af22568bba0b661f7a9d4402c443a888Elliott Hughesint ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) { 4911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec mutable_ts; 5011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec* mutable_ts_ptr = NULL; 5111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (ts != NULL) { 5211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes mutable_ts = *ts; 5311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes mutable_ts_ptr = &mutable_ts; 5411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 5511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 5611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_sigset_t kernel_ss; 5711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_sigset_t* kernel_ss_ptr = NULL; 5811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (ss != NULL) { 5911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_ss.set(ss); 6011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_ss_ptr = &kernel_ss; 6111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 6211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 6311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes return __ppoll(fds, fd_count, mutable_ts_ptr, kernel_ss_ptr, sizeof(kernel_ss)); 6411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes} 6511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 6611952073af22568bba0b661f7a9d4402c443a888Elliott Hughesint select(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, timeval* tv) { 6711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec ts; 6811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec* ts_ptr = NULL; 6911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (tv != NULL) { 7011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (!timespec_from_timeval(ts, *tv)) { 7111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes errno = EINVAL; 7211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes return -1; 7311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 7411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes ts_ptr = &ts; 7511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 7611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes int result = __pselect6(fd_count, read_fds, write_fds, error_fds, ts_ptr, NULL); 7711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (tv != NULL) { 7811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timeval_from_timespec(*tv, ts); 7911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 8011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes return result; 8111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes} 8211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 8311952073af22568bba0b661f7a9d4402c443a888Elliott Hughesint pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds, 8411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes const timespec* ts, const sigset_t* ss) { 8511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec mutable_ts; 8611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes timespec* mutable_ts_ptr = NULL; 8711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (ts != NULL) { 8811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes mutable_ts = *ts; 8911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes mutable_ts_ptr = &mutable_ts; 9011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 9111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 9211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_sigset_t kernel_ss; 9311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_sigset_t* kernel_ss_ptr = NULL; 9411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes if (ss != NULL) { 9511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_ss.set(ss); 9611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes kernel_ss_ptr = &kernel_ss; 9711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes } 9811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 9911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes // The Linux kernel only handles 6 arguments and this system call really needs 7, 10011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes // so the last argument is a void* pointing to: 10111952073af22568bba0b661f7a9d4402c443a888Elliott Hughes struct pselect6_extra_data_t { 10211952073af22568bba0b661f7a9d4402c443a888Elliott Hughes uintptr_t ss_addr; 10311952073af22568bba0b661f7a9d4402c443a888Elliott Hughes size_t ss_len; 10411952073af22568bba0b661f7a9d4402c443a888Elliott Hughes }; 10511952073af22568bba0b661f7a9d4402c443a888Elliott Hughes pselect6_extra_data_t extra_data; 10611952073af22568bba0b661f7a9d4402c443a888Elliott Hughes extra_data.ss_addr = reinterpret_cast<uintptr_t>(kernel_ss_ptr); 10711952073af22568bba0b661f7a9d4402c443a888Elliott Hughes extra_data.ss_len = sizeof(kernel_ss); 10811952073af22568bba0b661f7a9d4402c443a888Elliott Hughes 10911952073af22568bba0b661f7a9d4402c443a888Elliott Hughes return __pselect6(fd_count, read_fds, write_fds, error_fds, mutable_ts_ptr, &extra_data); 11011952073af22568bba0b661f7a9d4402c443a888Elliott Hughes} 111