From 30fe9d1912f43be32c3c06bf279fa96b52635b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 24 May 2012 15:26:59 +0200 Subject: [PATCH] Extend libc with libresolv functionality This commit enables libc's own libresolv and its dependencies. --- libports/include/libc-plugin/plugin.h | 2 + libports/lib/mk/libc-common.inc | 1 + libports/lib/mk/libc-inet.mk | 2 - libports/lib/mk/libc-isc.mk | 9 +++ libports/lib/mk/libc-nameser.mk | 7 ++ libports/lib/mk/libc-net.mk | 29 +++++++++ libports/lib/mk/libc-resolv.mk | 7 ++ libports/lib/mk/libc.mk | 5 +- libports/lib/mk/libutil.mk | 10 +++ libports/ports/libc.mk | 52 +++++++++++++-- libports/ports/ncurses.mk | 2 +- libports/src/lib/libc/dummies.cc | 3 + libports/src/lib/libc/file_operations.cc | 64 ++++++++++++++++--- libports/src/lib/libc/patches/README | 4 ++ .../src/lib/libc/patches/res_send_c.patch | 35 ++++++++++ libports/src/lib/libc/plugin.cc | 2 + libports/src/lib/libc/select.cc | 25 ++++++++ 17 files changed, 242 insertions(+), 17 deletions(-) create mode 100644 libports/lib/mk/libc-isc.mk create mode 100644 libports/lib/mk/libc-nameser.mk create mode 100644 libports/lib/mk/libc-net.mk create mode 100644 libports/lib/mk/libc-resolv.mk create mode 100644 libports/lib/mk/libutil.mk create mode 100644 libports/src/lib/libc/patches/res_send_c.patch diff --git a/libports/include/libc-plugin/plugin.h b/libports/include/libc-plugin/plugin.h index d02ae57f1d..a9c9dbad9e 100644 --- a/libports/include/libc-plugin/plugin.h +++ b/libports/include/libc-plugin/plugin.h @@ -103,6 +103,7 @@ namespace Libc { virtual ssize_t recv(File_descriptor *, void *buf, ::size_t len, int flags); virtual ssize_t recvfrom(File_descriptor *, void *buf, ::size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); + virtual ssize_t recvmsg(File_descriptor *, struct msghdr *msg, int flags); virtual int rename(const char *oldpath, const char *newpath); virtual int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); @@ -114,6 +115,7 @@ namespace Libc { virtual int setsockopt(File_descriptor *, int level, int optname, const void *optval, socklen_t optlen); + virtual int shutdown(File_descriptor *, int how); virtual File_descriptor *socket(int domain, int type, int protocol); virtual int stat(const char *path, struct stat *buf); virtual int unlink(const char *path); diff --git a/libports/lib/mk/libc-common.inc b/libports/lib/mk/libc-common.inc index 39869865b4..f61d38e98d 100644 --- a/libports/lib/mk/libc-common.inc +++ b/libports/lib/mk/libc-common.inc @@ -4,6 +4,7 @@ LIBC_DIR = $(REP_DIR)/contrib/libc-8.2.0 INC_DIR += $(LIBC_DIR)/libc/locale INC_DIR += $(LIBC_DIR)/libc/include INC_DIR += $(LIBC_DIR)/libc/stdio +INC_DIR += $(LIBC_DIR)/libc/net INC_DIR += $(LIBC_DIR)/gdtoa #CC_OPT += -DGENODE_RELEASE diff --git a/libports/lib/mk/libc-inet.mk b/libports/lib/mk/libc-inet.mk index 9ca30d75d3..9cfb85175a 100644 --- a/libports/lib/mk/libc-inet.mk +++ b/libports/lib/mk/libc-inet.mk @@ -1,7 +1,5 @@ LIBC_INET_DIR = $(LIBC_DIR)/libc/inet -FILTER_OUT_C += nsap_addr.c - SRC_C = $(filter-out $(FILTER_OUT_C),$(notdir $(wildcard $(LIBC_INET_DIR)/*.c))) include $(REP_DIR)/lib/mk/libc-common.inc diff --git a/libports/lib/mk/libc-isc.mk b/libports/lib/mk/libc-isc.mk new file mode 100644 index 0000000000..77156e49cd --- /dev/null +++ b/libports/lib/mk/libc-isc.mk @@ -0,0 +1,9 @@ +LIBC_ISC_DIR = $(LIBC_DIR)/libc/isc + +INC_DIR += $(LIBC_DIR)/libc/isc + +SRC_C = $(notdir $(wildcard $(LIBC_ISC_DIR)/*.c)) + +include $(REP_DIR)/lib/mk/libc-common.inc + +vpath %.c $(LIBC_ISC_DIR) diff --git a/libports/lib/mk/libc-nameser.mk b/libports/lib/mk/libc-nameser.mk new file mode 100644 index 0000000000..f8ad598f0a --- /dev/null +++ b/libports/lib/mk/libc-nameser.mk @@ -0,0 +1,7 @@ +LIBC_NAMESER_DIR = $(LIBC_DIR)/libc/nameser + +SRC_C = $(notdir $(wildcard $(LIBC_NAMESER_DIR)/*.c)) + +include $(REP_DIR)/lib/mk/libc-common.inc + +vpath %.c $(LIBC_NAMESER_DIR) diff --git a/libports/lib/mk/libc-net.mk b/libports/lib/mk/libc-net.mk new file mode 100644 index 0000000000..9c0ca95876 --- /dev/null +++ b/libports/lib/mk/libc-net.mk @@ -0,0 +1,29 @@ +LIBC_NET_DIR = $(LIBC_DIR)/libc/net + +# needed for compiling getservbyname() and getservbyport() +SRC_C = getservent.c nsdispatch.c nsparser.c nslexer.c + +# needed for getaddrinfo() +#SRC_C += getaddrinfo.c + +# getaddrinfo() includes parts of rpc/ which in return includes +# even more stuff from the rpc framework. For now the effort for +# getting this right is too much. + +# needed for gethostbyname() +SRC_C += gethostnamadr.c gethostbydns.c gethostbyht.c map_v4v6.c + +# needed for getprotobyname() +SRC_C += getprotoent.c getprotoname.c + +# defines in6addr_any +SRC_C += vars.c + +# b64_ntop +SRC_C += base64.c + +INC_DIR += $(REP_DIR)/include/libc/sys + +include $(REP_DIR)/lib/mk/libc-common.inc + +vpath %.c $(LIBC_NET_DIR) diff --git a/libports/lib/mk/libc-resolv.mk b/libports/lib/mk/libc-resolv.mk new file mode 100644 index 0000000000..8ad066125d --- /dev/null +++ b/libports/lib/mk/libc-resolv.mk @@ -0,0 +1,7 @@ +LIBC_RESOLV_DIR = $(LIBC_DIR)/libc/resolv + +SRC_C = $(notdir $(wildcard $(LIBC_RESOLV_DIR)/*.c)) + +include $(REP_DIR)/lib/mk/libc-common.inc + +vpath %.c $(LIBC_RESOLV_DIR) diff --git a/libports/lib/mk/libc.mk b/libports/lib/mk/libc.mk index 79aada8ee3..75a8214644 100644 --- a/libports/lib/mk/libc.mk +++ b/libports/lib/mk/libc.mk @@ -1,9 +1,10 @@ # # C Library including string, locale # - LIBS = libc-string libc-locale libc-stdlib libc-stdio libc-gen libc-gdtoa \ - libc-inet libc-stdtime libc-regex libc-compat libc-setjmp + libc-net libc-inet libc-stdtime libc-regex libc-compat libc-resolv \ + libc-isc libc-nameser libc-setjmp + LIBS += timed_semaphore cxx # diff --git a/libports/lib/mk/libutil.mk b/libports/lib/mk/libutil.mk new file mode 100644 index 0000000000..755ebc9617 --- /dev/null +++ b/libports/lib/mk/libutil.mk @@ -0,0 +1,10 @@ +LIBC_UTIL_DIR = $(LIBC_DIR)/libutil + +# needed by libinetutils +SRC_C = logout.c logwtmp.c trimdomain.c + +INC_DIR += $(LIBC_UTIL_DIR) + +include $(REP_DIR)/lib/mk/libc-common.inc + +vpath %.c $(LIBC_UTIL_DIR) diff --git a/libports/ports/libc.mk b/libports/ports/libc.mk index 26bddcc6a3..c753f239c2 100644 --- a/libports/ports/libc.mk +++ b/libports/ports/libc.mk @@ -5,18 +5,28 @@ LIBC := libc-8.2.0 # PORTS += $(LIBC) +# +# Sanity check for tools +# +ifeq ($(shell which lex),) +$(error Missing installation of 'lex' (package flex)) +endif + # # Subdirectories to check out from FreeBSD's Subversion repository # LIBC_SVN_BASE = http://svn.freebsd.org/base/release/8.2.0 -LIBC_CONTRIB_SUB_DIRS = libc include sys_sys sys_netinet sys_netinet6 \ - sys_bsm sys_vm sys_arm sys_i386 sys_amd64 \ +LIBC_CONTRIB_SUB_DIRS = libc libutil include sys_sys sys_netinet sys_netinet6 \ + sys_net sys_bsm sys_rpc sys_vm sys_arm sys_i386 sys_amd64 \ msun gdtoa LIBC_SVN_libc = lib/libc +LIBC_SVN_libutil = lib/libutil LIBC_SVN_include = include LIBC_SVN_sys_sys = sys/sys +LIBC_SVN_sys_rpc = sys/rpc +LIBC_SVN_sys_net = sys/net LIBC_SVN_sys_netinet = sys/netinet LIBC_SVN_sys_netinet6 = sys/netinet6 LIBC_SVN_sys_bsm = sys/bsm @@ -53,8 +63,11 @@ LIBC_IMPORT_INCLUDES = include/libc/strings.h \ include/libc/time.h \ include/libc/sysexits.h \ include/libc/arpa/inet.h \ + include/libc/arpa/ftp.h \ include/libc/arpa/nameser.h \ include/libc/arpa/nameser_compat.h \ + include/libc/arpa/telnet.h \ + include/libc/arpa/tftp.h \ include/libc/resolv.h \ include/libc/wctype.h \ include/libc/fcntl.h \ @@ -68,7 +81,9 @@ LIBC_IMPORT_INCLUDES = include/libc/strings.h \ include/libc/ar.h \ include/libc/stdint.h \ include/libc/ieeefp.h \ - include/libc/memory.h + include/libc/memory.h \ + include/libc/res_update.h \ + include/libc/rpc/rpc.h # # Files from include directory needed for stdlib @@ -132,11 +147,18 @@ LIBC_IMPORT_INCLUDES += include/libc/vm/vm_param.h \ include/libc/vm/vm.h \ include/libc/vm/pmap.h +# +# Files coming from the sys/net directories +# +LIBC_IMPORT_INCLUDES += include/libc/net/if.h + # # Files coming from the sys/netinet and sys/netinet6 directories # LIBC_IMPORT_INCLUDES += include/libc/netinet/in.h \ + include/libc/netinet/in_systm.h \ include/libc/netinet6/in6.h \ + include/libc/netinet/ip.h \ include/libc/netinet/tcp.h # @@ -160,6 +182,7 @@ LIBC_IMPORT_INCLUDES += include/libc/sys/_types.h \ include/libc/sys/time.h \ include/libc/sys/param.h \ include/libc/sys/stdint.h \ + include/libc/sys/event.h \ include/libc/errno.h # @@ -371,6 +394,21 @@ LIBC_IMPORT_INCLUDES += include/libc-amd64/fenv.h # LIBC_IMPORT_INCLUDES += include/libc/bsm/audit.h +# +# Generate files needed for compiling libc-net +# +libc_gen_nslexer: $(CONTRIB_DIR)/$(LIBC)/libc/net/nslexer.l + $(VERBOSE)$(LEX) -P_nsyy -t $< | \ + sed -e '/YY_BUF_SIZE/s/16384/1024/' \ + > $(CONTRIB_DIR)/$(LIBC)/libc/net/nslexer.c + +libc_gen_nsparser: $(CONTRIB_DIR)/$(LIBC)/libc/net/nsparser.y + $(VERBOSE)$(YACC) -d -p_nsyy $< \ + --defines=$(CONTRIB_DIR)/$(LIBC)/libc/net/nsparser.h \ + --output=$(CONTRIB_DIR)/$(LIBC)/libc/net/nsparser.c + +libc_net_generate: libc_gen_nslexer libc_gen_nsparser + ## # Shortcut for creating a symlink # @@ -386,12 +424,18 @@ include/libc/arpa/%.h: $(CONTRIB_DIR)/$(LIBC)/include/arpa/%.h include/libc/%.h: $(CONTRIB_DIR)/$(LIBC)/include/%.h $(libc_gen_symlink_subsub) +include/libc/net/%.h: $(CONTRIB_DIR)/$(LIBC)/sys_net/%.h + $(libc_gen_symlink_subsubsub) + include/libc/netinet/%.h: $(CONTRIB_DIR)/$(LIBC)/sys_netinet/%.h $(libc_gen_symlink_subsubsub) include/libc/netinet6/%.h: $(CONTRIB_DIR)/$(LIBC)/sys_netinet6/%.h $(libc_gen_symlink_subsubsub) +include/libc/rpc/%.h: $(CONTRIB_DIR)/$(LIBC)/include/rpc/%.h + $(libc_gen_symlink_subsubsub) + include/libc/%.h: $(CONTRIB_DIR)/$(LIBC)/sys_sys/%.h $(libc_gen_symlink_subsub) @@ -456,7 +500,7 @@ apply_patches-libc: checkout-libc create_include_symlinks-libc: checkout-libc $(VERBOSE)make -s $(LIBC_IMPORT_INCLUDES) -prepare-libc: create_include_symlinks-libc apply_patches-libc +prepare-libc: create_include_symlinks-libc apply_patches-libc libc_net_generate clean_include_symlinks-libc: $(VERBOSE)find include -type l -delete diff --git a/libports/ports/ncurses.mk b/libports/ports/ncurses.mk index 7d391f4097..e2ef4ee168 100644 --- a/libports/ports/ncurses.mk +++ b/libports/ports/ncurses.mk @@ -153,7 +153,7 @@ src/lib/ncurses/codes.c: src/lib/ncurses/fallback.c: $(NCURSES_SRC_DIR)/tinfo/MKfallback.sh $(VERBOSE)sh -e $< x $(CONTRIB_DIR)/$(NCURSES)/misc/terminfo.src tic linux > $@ - #$(VERBOSE)sh -e $< /usr/share/terminfo $(NCURSES_SRC_DIR)/misc/terminfo.src /usr/bin/tic > $@ + $(VERBOSE)#sh -e $< /usr/share/terminfo $(NCURSES_SRC_DIR)/misc/terminfo.src /usr/bin/tic > $@ src/lib/ncurses/unctrl.c: $(VERBOSE)echo | mawk -f $(NCURSES_SRC_DIR)/base/MKunctrl.awk bigstrings=1 > $@ diff --git a/libports/src/lib/libc/dummies.cc b/libports/src/lib/libc/dummies.cc index 60d4a39aac..64619fbf90 100644 --- a/libports/src/lib/libc/dummies.cc +++ b/libports/src/lib/libc/dummies.cc @@ -29,6 +29,7 @@ DUMMY name(void) { \ DUMMY(-1, access) DUMMY(-1, chmod) DUMMY(-1, chown) +DUMMY(-1, chroot) DUMMY( 0, crypt) DUMMY( 0, dbopen) DUMMY(-1, dup) @@ -65,6 +66,8 @@ DUMMY(-1, getsid) DUMMY(-1, getppid) DUMMY(-1, getpgrp) DUMMY(-1, getpriority) +DUMMY(-1, __getpty) +DUMMY(-1, _getpty) DUMMY(-1, getrusage) DUMMY( 0, getuid) DUMMY(-1, __has_sse) diff --git a/libports/src/lib/libc/file_operations.cc b/libports/src/lib/libc/file_operations.cc index e72c0e9e19..82176f5831 100644 --- a/libports/src/lib/libc/file_operations.cc +++ b/libports/src/lib/libc/file_operations.cc @@ -227,17 +227,25 @@ extern "C" ssize_t _getdirentries(int libc_fd, char *buf, ::size_t nbytes, ::off FD_FUNC_WRAPPER(getdirentries, libc_fd, buf, nbytes, basep); } -extern "C" int getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { + +extern "C" int _getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { FD_FUNC_WRAPPER(getpeername, libc_fd, addr, addrlen); } -extern "C" int getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { +extern "C" int getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) +{ + return _getpeername(libc_fd, addr, addrlen); +} + + +extern "C" int _getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen); } -extern "C" int getsockopt(int libc_fd, int level, int optname, - void *optval, socklen_t *optlen) { - FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen); } +extern "C" int getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) +{ + return _getsockname(libc_fd, addr, addrlen); +} extern "C" int ioctl(int libc_fd, int request, char *argp) { @@ -348,11 +356,22 @@ extern "C" ssize_t recv(int libc_fd, void *buf, ::size_t len, int flags) { FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags); } -extern "C" ssize_t recvfrom(int libc_fd, void *buf, ::size_t len, int flags, +extern "C" ssize_t _recvfrom(int libc_fd, void *buf, ::size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, addrlen); } +extern "C" ssize_t recvfrom(int libc_fd, void *buf, ::size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + return _recvfrom(libc_fd, buf, len, flags, src_addr, addrlen); +} + + +extern "C" ssize_t recvmsg(int libc_fd, struct msghdr *msg, int flags) { + FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags); } + + extern "C" int rename(const char *oldpath, const char *newpath) { FNAME_FUNC_WRAPPER(rename, oldpath, newpath); } @@ -361,16 +380,45 @@ extern "C" ssize_t send(int libc_fd, const void *buf, ::size_t len, int flags) { FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags); } -extern "C" ssize_t sendto(int libc_fd, const void *buf, ::size_t len, int flags, +extern "C" ssize_t _sendto(int libc_fd, const void *buf, ::size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, addrlen); } -extern "C" int setsockopt(int libc_fd, int level, int optname, +extern "C" ssize_t sendto(int libc_fd, const void *buf, ::size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + return _sendto(libc_fd, buf, len, flags, dest_addr, addrlen); +} + + +extern "C" int _getsockopt(int libc_fd, int level, int optname, + void *optval, socklen_t *optlen) +{ + return getsockopt(libc_fd, level, optname, optval, optlen); +} + + +extern "C" int getsockopt(int libc_fd, int level, int optname, + void *optval, socklen_t *optlen) { + FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen); } + + +extern "C" int _setsockopt(int libc_fd, int level, int optname, const void *optval, socklen_t optlen) { FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen); } +extern "C" int setsockopt(int libc_fd, int level, int optname, + const void *optval, socklen_t optlen) +{ + return _setsockopt(libc_fd, level, optname, optval, optlen); +} + + +extern "C" int shutdown(int libc_fd, int how) { + FD_FUNC_WRAPPER(shutdown, libc_fd, how); } + extern "C" int socket(int domain, int type, int protocol) { Plugin *plugin; diff --git a/libports/src/lib/libc/patches/README b/libports/src/lib/libc/patches/README index 1b0cb38e71..4d0c13a692 100644 --- a/libports/src/lib/libc/patches/README +++ b/libports/src/lib/libc/patches/README @@ -17,3 +17,7 @@ Manual modifications C++ support library as weak symbol. By redefining this symbol as non-weak in the libc, the C++ support library would use the libc dummy stub instead its own implementation, causing problems with handling exceptions. + +:'src/lib/libc/resolv/res_send.c': + + Disable usage of kqueue and fix building libresolv when kqueue is disabled. diff --git a/libports/src/lib/libc/patches/res_send_c.patch b/libports/src/lib/libc/patches/res_send_c.patch new file mode 100644 index 0000000000..13bb51357e --- /dev/null +++ b/libports/src/lib/libc/patches/res_send_c.patch @@ -0,0 +1,35 @@ +--- libc/include/port_after.h.orig 2006-03-21 19:31:24.000000000 +0100 ++++ libc/include/port_after.h 2012-05-24 11:22:13.453080652 +0200 +@@ -4,7 +4,7 @@ + #define _PORT_AFTER_H_ + + #define HAVE_SA_LEN 1 +-#define HAS_INET6_STRUCTS 1 ++//#define HAS_INET6_STRUCTS 1 + #define HAVE_SIN6_SCOPE_ID 1 + #define HAVE_TIME_R 1 + +--- libc/include/port_before.h.orig 2006-03-21 16:37:16.000000000 +0100 ++++ libc/include/port_before.h 2012-05-24 11:22:13.453080652 +0200 +@@ -4,8 +4,8 @@ + #define _PORT_BEFORE_H_ + + #define _LIBC 1 +-#define DO_PTHREADS 1 +-#define USE_KQUEUE 1 ++//#define DO_PTHREADS 1 ++//#define USE_KQUEUE 1 + + #define ISC_SOCKLEN_T socklen_t + #define ISC_FORMAT_PRINTF(fmt, args) \ +--- libc/resolv/res_send.c.orig 2008-12-14 20:39:53.360146000 +0100 ++++ libc/resolv/res_send.c 2012-05-24 11:29:55.602592107 +0200 +@@ -78,7 +78,7 @@ + + #include "port_before.h" + #ifndef USE_KQUEUE +-#include "fd_setsize.h" ++//#include "fd_setsize.h" + #endif + + #include "namespace.h" diff --git a/libports/src/lib/libc/plugin.cc b/libports/src/lib/libc/plugin.cc index bfa48daa06..ac8e1b0966 100644 --- a/libports/src/lib/libc/plugin.cc +++ b/libports/src/lib/libc/plugin.cc @@ -164,9 +164,11 @@ DUMMY(::off_t, -1, lseek, (File_descriptor *, ::off_t, int)); DUMMY(ssize_t, -1, read, (File_descriptor *, void *, ::size_t)); DUMMY(ssize_t, -1, recv, (File_descriptor *, void *, ::size_t, int)); DUMMY(ssize_t, -1, recvfrom, (File_descriptor *, void *, ::size_t, int, struct sockaddr *, socklen_t *)); +DUMMY(ssize_t, -1, recvmsg, (File_descriptor *, struct msghdr *, int)); DUMMY(ssize_t, -1, send, (File_descriptor *, const void *, ::size_t, int)); DUMMY(ssize_t, -1, sendto, (File_descriptor *, const void *, ::size_t, int, const struct sockaddr *, socklen_t)); DUMMY(int, -1, setsockopt, (File_descriptor *, int, int, const void *, socklen_t)); +DUMMY(int, -1, shutdown, (File_descriptor *, int)); DUMMY(ssize_t, -1, write, (File_descriptor *, const void *, ::size_t)); diff --git a/libports/src/lib/libc/select.cc b/libports/src/lib/libc/select.cc index 76b989b092..fc0a3a4b12 100644 --- a/libports/src/lib/libc/select.cc +++ b/libports/src/lib/libc/select.cc @@ -21,6 +21,7 @@ #include #include +#include using namespace Libc; @@ -272,3 +273,27 @@ select(int nfds, fd_set *readfds, fd_set *writefds, return nready; } + +extern "C" int +__attribute__((weak)) +pselect(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, const struct timespec *timeout, + const sigset_t *sigmask) +{ + struct timeval tv, *tvp; + sigset_t origmask; + int nready; + + if (timeout) { + tv.tv_usec = timeout->tv_nsec / 1000; + tv.tv_sec = timeout->tv_sec; + } + + if (sigmask) + sigprocmask(SIG_SETMASK, sigmask, &origmask); + nready = select(nfds, readfds, writefds, exceptfds, &tv); + if (sigmask) + sigprocmask(SIG_SETMASK, &origmask, NULL); + + return nready; +}