diff --git a/compat/pselect.c b/compat/pselect.c new file mode 100644 index 00000000..79302158 --- /dev/null +++ b/compat/pselect.c @@ -0,0 +1,65 @@ +/* + * dhcpcd - DHCP client daemon + * Copyright (c) 2006-2012 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +#include "pselect.h" + +#warning "This pselect(2) implementation is not entirely race condition safe." +#warning "Only operating system support for pselect(2) can correct this." + +int +pselect(int nfds, + fd_set *restrict readfds, + fd_set *restrict writefds, + fd_set *restrict errorfds, + const struct timespec *restrict timeout, + const sigset_t *restrict newset) +{ + int r; + sigset_t oldset; + struct timeval saved_timeout; + + if (newset && sigprocmask(SIG_SETMASK, newset, &oldset) == -1) + return -1; + + if (timeout) { + saved_timeout.tv_sec = timeout->tv_sec; + saved_timeout.tv_usec = timeout->tv_nsec / 1000; + r = select(nfds, readfds, writefds, errorfds, &saved_timeout); + } else + r = select(nfds, readfds, writefds, errorfds, NULL); + + if (newset && sigprocmask(SIG_SETMASK, &oldset, NULL) == -1) + return -1; + + return r; +} diff --git a/compat/pselect.h b/compat/pselect.h new file mode 100644 index 00000000..2d61ce36 --- /dev/null +++ b/compat/pselect.h @@ -0,0 +1,40 @@ +/* + * dhcpcd - DHCP client daemon + * Copyright (c) 2006-2012 Roy Marples + * All rights reserved + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef PSELECT_H +#define PSELECT_H + +#include +#include + +#include + +int pselect(int, fd_set *restrict, fd_set *restrict, fd_set *restrict, + const struct timespec *restrict, + const sigset_t *restrict); + +#endif diff --git a/configure b/configure index 233f23c1..32a4dfd0 100755 --- a/configure +++ b/configure @@ -50,6 +50,8 @@ for x do --without-closefrom) CLOSEFROM=no;; --without-getline) GETLINE=no;; --without-strlcpy) STRLCPY=no;; + --without-posix_spawn) POSIX_SPAWN=no;; + --without-pselect) PSELECT=no;; --serviceexists) SERVICEEXISTS=$var;; --servicecmd) SERVICECMD=$var;; --servicestatus) SERVICESTATUS=$var;; @@ -437,6 +439,29 @@ else echo "#include " >>$CONFIG_H fi +if [ -z "$PSELECT" ]; then + printf "Testing for pselect ... " + cat <_pselect.c +#include +#include +int main(void) { + pselect(0, NULL, NULL, NULL, NULL, NULL); + return 0; +} +EOF + if $XCC _pselect.c -o _pselect 2>/dev/null; then + PSELECT=yes + else + PSELECT=no + fi + echo "$PSELECT" + rm -f _pselect.c _pselect +fi +if [ "$PSELECT" = no ]; then + echo "COMPAT_SRCS+= compat/pselect.c" >>$CONFIG_MK + echo "#include \"compat/pselect.h\"" >>$CONFIG_H +fi + if [ -z "$SERVICECMD" ]; then printf "Checking for OpenRC ... " if [ -x /sbin/rc-service ]; then