mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Add gnulib `select' module.
Should fix fport_input_waiting when neither poll nor select nor FIONREAD are available, which is the case on MinGW. Thanks to Eli Zaretskii for the report.
This commit is contained in:
parent
af07e10429
commit
3dac6181c1
10 changed files with 1881 additions and 2 deletions
|
@ -21,7 +21,7 @@
|
||||||
# the same distribution terms as the rest of that program.
|
# the same distribution terms as the rest of that program.
|
||||||
#
|
#
|
||||||
# Generated by gnulib-tool.
|
# Generated by gnulib-tool.
|
||||||
# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp full-read full-write func gendocs getaddrinfo getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe2 putenv recv recvfrom regex rename send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat trunc verify vsnprintf warnings wchar
|
# Reproduce by: gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp full-read full-write func gendocs getaddrinfo getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe2 putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat trunc verify vsnprintf warnings wchar
|
||||||
|
|
||||||
AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
|
AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ libgnu_la_LDFLAGS += $(ISNANL_LIBM)
|
||||||
libgnu_la_LDFLAGS += $(LDEXP_LIBM)
|
libgnu_la_LDFLAGS += $(LDEXP_LIBM)
|
||||||
libgnu_la_LDFLAGS += $(LIBSOCKET)
|
libgnu_la_LDFLAGS += $(LIBSOCKET)
|
||||||
libgnu_la_LDFLAGS += $(LIB_CLOCK_GETTIME)
|
libgnu_la_LDFLAGS += $(LIB_CLOCK_GETTIME)
|
||||||
|
libgnu_la_LDFLAGS += $(LIB_SELECT)
|
||||||
libgnu_la_LDFLAGS += $(LOG1P_LIBM)
|
libgnu_la_LDFLAGS += $(LOG1P_LIBM)
|
||||||
libgnu_la_LDFLAGS += $(LOG_LIBM)
|
libgnu_la_LDFLAGS += $(LOG_LIBM)
|
||||||
libgnu_la_LDFLAGS += $(LTLIBICONV)
|
libgnu_la_LDFLAGS += $(LTLIBICONV)
|
||||||
|
@ -87,6 +88,17 @@ EXTRA_DIST += alignof.h
|
||||||
|
|
||||||
## end gnulib module alignof
|
## end gnulib module alignof
|
||||||
|
|
||||||
|
## begin gnulib module alloca
|
||||||
|
|
||||||
|
|
||||||
|
libgnu_la_LIBADD += @LTALLOCA@
|
||||||
|
libgnu_la_DEPENDENCIES += @LTALLOCA@
|
||||||
|
EXTRA_DIST += alloca.c
|
||||||
|
|
||||||
|
EXTRA_libgnu_la_SOURCES += alloca.c
|
||||||
|
|
||||||
|
## end gnulib module alloca
|
||||||
|
|
||||||
## begin gnulib module alloca-opt
|
## begin gnulib module alloca-opt
|
||||||
|
|
||||||
BUILT_SOURCES += $(ALLOCA_H)
|
BUILT_SOURCES += $(ALLOCA_H)
|
||||||
|
@ -371,6 +383,15 @@ EXTRA_DIST += dosname.h
|
||||||
|
|
||||||
## end gnulib module dosname
|
## end gnulib module dosname
|
||||||
|
|
||||||
|
## begin gnulib module dup2
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_DIST += dup2.c
|
||||||
|
|
||||||
|
EXTRA_libgnu_la_SOURCES += dup2.c
|
||||||
|
|
||||||
|
## end gnulib module dup2
|
||||||
|
|
||||||
## begin gnulib module duplocale
|
## begin gnulib module duplocale
|
||||||
|
|
||||||
|
|
||||||
|
@ -1560,6 +1581,15 @@ EXTRA_DIST += same-inode.h
|
||||||
|
|
||||||
## end gnulib module same-inode
|
## end gnulib module same-inode
|
||||||
|
|
||||||
|
## begin gnulib module select
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_DIST += select.c
|
||||||
|
|
||||||
|
EXTRA_libgnu_la_SOURCES += select.c
|
||||||
|
|
||||||
|
## end gnulib module select
|
||||||
|
|
||||||
## begin gnulib module send
|
## begin gnulib module send
|
||||||
|
|
||||||
|
|
||||||
|
@ -2314,6 +2344,40 @@ EXTRA_DIST += sys_file.in.h
|
||||||
|
|
||||||
## end gnulib module sys_file
|
## end gnulib module sys_file
|
||||||
|
|
||||||
|
## begin gnulib module sys_select
|
||||||
|
|
||||||
|
BUILT_SOURCES += sys/select.h
|
||||||
|
|
||||||
|
# We need the following in order to create <sys/select.h> when the system
|
||||||
|
# doesn't have one that works with the given compiler.
|
||||||
|
sys/select.h: sys_select.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H)
|
||||||
|
$(AM_V_at)$(MKDIR_P) sys
|
||||||
|
$(AM_V_GEN)rm -f $@-t $@ && \
|
||||||
|
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
|
||||||
|
sed -e 's|@''GUARD_PREFIX''@|GL|g' \
|
||||||
|
-e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
|
||||||
|
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
|
||||||
|
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
|
||||||
|
-e 's|@''NEXT_SYS_SELECT_H''@|$(NEXT_SYS_SELECT_H)|g' \
|
||||||
|
-e 's|@''HAVE_SYS_SELECT_H''@|$(HAVE_SYS_SELECT_H)|g' \
|
||||||
|
-e 's/@''GNULIB_PSELECT''@/$(GNULIB_PSELECT)/g' \
|
||||||
|
-e 's/@''GNULIB_SELECT''@/$(GNULIB_SELECT)/g' \
|
||||||
|
-e 's|@''HAVE_WINSOCK2_H''@|$(HAVE_WINSOCK2_H)|g' \
|
||||||
|
-e 's|@''HAVE_PSELECT''@|$(HAVE_PSELECT)|g' \
|
||||||
|
-e 's|@''REPLACE_PSELECT''@|$(REPLACE_PSELECT)|g' \
|
||||||
|
-e 's|@''REPLACE_SELECT''@|$(REPLACE_SELECT)|g' \
|
||||||
|
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
|
||||||
|
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
|
||||||
|
< $(srcdir)/sys_select.in.h; \
|
||||||
|
} > $@-t && \
|
||||||
|
mv $@-t $@
|
||||||
|
MOSTLYCLEANFILES += sys/select.h sys/select.h-t
|
||||||
|
MOSTLYCLEANDIRS += sys
|
||||||
|
|
||||||
|
EXTRA_DIST += sys_select.in.h
|
||||||
|
|
||||||
|
## end gnulib module sys_select
|
||||||
|
|
||||||
## begin gnulib module sys_socket
|
## begin gnulib module sys_socket
|
||||||
|
|
||||||
BUILT_SOURCES += sys/socket.h
|
BUILT_SOURCES += sys/socket.h
|
||||||
|
|
478
lib/alloca.c
Normal file
478
lib/alloca.c
Normal file
|
@ -0,0 +1,478 @@
|
||||||
|
/* alloca.c -- allocate automatically reclaimed memory
|
||||||
|
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||||
|
|
||||||
|
This implementation of the PWB library alloca function,
|
||||||
|
which is used to allocate space off the run-time stack so
|
||||||
|
that it is automatically reclaimed upon procedure exit,
|
||||||
|
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||||
|
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||||
|
|
||||||
|
There are some preprocessor constants that can
|
||||||
|
be defined when compiling for your specific system, for
|
||||||
|
improved efficiency; however, the defaults should be okay.
|
||||||
|
|
||||||
|
The general concept of this implementation is to keep
|
||||||
|
track of all alloca-allocated blocks, and reclaim any
|
||||||
|
that are found to be deeper in the stack than the current
|
||||||
|
invocation. This heuristic does not reclaim storage as
|
||||||
|
soon as it becomes invalid, but it will do so eventually.
|
||||||
|
|
||||||
|
As a special case, alloca(0) reclaims storage without
|
||||||
|
allocating any. It is a good idea to use alloca(0) in
|
||||||
|
your main control loop, etc. to force garbage collection. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef emacs
|
||||||
|
# include "lisp.h"
|
||||||
|
# include "blockinput.h"
|
||||||
|
# ifdef EMACS_FREE
|
||||||
|
# undef free
|
||||||
|
# define free EMACS_FREE
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define memory_full() abort ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If compiling with GCC 2, this file's not needed. */
|
||||||
|
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||||
|
|
||||||
|
/* If someone has defined alloca as a macro,
|
||||||
|
there must be some other way alloca is supposed to work. */
|
||||||
|
# ifndef alloca
|
||||||
|
|
||||||
|
# ifdef emacs
|
||||||
|
# ifdef static
|
||||||
|
/* actually, only want this if static is defined as ""
|
||||||
|
-- this is for usg, in which emacs must undefine static
|
||||||
|
in order to make unexec workable
|
||||||
|
*/
|
||||||
|
# ifndef STACK_DIRECTION
|
||||||
|
you
|
||||||
|
lose
|
||||||
|
-- must know STACK_DIRECTION at compile-time
|
||||||
|
/* Using #error here is not wise since this file should work for
|
||||||
|
old and obscure compilers. */
|
||||||
|
# endif /* STACK_DIRECTION undefined */
|
||||||
|
# endif /* static */
|
||||||
|
# endif /* emacs */
|
||||||
|
|
||||||
|
/* If your stack is a linked list of frames, you have to
|
||||||
|
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||||
|
|
||||||
|
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||||
|
long i00afunc ();
|
||||||
|
# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||||
|
# else
|
||||||
|
# define ADDRESS_FUNCTION(arg) &(arg)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Define STACK_DIRECTION if you know the direction of stack
|
||||||
|
growth for your system; otherwise it will be automatically
|
||||||
|
deduced at run-time.
|
||||||
|
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
|
||||||
|
# ifndef STACK_DIRECTION
|
||||||
|
# define STACK_DIRECTION 0 /* Direction unknown. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if STACK_DIRECTION != 0
|
||||||
|
|
||||||
|
# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||||
|
|
||||||
|
# else /* STACK_DIRECTION == 0; need run-time code. */
|
||||||
|
|
||||||
|
static int stack_dir; /* 1 or -1 once known. */
|
||||||
|
# define STACK_DIR stack_dir
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_stack_direction (int *addr, int depth)
|
||||||
|
{
|
||||||
|
int dir, dummy = 0;
|
||||||
|
if (! addr)
|
||||||
|
addr = &dummy;
|
||||||
|
*addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
|
||||||
|
dir = depth ? find_stack_direction (addr, depth - 1) : 0;
|
||||||
|
return dir + dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif /* STACK_DIRECTION == 0 */
|
||||||
|
|
||||||
|
/* An "alloca header" is used to:
|
||||||
|
(a) chain together all alloca'ed blocks;
|
||||||
|
(b) keep track of stack depth.
|
||||||
|
|
||||||
|
It is very important that sizeof(header) agree with malloc
|
||||||
|
alignment chunk size. The following default should work okay. */
|
||||||
|
|
||||||
|
# ifndef ALIGN_SIZE
|
||||||
|
# define ALIGN_SIZE sizeof(double)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
typedef union hdr
|
||||||
|
{
|
||||||
|
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
union hdr *next; /* For chaining headers. */
|
||||||
|
char *deep; /* For stack depth measure. */
|
||||||
|
} h;
|
||||||
|
} header;
|
||||||
|
|
||||||
|
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||||
|
|
||||||
|
/* Return a pointer to at least SIZE bytes of storage,
|
||||||
|
which will be automatically reclaimed upon exit from
|
||||||
|
the procedure that called alloca. Originally, this space
|
||||||
|
was supposed to be taken from the current stack frame of the
|
||||||
|
caller, but that method cannot be made to work for some
|
||||||
|
implementations of C, for example under Gould's UTX/32. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
alloca (size_t size)
|
||||||
|
{
|
||||||
|
auto char probe; /* Probes stack depth: */
|
||||||
|
register char *depth = ADDRESS_FUNCTION (probe);
|
||||||
|
|
||||||
|
# if STACK_DIRECTION == 0
|
||||||
|
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||||
|
STACK_DIR = find_stack_direction (NULL, (size & 1) + 20);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Reclaim garbage, defined as all alloca'd storage that
|
||||||
|
was allocated from deeper in the stack than currently. */
|
||||||
|
|
||||||
|
{
|
||||||
|
register header *hp; /* Traverses linked list. */
|
||||||
|
|
||||||
|
# ifdef emacs
|
||||||
|
BLOCK_INPUT;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
for (hp = last_alloca_header; hp != NULL;)
|
||||||
|
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||||
|
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||||
|
{
|
||||||
|
register header *np = hp->h.next;
|
||||||
|
|
||||||
|
free (hp); /* Collect garbage. */
|
||||||
|
|
||||||
|
hp = np; /* -> next header. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break; /* Rest are not deeper. */
|
||||||
|
|
||||||
|
last_alloca_header = hp; /* -> last valid storage. */
|
||||||
|
|
||||||
|
# ifdef emacs
|
||||||
|
UNBLOCK_INPUT;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return NULL; /* No allocation required. */
|
||||||
|
|
||||||
|
/* Allocate combined header + user data storage. */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Address of header. */
|
||||||
|
register header *new;
|
||||||
|
|
||||||
|
size_t combined_size = sizeof (header) + size;
|
||||||
|
if (combined_size < sizeof (header))
|
||||||
|
memory_full ();
|
||||||
|
|
||||||
|
new = malloc (combined_size);
|
||||||
|
|
||||||
|
if (! new)
|
||||||
|
memory_full ();
|
||||||
|
|
||||||
|
new->h.next = last_alloca_header;
|
||||||
|
new->h.deep = depth;
|
||||||
|
|
||||||
|
last_alloca_header = new;
|
||||||
|
|
||||||
|
/* User storage begins just after header. */
|
||||||
|
|
||||||
|
return (void *) (new + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||||
|
|
||||||
|
# ifdef DEBUG_I00AFUNC
|
||||||
|
# include <stdio.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef CRAY_STACK
|
||||||
|
# define CRAY_STACK
|
||||||
|
# ifndef CRAY2
|
||||||
|
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||||
|
struct stack_control_header
|
||||||
|
{
|
||||||
|
long shgrow:32; /* Number of times stack has grown. */
|
||||||
|
long shaseg:32; /* Size of increments to stack. */
|
||||||
|
long shhwm:32; /* High water mark of stack. */
|
||||||
|
long shsize:32; /* Current size of stack (all segments). */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The stack segment linkage control information occurs at
|
||||||
|
the high-address end of a stack segment. (The stack
|
||||||
|
grows from low addresses to high addresses.) The initial
|
||||||
|
part of the stack segment linkage control information is
|
||||||
|
0200 (octal) words. This provides for register storage
|
||||||
|
for the routine which overflows the stack. */
|
||||||
|
|
||||||
|
struct stack_segment_linkage
|
||||||
|
{
|
||||||
|
long ss[0200]; /* 0200 overflow words. */
|
||||||
|
long sssize:32; /* Number of words in this segment. */
|
||||||
|
long ssbase:32; /* Offset to stack base. */
|
||||||
|
long:32;
|
||||||
|
long sspseg:32; /* Offset to linkage control of previous
|
||||||
|
segment of stack. */
|
||||||
|
long:32;
|
||||||
|
long sstcpt:32; /* Pointer to task common address block. */
|
||||||
|
long sscsnm; /* Private control structure number for
|
||||||
|
microtasking. */
|
||||||
|
long ssusr1; /* Reserved for user. */
|
||||||
|
long ssusr2; /* Reserved for user. */
|
||||||
|
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||||
|
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||||
|
long sscray[7]; /* Reserved for Cray Research. */
|
||||||
|
long ssa0;
|
||||||
|
long ssa1;
|
||||||
|
long ssa2;
|
||||||
|
long ssa3;
|
||||||
|
long ssa4;
|
||||||
|
long ssa5;
|
||||||
|
long ssa6;
|
||||||
|
long ssa7;
|
||||||
|
long sss0;
|
||||||
|
long sss1;
|
||||||
|
long sss2;
|
||||||
|
long sss3;
|
||||||
|
long sss4;
|
||||||
|
long sss5;
|
||||||
|
long sss6;
|
||||||
|
long sss7;
|
||||||
|
};
|
||||||
|
|
||||||
|
# else /* CRAY2 */
|
||||||
|
/* The following structure defines the vector of words
|
||||||
|
returned by the STKSTAT library routine. */
|
||||||
|
struct stk_stat
|
||||||
|
{
|
||||||
|
long now; /* Current total stack size. */
|
||||||
|
long maxc; /* Amount of contiguous space which would
|
||||||
|
be required to satisfy the maximum
|
||||||
|
stack demand to date. */
|
||||||
|
long high_water; /* Stack high-water mark. */
|
||||||
|
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||||
|
long hits; /* Number of internal buffer hits. */
|
||||||
|
long extends; /* Number of block extensions. */
|
||||||
|
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||||
|
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||||
|
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||||
|
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||||
|
long segments; /* Current number of stack segments. */
|
||||||
|
long maxs; /* Maximum number of stack segments so far. */
|
||||||
|
long pad_size; /* Stack pad size. */
|
||||||
|
long current_address; /* Current stack segment address. */
|
||||||
|
long current_size; /* Current stack segment size. This
|
||||||
|
number is actually corrupted by STKSTAT to
|
||||||
|
include the fifteen word trailer area. */
|
||||||
|
long initial_address; /* Address of initial segment. */
|
||||||
|
long initial_size; /* Size of initial segment. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The following structure describes the data structure which trails
|
||||||
|
any stack segment. I think that the description in 'asdef' is
|
||||||
|
out of date. I only describe the parts that I am sure about. */
|
||||||
|
|
||||||
|
struct stk_trailer
|
||||||
|
{
|
||||||
|
long this_address; /* Address of this block. */
|
||||||
|
long this_size; /* Size of this block (does not include
|
||||||
|
this trailer). */
|
||||||
|
long unknown2;
|
||||||
|
long unknown3;
|
||||||
|
long link; /* Address of trailer block of previous
|
||||||
|
segment. */
|
||||||
|
long unknown5;
|
||||||
|
long unknown6;
|
||||||
|
long unknown7;
|
||||||
|
long unknown8;
|
||||||
|
long unknown9;
|
||||||
|
long unknown10;
|
||||||
|
long unknown11;
|
||||||
|
long unknown12;
|
||||||
|
long unknown13;
|
||||||
|
long unknown14;
|
||||||
|
};
|
||||||
|
|
||||||
|
# endif /* CRAY2 */
|
||||||
|
# endif /* not CRAY_STACK */
|
||||||
|
|
||||||
|
# ifdef CRAY2
|
||||||
|
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||||
|
I doubt that "lint" will like this much. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
i00afunc (long *address)
|
||||||
|
{
|
||||||
|
struct stk_stat status;
|
||||||
|
struct stk_trailer *trailer;
|
||||||
|
long *block, size;
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
/* We want to iterate through all of the segments. The first
|
||||||
|
step is to get the stack status structure. We could do this
|
||||||
|
more quickly and more directly, perhaps, by referencing the
|
||||||
|
$LM00 common block, but I know that this works. */
|
||||||
|
|
||||||
|
STKSTAT (&status);
|
||||||
|
|
||||||
|
/* Set up the iteration. */
|
||||||
|
|
||||||
|
trailer = (struct stk_trailer *) (status.current_address
|
||||||
|
+ status.current_size
|
||||||
|
- 15);
|
||||||
|
|
||||||
|
/* There must be at least one stack segment. Therefore it is
|
||||||
|
a fatal error if "trailer" is null. */
|
||||||
|
|
||||||
|
if (trailer == 0)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
/* Discard segments that do not contain our argument address. */
|
||||||
|
|
||||||
|
while (trailer != 0)
|
||||||
|
{
|
||||||
|
block = (long *) trailer->this_address;
|
||||||
|
size = trailer->this_size;
|
||||||
|
if (block == 0 || size == 0)
|
||||||
|
abort ();
|
||||||
|
trailer = (struct stk_trailer *) trailer->link;
|
||||||
|
if ((block <= address) && (address < (block + size)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the result to the offset in this segment and add the sizes
|
||||||
|
of all predecessor segments. */
|
||||||
|
|
||||||
|
result = address - block;
|
||||||
|
|
||||||
|
if (trailer == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (trailer->this_size <= 0)
|
||||||
|
abort ();
|
||||||
|
result += trailer->this_size;
|
||||||
|
trailer = (struct stk_trailer *) trailer->link;
|
||||||
|
}
|
||||||
|
while (trailer != 0);
|
||||||
|
|
||||||
|
/* We are done. Note that if you present a bogus address (one
|
||||||
|
not in any segment), you will get a different number back, formed
|
||||||
|
from subtracting the address of the first block. This is probably
|
||||||
|
not what you want. */
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
# else /* not CRAY2 */
|
||||||
|
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||||
|
Determine the number of the cell within the stack,
|
||||||
|
given the address of the cell. The purpose of this
|
||||||
|
routine is to linearize, in some sense, stack addresses
|
||||||
|
for alloca. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
i00afunc (long address)
|
||||||
|
{
|
||||||
|
long stkl = 0;
|
||||||
|
|
||||||
|
long size, pseg, this_segment, stack;
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
struct stack_segment_linkage *ssptr;
|
||||||
|
|
||||||
|
/* Register B67 contains the address of the end of the
|
||||||
|
current stack segment. If you (as a subprogram) store
|
||||||
|
your registers on the stack and find that you are past
|
||||||
|
the contents of B67, you have overflowed the segment.
|
||||||
|
|
||||||
|
B67 also points to the stack segment linkage control
|
||||||
|
area, which is what we are really interested in. */
|
||||||
|
|
||||||
|
stkl = CRAY_STACKSEG_END ();
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
|
||||||
|
/* If one subtracts 'size' from the end of the segment,
|
||||||
|
one has the address of the first word of the segment.
|
||||||
|
|
||||||
|
If this is not the first segment, 'pseg' will be
|
||||||
|
nonzero. */
|
||||||
|
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
|
||||||
|
this_segment = stkl - size;
|
||||||
|
|
||||||
|
/* It is possible that calling this routine itself caused
|
||||||
|
a stack overflow. Discard stack segments which do not
|
||||||
|
contain the target address. */
|
||||||
|
|
||||||
|
while (!(this_segment <= address && address <= stkl))
|
||||||
|
{
|
||||||
|
# ifdef DEBUG_I00AFUNC
|
||||||
|
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||||
|
# endif
|
||||||
|
if (pseg == 0)
|
||||||
|
break;
|
||||||
|
stkl = stkl - pseg;
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
this_segment = stkl - size;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = address - this_segment;
|
||||||
|
|
||||||
|
/* If you subtract pseg from the current end of the stack,
|
||||||
|
you get the address of the previous stack segment's end.
|
||||||
|
This seems a little convoluted to me, but I'll bet you save
|
||||||
|
a cycle somewhere. */
|
||||||
|
|
||||||
|
while (pseg != 0)
|
||||||
|
{
|
||||||
|
# ifdef DEBUG_I00AFUNC
|
||||||
|
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||||
|
# endif
|
||||||
|
stkl = stkl - pseg;
|
||||||
|
ssptr = (struct stack_segment_linkage *) stkl;
|
||||||
|
size = ssptr->sssize;
|
||||||
|
pseg = ssptr->sspseg;
|
||||||
|
result += size;
|
||||||
|
}
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
# endif /* not CRAY2 */
|
||||||
|
# endif /* CRAY */
|
||||||
|
|
||||||
|
# endif /* no alloca */
|
||||||
|
#endif /* not GCC 2 */
|
160
lib/dup2.c
Normal file
160
lib/dup2.c
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/* Duplicate an open file descriptor to a specified file descriptor.
|
||||||
|
|
||||||
|
Copyright (C) 1999, 2004-2007, 2009-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* written by Paul Eggert */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* Specification. */
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#if HAVE_DUP2
|
||||||
|
|
||||||
|
# undef dup2
|
||||||
|
|
||||||
|
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||||
|
|
||||||
|
/* Get declarations of the native Windows API functions. */
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# include <windows.h>
|
||||||
|
|
||||||
|
# include "msvc-inval.h"
|
||||||
|
|
||||||
|
/* Get _get_osfhandle. */
|
||||||
|
# include "msvc-nothrow.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
ms_windows_dup2 (int fd, int desired_fd)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* If fd is closed, mingw hangs on dup2 (fd, fd). If fd is open,
|
||||||
|
dup2 (fd, fd) returns 0, but all further attempts to use fd in
|
||||||
|
future dup2 calls will hang. */
|
||||||
|
if (fd == desired_fd)
|
||||||
|
{
|
||||||
|
if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wine 1.0.1 return 0 when desired_fd is negative but not -1:
|
||||||
|
http://bugs.winehq.org/show_bug.cgi?id=21289 */
|
||||||
|
if (desired_fd < 0)
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRY_MSVC_INVAL
|
||||||
|
{
|
||||||
|
result = dup2 (fd, desired_fd);
|
||||||
|
}
|
||||||
|
CATCH_MSVC_INVAL
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
DONE_MSVC_INVAL;
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
result = desired_fd;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
# define dup2 ms_windows_dup2
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
int
|
||||||
|
rpl_dup2 (int fd, int desired_fd)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
# ifdef F_GETFL
|
||||||
|
/* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF.
|
||||||
|
On Cygwin 1.5.x, dup2 (1, 1) returns 0.
|
||||||
|
On Cygwin 1.7.17, dup2 (1, -1) dumps core.
|
||||||
|
On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */
|
||||||
|
if (desired_fd < 0)
|
||||||
|
fd = desired_fd;
|
||||||
|
if (fd == desired_fd)
|
||||||
|
return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
result = dup2 (fd, desired_fd);
|
||||||
|
|
||||||
|
/* Correct an errno value on FreeBSD 6.1 and Cygwin 1.5.x. */
|
||||||
|
if (result == -1 && errno == EMFILE)
|
||||||
|
errno = EBADF;
|
||||||
|
# if REPLACE_FCHDIR
|
||||||
|
if (fd != desired_fd && result != -1)
|
||||||
|
result = _gl_register_dup (fd, result);
|
||||||
|
# endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !HAVE_DUP2 */
|
||||||
|
|
||||||
|
/* On older platforms, dup2 did not exist. */
|
||||||
|
|
||||||
|
# ifndef F_DUPFD
|
||||||
|
static int
|
||||||
|
dupfd (int fd, int desired_fd)
|
||||||
|
{
|
||||||
|
int duplicated_fd = dup (fd);
|
||||||
|
if (duplicated_fd < 0 || duplicated_fd == desired_fd)
|
||||||
|
return duplicated_fd;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int r = dupfd (fd, desired_fd);
|
||||||
|
int e = errno;
|
||||||
|
close (duplicated_fd);
|
||||||
|
errno = e;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
int
|
||||||
|
dup2 (int fd, int desired_fd)
|
||||||
|
{
|
||||||
|
int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
|
||||||
|
if (result == -1 || fd == desired_fd)
|
||||||
|
return result;
|
||||||
|
close (desired_fd);
|
||||||
|
# ifdef F_DUPFD
|
||||||
|
result = fcntl (fd, F_DUPFD, desired_fd);
|
||||||
|
# if REPLACE_FCHDIR
|
||||||
|
if (0 <= result)
|
||||||
|
result = _gl_register_dup (fd, result);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
result = dupfd (fd, desired_fd);
|
||||||
|
# endif
|
||||||
|
if (result == -1 && (errno == EMFILE || errno == EINVAL))
|
||||||
|
errno = EBADF;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_DUP2 */
|
547
lib/select.c
Normal file
547
lib/select.c
Normal file
|
@ -0,0 +1,547 @@
|
||||||
|
/* Emulation for select(2)
|
||||||
|
Contributed by Paolo Bonzini.
|
||||||
|
|
||||||
|
Copyright 2008-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of gnulib.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||||
|
/* Native Windows. */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
/* Get the overridden 'struct timeval'. */
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "msvc-nothrow.h"
|
||||||
|
|
||||||
|
#undef select
|
||||||
|
|
||||||
|
struct bitset {
|
||||||
|
unsigned char in[FD_SETSIZE / CHAR_BIT];
|
||||||
|
unsigned char out[FD_SETSIZE / CHAR_BIT];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Declare data structures for ntdll functions. */
|
||||||
|
typedef struct _FILE_PIPE_LOCAL_INFORMATION {
|
||||||
|
ULONG NamedPipeType;
|
||||||
|
ULONG NamedPipeConfiguration;
|
||||||
|
ULONG MaximumInstances;
|
||||||
|
ULONG CurrentInstances;
|
||||||
|
ULONG InboundQuota;
|
||||||
|
ULONG ReadDataAvailable;
|
||||||
|
ULONG OutboundQuota;
|
||||||
|
ULONG WriteQuotaAvailable;
|
||||||
|
ULONG NamedPipeState;
|
||||||
|
ULONG NamedPipeEnd;
|
||||||
|
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _IO_STATUS_BLOCK
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
DWORD Status;
|
||||||
|
PVOID Pointer;
|
||||||
|
} u;
|
||||||
|
ULONG_PTR Information;
|
||||||
|
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||||
|
|
||||||
|
typedef enum _FILE_INFORMATION_CLASS {
|
||||||
|
FilePipeLocalInformation = 24
|
||||||
|
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
||||||
|
|
||||||
|
typedef DWORD (WINAPI *PNtQueryInformationFile)
|
||||||
|
(HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
|
||||||
|
|
||||||
|
#ifndef PIPE_BUF
|
||||||
|
#define PIPE_BUF 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Optimized test whether a HANDLE refers to a console.
|
||||||
|
See <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00065.html>. */
|
||||||
|
#define IsConsoleHandle(h) (((intptr_t) (h) & 3) == 3)
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
IsSocketHandle (HANDLE h)
|
||||||
|
{
|
||||||
|
WSANETWORKEVENTS ev;
|
||||||
|
|
||||||
|
if (IsConsoleHandle (h))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Under Wine, it seems that getsockopt returns 0 for pipes too.
|
||||||
|
WSAEnumNetworkEvents instead distinguishes the two correctly. */
|
||||||
|
ev.lNetworkEvents = 0xDEADBEEF;
|
||||||
|
WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
|
||||||
|
return ev.lNetworkEvents != 0xDEADBEEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute output fd_sets for libc descriptor FD (whose Windows handle is
|
||||||
|
H). */
|
||||||
|
|
||||||
|
static int
|
||||||
|
windows_poll_handle (HANDLE h, int fd,
|
||||||
|
struct bitset *rbits,
|
||||||
|
struct bitset *wbits,
|
||||||
|
struct bitset *xbits)
|
||||||
|
{
|
||||||
|
BOOL read, write, except;
|
||||||
|
int i, ret;
|
||||||
|
INPUT_RECORD *irbuffer;
|
||||||
|
DWORD avail, nbuffer;
|
||||||
|
BOOL bRet;
|
||||||
|
IO_STATUS_BLOCK iosb;
|
||||||
|
FILE_PIPE_LOCAL_INFORMATION fpli;
|
||||||
|
static PNtQueryInformationFile NtQueryInformationFile;
|
||||||
|
static BOOL once_only;
|
||||||
|
|
||||||
|
read = write = except = FALSE;
|
||||||
|
switch (GetFileType (h))
|
||||||
|
{
|
||||||
|
case FILE_TYPE_DISK:
|
||||||
|
read = TRUE;
|
||||||
|
write = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FILE_TYPE_PIPE:
|
||||||
|
if (!once_only)
|
||||||
|
{
|
||||||
|
NtQueryInformationFile = (PNtQueryInformationFile)
|
||||||
|
GetProcAddress (GetModuleHandle ("ntdll.dll"),
|
||||||
|
"NtQueryInformationFile");
|
||||||
|
once_only = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
|
||||||
|
{
|
||||||
|
if (avail)
|
||||||
|
read = TRUE;
|
||||||
|
}
|
||||||
|
else if (GetLastError () == ERROR_BROKEN_PIPE)
|
||||||
|
;
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It was the write-end of the pipe. Check if it is writable.
|
||||||
|
If NtQueryInformationFile fails, optimistically assume the pipe is
|
||||||
|
writable. This could happen on Windows 9x, where
|
||||||
|
NtQueryInformationFile is not available, or if we inherit a pipe
|
||||||
|
that doesn't permit FILE_READ_ATTRIBUTES access on the write end
|
||||||
|
(I think this should not happen since Windows XP SP2; WINE seems
|
||||||
|
fine too). Otherwise, ensure that enough space is available for
|
||||||
|
atomic writes. */
|
||||||
|
memset (&iosb, 0, sizeof (iosb));
|
||||||
|
memset (&fpli, 0, sizeof (fpli));
|
||||||
|
|
||||||
|
if (!NtQueryInformationFile
|
||||||
|
|| NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
|
||||||
|
FilePipeLocalInformation)
|
||||||
|
|| fpli.WriteQuotaAvailable >= PIPE_BUF
|
||||||
|
|| (fpli.OutboundQuota < PIPE_BUF &&
|
||||||
|
fpli.WriteQuotaAvailable == fpli.OutboundQuota))
|
||||||
|
write = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FILE_TYPE_CHAR:
|
||||||
|
write = TRUE;
|
||||||
|
if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = WaitForSingleObject (h, 0);
|
||||||
|
if (ret == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
if (!IsConsoleHandle (h))
|
||||||
|
{
|
||||||
|
read = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nbuffer = avail = 0;
|
||||||
|
bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
|
||||||
|
|
||||||
|
/* Screen buffers handles are filtered earlier. */
|
||||||
|
assert (bRet);
|
||||||
|
if (nbuffer == 0)
|
||||||
|
{
|
||||||
|
except = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
|
||||||
|
bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
|
||||||
|
if (!bRet || avail == 0)
|
||||||
|
{
|
||||||
|
except = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < avail; i++)
|
||||||
|
if (irbuffer[i].EventType == KEY_EVENT)
|
||||||
|
read = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = WaitForSingleObject (h, 0);
|
||||||
|
write = TRUE;
|
||||||
|
if (ret == WAIT_OBJECT_0)
|
||||||
|
read = TRUE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
if (read && (rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
|
||||||
|
{
|
||||||
|
rbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write && (wbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
|
||||||
|
{
|
||||||
|
wbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (except && (xbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
|
||||||
|
{
|
||||||
|
xbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
|
||||||
|
struct timeval *timeout)
|
||||||
|
#undef timeval
|
||||||
|
{
|
||||||
|
static struct timeval tv0;
|
||||||
|
static HANDLE hEvent;
|
||||||
|
HANDLE h, handle_array[FD_SETSIZE + 2];
|
||||||
|
fd_set handle_rfds, handle_wfds, handle_xfds;
|
||||||
|
struct bitset rbits, wbits, xbits;
|
||||||
|
unsigned char anyfds_in[FD_SETSIZE / CHAR_BIT];
|
||||||
|
DWORD ret, wait_timeout, nhandles, nsock, nbuffer;
|
||||||
|
MSG msg;
|
||||||
|
int i, fd, rc;
|
||||||
|
|
||||||
|
if (nfds > FD_SETSIZE)
|
||||||
|
nfds = FD_SETSIZE;
|
||||||
|
|
||||||
|
if (!timeout)
|
||||||
|
wait_timeout = INFINITE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wait_timeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
||||||
|
|
||||||
|
/* select is also used as a portable usleep. */
|
||||||
|
if (!rfds && !wfds && !xfds)
|
||||||
|
{
|
||||||
|
Sleep (wait_timeout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hEvent)
|
||||||
|
hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
handle_array[0] = hEvent;
|
||||||
|
nhandles = 1;
|
||||||
|
nsock = 0;
|
||||||
|
|
||||||
|
/* Copy descriptors to bitsets. At the same time, eliminate
|
||||||
|
bits in the "wrong" direction for console input buffers
|
||||||
|
and screen buffers, because screen buffers are waitable
|
||||||
|
and they will block until a character is available. */
|
||||||
|
memset (&rbits, 0, sizeof (rbits));
|
||||||
|
memset (&wbits, 0, sizeof (wbits));
|
||||||
|
memset (&xbits, 0, sizeof (xbits));
|
||||||
|
memset (anyfds_in, 0, sizeof (anyfds_in));
|
||||||
|
if (rfds)
|
||||||
|
for (i = 0; i < rfds->fd_count; i++)
|
||||||
|
{
|
||||||
|
fd = rfds->fd_array[i];
|
||||||
|
h = (HANDLE) _get_osfhandle (fd);
|
||||||
|
if (IsConsoleHandle (h)
|
||||||
|
&& !GetNumberOfConsoleInputEvents (h, &nbuffer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
|
||||||
|
anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rfds = (fd_set *) alloca (sizeof (fd_set));
|
||||||
|
|
||||||
|
if (wfds)
|
||||||
|
for (i = 0; i < wfds->fd_count; i++)
|
||||||
|
{
|
||||||
|
fd = wfds->fd_array[i];
|
||||||
|
h = (HANDLE) _get_osfhandle (fd);
|
||||||
|
if (IsConsoleHandle (h)
|
||||||
|
&& GetNumberOfConsoleInputEvents (h, &nbuffer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
|
||||||
|
anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wfds = (fd_set *) alloca (sizeof (fd_set));
|
||||||
|
|
||||||
|
if (xfds)
|
||||||
|
for (i = 0; i < xfds->fd_count; i++)
|
||||||
|
{
|
||||||
|
fd = xfds->fd_array[i];
|
||||||
|
xbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
|
||||||
|
anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
xfds = (fd_set *) alloca (sizeof (fd_set));
|
||||||
|
|
||||||
|
/* Zero all the fd_sets, including the application's. */
|
||||||
|
FD_ZERO (rfds);
|
||||||
|
FD_ZERO (wfds);
|
||||||
|
FD_ZERO (xfds);
|
||||||
|
FD_ZERO (&handle_rfds);
|
||||||
|
FD_ZERO (&handle_wfds);
|
||||||
|
FD_ZERO (&handle_xfds);
|
||||||
|
|
||||||
|
/* Classify handles. Create fd sets for sockets, poll the others. */
|
||||||
|
for (i = 0; i < nfds; i++)
|
||||||
|
{
|
||||||
|
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
h = (HANDLE) _get_osfhandle (i);
|
||||||
|
if (!h)
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsSocketHandle (h))
|
||||||
|
{
|
||||||
|
int requested = FD_CLOSE;
|
||||||
|
|
||||||
|
/* See above; socket handles are mapped onto select, but we
|
||||||
|
need to map descriptors to handles. */
|
||||||
|
if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
{
|
||||||
|
requested |= FD_READ | FD_ACCEPT;
|
||||||
|
FD_SET ((SOCKET) h, rfds);
|
||||||
|
FD_SET ((SOCKET) h, &handle_rfds);
|
||||||
|
}
|
||||||
|
if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
{
|
||||||
|
requested |= FD_WRITE | FD_CONNECT;
|
||||||
|
FD_SET ((SOCKET) h, wfds);
|
||||||
|
FD_SET ((SOCKET) h, &handle_wfds);
|
||||||
|
}
|
||||||
|
if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
{
|
||||||
|
requested |= FD_OOB;
|
||||||
|
FD_SET ((SOCKET) h, xfds);
|
||||||
|
FD_SET ((SOCKET) h, &handle_xfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
WSAEventSelect ((SOCKET) h, hEvent, requested);
|
||||||
|
nsock++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle_array[nhandles++] = h;
|
||||||
|
|
||||||
|
/* Poll now. If we get an event, do not wait below. */
|
||||||
|
if (wait_timeout != 0
|
||||||
|
&& windows_poll_handle (h, i, &rbits, &wbits, &xbits))
|
||||||
|
wait_timeout = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place a sentinel at the end of the array. */
|
||||||
|
handle_array[nhandles] = NULL;
|
||||||
|
|
||||||
|
restart:
|
||||||
|
if (wait_timeout == 0 || nsock == 0)
|
||||||
|
rc = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* See if we need to wait in the loop below. If any select is ready,
|
||||||
|
do MsgWaitForMultipleObjects anyway to dispatch messages, but
|
||||||
|
no need to call select again. */
|
||||||
|
rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
|
||||||
|
if (rc == 0)
|
||||||
|
{
|
||||||
|
/* Restore the fd_sets for the other select we do below. */
|
||||||
|
memcpy (&handle_rfds, rfds, sizeof (fd_set));
|
||||||
|
memcpy (&handle_wfds, wfds, sizeof (fd_set));
|
||||||
|
memcpy (&handle_xfds, xfds, sizeof (fd_set));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wait_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
|
||||||
|
wait_timeout, QS_ALLINPUT);
|
||||||
|
|
||||||
|
if (ret == WAIT_OBJECT_0 + nhandles)
|
||||||
|
{
|
||||||
|
/* new input of some other kind */
|
||||||
|
BOOL bRet;
|
||||||
|
while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
|
||||||
|
{
|
||||||
|
TranslateMessage (&msg);
|
||||||
|
DispatchMessage (&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we haven't done it yet, check the status of the sockets. */
|
||||||
|
if (rc == 0 && nsock > 0)
|
||||||
|
rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
|
||||||
|
|
||||||
|
if (nhandles > 1)
|
||||||
|
{
|
||||||
|
/* Count results that are not counted in the return value of select. */
|
||||||
|
nhandles = 1;
|
||||||
|
for (i = 0; i < nfds; i++)
|
||||||
|
{
|
||||||
|
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
h = (HANDLE) _get_osfhandle (i);
|
||||||
|
if (h == handle_array[nhandles])
|
||||||
|
{
|
||||||
|
/* Not a socket. */
|
||||||
|
nhandles++;
|
||||||
|
windows_poll_handle (h, i, &rbits, &wbits, &xbits);
|
||||||
|
if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))
|
||||||
|
|| wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))
|
||||||
|
|| xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
rc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == 0 && wait_timeout == INFINITE)
|
||||||
|
{
|
||||||
|
/* Sleep 1 millisecond to avoid busy wait and retry with the
|
||||||
|
original fd_sets. */
|
||||||
|
memcpy (&handle_rfds, rfds, sizeof (fd_set));
|
||||||
|
memcpy (&handle_wfds, wfds, sizeof (fd_set));
|
||||||
|
memcpy (&handle_xfds, xfds, sizeof (fd_set));
|
||||||
|
SleepEx (1, TRUE);
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now fill in the results. */
|
||||||
|
FD_ZERO (rfds);
|
||||||
|
FD_ZERO (wfds);
|
||||||
|
FD_ZERO (xfds);
|
||||||
|
nhandles = 1;
|
||||||
|
for (i = 0; i < nfds; i++)
|
||||||
|
{
|
||||||
|
if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
h = (HANDLE) _get_osfhandle (i);
|
||||||
|
if (h != handle_array[nhandles])
|
||||||
|
{
|
||||||
|
/* Perform handle->descriptor mapping. */
|
||||||
|
WSAEventSelect ((SOCKET) h, NULL, 0);
|
||||||
|
if (FD_ISSET (h, &handle_rfds))
|
||||||
|
FD_SET (i, rfds);
|
||||||
|
if (FD_ISSET (h, &handle_wfds))
|
||||||
|
FD_SET (i, wfds);
|
||||||
|
if (FD_ISSET (h, &handle_xfds))
|
||||||
|
FD_SET (i, xfds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Not a socket. */
|
||||||
|
nhandles++;
|
||||||
|
if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
FD_SET (i, rfds);
|
||||||
|
if (wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
FD_SET (i, wfds);
|
||||||
|
if (xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
|
||||||
|
FD_SET (i, xfds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ! Native Windows. */
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <stddef.h> /* NULL */
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#undef select
|
||||||
|
|
||||||
|
int
|
||||||
|
rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
|
||||||
|
struct timeval *timeout)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* FreeBSD 8.2 has a bug: it does not always detect invalid fds. */
|
||||||
|
if (nfds < 0 || nfds > FD_SETSIZE)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < nfds; i++)
|
||||||
|
{
|
||||||
|
if (((rfds && FD_ISSET (i, rfds))
|
||||||
|
|| (wfds && FD_ISSET (i, wfds))
|
||||||
|
|| (xfds && FD_ISSET (i, xfds)))
|
||||||
|
&& dup2 (i, i) != i)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interix 3.5 has a bug: it does not support nfds == 0. */
|
||||||
|
if (nfds == 0)
|
||||||
|
{
|
||||||
|
nfds = 1;
|
||||||
|
rfds = NULL;
|
||||||
|
wfds = NULL;
|
||||||
|
xfds = NULL;
|
||||||
|
}
|
||||||
|
return select (nfds, rfds, wfds, xfds, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
309
lib/sys_select.in.h
Normal file
309
lib/sys_select.in.h
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
/* Substitute for <sys/select.h>.
|
||||||
|
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
# if __GNUC__ >= 3
|
||||||
|
@PRAGMA_SYSTEM_HEADER@
|
||||||
|
# endif
|
||||||
|
@PRAGMA_COLUMNS@
|
||||||
|
|
||||||
|
/* On OSF/1 and Solaris 2.6, <sys/types.h> and <sys/time.h>
|
||||||
|
both include <sys/select.h>.
|
||||||
|
Simply delegate to the system's header in this case. */
|
||||||
|
#if (@HAVE_SYS_SELECT_H@ \
|
||||||
|
&& ((defined __osf__ && defined _SYS_TYPES_H_ && defined _OSF_SOURCE) \
|
||||||
|
|| (defined __sun && defined _SYS_TYPES_H \
|
||||||
|
&& (! (defined _XOPEN_SOURCE || defined _POSIX_C_SOURCE) \
|
||||||
|
|| defined __EXTENSIONS__))) \
|
||||||
|
&& !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H)
|
||||||
|
|
||||||
|
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
|
||||||
|
|
||||||
|
#elif (@HAVE_SYS_SELECT_H@ \
|
||||||
|
&& ((defined __osf__ && defined _SYS_TIME_H_ && defined _OSF_SOURCE) \
|
||||||
|
|| (defined __sun && defined _SYS_TIME_H \
|
||||||
|
&& (! (defined _XOPEN_SOURCE || defined _POSIX_C_SOURCE) \
|
||||||
|
|| defined __EXTENSIONS__))) \
|
||||||
|
&& !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H)
|
||||||
|
|
||||||
|
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_H
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
|
||||||
|
|
||||||
|
/* On IRIX 6.5, <sys/timespec.h> includes <sys/types.h>, which includes
|
||||||
|
<sys/bsd_types.h>, which includes <sys/select.h>. At this point we cannot
|
||||||
|
include <signal.h>, because that includes <internal/signal_core.h>, which
|
||||||
|
gives a syntax error because <sys/timespec.h> has not been completely
|
||||||
|
processed. Simply delegate to the system's header in this case. */
|
||||||
|
#elif @HAVE_SYS_SELECT_H@ && defined __sgi && (defined _SYS_BSD_TYPES_H && !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H)
|
||||||
|
|
||||||
|
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_BSD_TYPES_H
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
|
||||||
|
|
||||||
|
/* On OpenBSD 5.0, <pthread.h> includes <sys/types.h>, which includes
|
||||||
|
<sys/select.h>. At this point we cannot include <signal.h>, because that
|
||||||
|
includes gnulib's pthread.h override, which gives a syntax error because
|
||||||
|
/usr/include/pthread.h has not been completely processed. Simply delegate
|
||||||
|
to the system's header in this case. */
|
||||||
|
#elif @HAVE_SYS_SELECT_H@ && defined __OpenBSD__ && (defined _PTHREAD_H_ && !defined PTHREAD_MUTEX_INITIALIZER)
|
||||||
|
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef _@GUARD_PREFIX@_SYS_SELECT_H
|
||||||
|
|
||||||
|
/* On many platforms, <sys/select.h> assumes prior inclusion of
|
||||||
|
<sys/types.h>. Also, mingw defines sigset_t there, instead of
|
||||||
|
in <signal.h> where it belongs. */
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if @HAVE_SYS_SELECT_H@
|
||||||
|
|
||||||
|
/* On OSF/1 4.0, <sys/select.h> provides only a forward declaration
|
||||||
|
of 'struct timeval', and no definition of this type.
|
||||||
|
Also, Mac OS X, AIX, HP-UX, IRIX, Solaris, Interix declare select()
|
||||||
|
in <sys/time.h>.
|
||||||
|
But avoid namespace pollution on glibc systems. */
|
||||||
|
# ifndef __GLIBC__
|
||||||
|
# include <sys/time.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* On AIX 7 and Solaris 10, <sys/select.h> provides an FD_ZERO implementation
|
||||||
|
that relies on memset(), but without including <string.h>.
|
||||||
|
But in any case avoid namespace pollution on glibc systems. */
|
||||||
|
# if (defined __OpenBSD__ || defined _AIX || defined __sun || defined __osf__ || defined __BEOS__) \
|
||||||
|
&& ! defined __GLIBC__
|
||||||
|
# include <string.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* The include_next requires a split double-inclusion guard. */
|
||||||
|
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get definition of 'sigset_t'.
|
||||||
|
But avoid namespace pollution on glibc systems.
|
||||||
|
Do this after the include_next (for the sake of OpenBSD 5.0) but before
|
||||||
|
the split double-inclusion guard (for the sake of Solaris). */
|
||||||
|
#if !(defined __GLIBC__ && !defined __UCLIBC__)
|
||||||
|
# include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _@GUARD_PREFIX@_SYS_SELECT_H
|
||||||
|
#define _@GUARD_PREFIX@_SYS_SELECT_H
|
||||||
|
|
||||||
|
#if !@HAVE_SYS_SELECT_H@
|
||||||
|
/* A platform that lacks <sys/select.h>. */
|
||||||
|
/* Get the 'struct timeval' and 'fd_set' types and the FD_* macros
|
||||||
|
on most platforms. */
|
||||||
|
# include <sys/time.h>
|
||||||
|
/* On HP-UX 11, <sys/time.h> provides an FD_ZERO implementation
|
||||||
|
that relies on memset(), but without including <string.h>. */
|
||||||
|
# if defined __hpux
|
||||||
|
# include <string.h>
|
||||||
|
# endif
|
||||||
|
/* On native Windows platforms:
|
||||||
|
Get the 'fd_set' type.
|
||||||
|
Get the close() declaration before we override it. */
|
||||||
|
# if @HAVE_WINSOCK2_H@
|
||||||
|
# if !defined _GL_INCLUDING_WINSOCK2_H
|
||||||
|
# define _GL_INCLUDING_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
# undef _GL_INCLUDING_WINSOCK2_H
|
||||||
|
# endif
|
||||||
|
# include <io.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||||
|
|
||||||
|
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Fix some definitions from <winsock2.h>. */
|
||||||
|
|
||||||
|
#if @HAVE_WINSOCK2_H@
|
||||||
|
|
||||||
|
# if !GNULIB_defined_rpl_fd_isset
|
||||||
|
|
||||||
|
/* Re-define FD_ISSET to avoid a WSA call while we are not using
|
||||||
|
network sockets. */
|
||||||
|
static int
|
||||||
|
rpl_fd_isset (SOCKET fd, fd_set * set)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
if (set == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < set->fd_count; i++)
|
||||||
|
if (set->fd_array[i] == fd)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# define GNULIB_defined_rpl_fd_isset 1
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# undef FD_ISSET
|
||||||
|
# define FD_ISSET(fd, set) rpl_fd_isset(fd, set)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Hide some function declarations from <winsock2.h>. */
|
||||||
|
|
||||||
|
#if @HAVE_WINSOCK2_H@
|
||||||
|
# if !defined _@GUARD_PREFIX@_UNISTD_H
|
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
|
# undef close
|
||||||
|
# define close close_used_without_including_unistd_h
|
||||||
|
# else
|
||||||
|
_GL_WARN_ON_USE (close,
|
||||||
|
"close() used without including <unistd.h>");
|
||||||
|
# endif
|
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
|
# undef gethostname
|
||||||
|
# define gethostname gethostname_used_without_including_unistd_h
|
||||||
|
# else
|
||||||
|
_GL_WARN_ON_USE (gethostname,
|
||||||
|
"gethostname() used without including <unistd.h>");
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
|
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
|
# undef socket
|
||||||
|
# define socket socket_used_without_including_sys_socket_h
|
||||||
|
# undef connect
|
||||||
|
# define connect connect_used_without_including_sys_socket_h
|
||||||
|
# undef accept
|
||||||
|
# define accept accept_used_without_including_sys_socket_h
|
||||||
|
# undef bind
|
||||||
|
# define bind bind_used_without_including_sys_socket_h
|
||||||
|
# undef getpeername
|
||||||
|
# define getpeername getpeername_used_without_including_sys_socket_h
|
||||||
|
# undef getsockname
|
||||||
|
# define getsockname getsockname_used_without_including_sys_socket_h
|
||||||
|
# undef getsockopt
|
||||||
|
# define getsockopt getsockopt_used_without_including_sys_socket_h
|
||||||
|
# undef listen
|
||||||
|
# define listen listen_used_without_including_sys_socket_h
|
||||||
|
# undef recv
|
||||||
|
# define recv recv_used_without_including_sys_socket_h
|
||||||
|
# undef send
|
||||||
|
# define send send_used_without_including_sys_socket_h
|
||||||
|
# undef recvfrom
|
||||||
|
# define recvfrom recvfrom_used_without_including_sys_socket_h
|
||||||
|
# undef sendto
|
||||||
|
# define sendto sendto_used_without_including_sys_socket_h
|
||||||
|
# undef setsockopt
|
||||||
|
# define setsockopt setsockopt_used_without_including_sys_socket_h
|
||||||
|
# undef shutdown
|
||||||
|
# define shutdown shutdown_used_without_including_sys_socket_h
|
||||||
|
# else
|
||||||
|
_GL_WARN_ON_USE (socket,
|
||||||
|
"socket() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (connect,
|
||||||
|
"connect() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (accept,
|
||||||
|
"accept() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (bind,
|
||||||
|
"bind() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (getpeername,
|
||||||
|
"getpeername() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (getsockname,
|
||||||
|
"getsockname() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (getsockopt,
|
||||||
|
"getsockopt() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (listen,
|
||||||
|
"listen() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (recv,
|
||||||
|
"recv() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (send,
|
||||||
|
"send() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (recvfrom,
|
||||||
|
"recvfrom() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (sendto,
|
||||||
|
"sendto() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (setsockopt,
|
||||||
|
"setsockopt() used without including <sys/socket.h>");
|
||||||
|
_GL_WARN_ON_USE (shutdown,
|
||||||
|
"shutdown() used without including <sys/socket.h>");
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if @GNULIB_PSELECT@
|
||||||
|
# if @REPLACE_PSELECT@
|
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
|
# undef pselect
|
||||||
|
# define pselect rpl_pselect
|
||||||
|
# endif
|
||||||
|
_GL_FUNCDECL_RPL (pselect, int,
|
||||||
|
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
|
||||||
|
struct timespec const *restrict, const sigset_t *restrict));
|
||||||
|
_GL_CXXALIAS_RPL (pselect, int,
|
||||||
|
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
|
||||||
|
struct timespec const *restrict, const sigset_t *restrict));
|
||||||
|
# else
|
||||||
|
# if !@HAVE_PSELECT@
|
||||||
|
_GL_FUNCDECL_SYS (pselect, int,
|
||||||
|
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
|
||||||
|
struct timespec const *restrict, const sigset_t *restrict));
|
||||||
|
# endif
|
||||||
|
_GL_CXXALIAS_SYS (pselect, int,
|
||||||
|
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
|
||||||
|
struct timespec const *restrict, const sigset_t *restrict));
|
||||||
|
# endif
|
||||||
|
_GL_CXXALIASWARN (pselect);
|
||||||
|
#elif defined GNULIB_POSIXCHECK
|
||||||
|
# undef pselect
|
||||||
|
# if HAVE_RAW_DECL_PSELECT
|
||||||
|
_GL_WARN_ON_USE (pselect, "pselect is not portable - "
|
||||||
|
"use gnulib module pselect for portability");
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if @GNULIB_SELECT@
|
||||||
|
# if @REPLACE_SELECT@
|
||||||
|
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||||
|
# undef select
|
||||||
|
# define select rpl_select
|
||||||
|
# endif
|
||||||
|
_GL_FUNCDECL_RPL (select, int,
|
||||||
|
(int, fd_set *, fd_set *, fd_set *, struct timeval *));
|
||||||
|
_GL_CXXALIAS_RPL (select, int,
|
||||||
|
(int, fd_set *, fd_set *, fd_set *, struct timeval *));
|
||||||
|
# else
|
||||||
|
_GL_CXXALIAS_SYS (select, int,
|
||||||
|
(int, fd_set *, fd_set *, fd_set *, struct timeval *));
|
||||||
|
# endif
|
||||||
|
_GL_CXXALIASWARN (select);
|
||||||
|
#elif @HAVE_WINSOCK2_H@
|
||||||
|
# undef select
|
||||||
|
# define select select_used_without_requesting_gnulib_module_select
|
||||||
|
#elif defined GNULIB_POSIXCHECK
|
||||||
|
# undef select
|
||||||
|
# if HAVE_RAW_DECL_SELECT
|
||||||
|
_GL_WARN_ON_USE (select, "select is not always POSIX compliant - "
|
||||||
|
"use gnulib module select for portability");
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */
|
||||||
|
#endif /* _@GUARD_PREFIX@_SYS_SELECT_H */
|
||||||
|
#endif /* OSF/1 */
|
84
m4/dup2.m4
Normal file
84
m4/dup2.m4
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#serial 19
|
||||||
|
dnl Copyright (C) 2002, 2005, 2007, 2009-2013 Free Software Foundation, Inc.
|
||||||
|
dnl This file is free software; the Free Software Foundation
|
||||||
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
|
dnl with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
AC_DEFUN([gl_FUNC_DUP2],
|
||||||
|
[
|
||||||
|
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
|
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||||
|
m4_ifdef([gl_FUNC_DUP2_OBSOLETE], [
|
||||||
|
AC_CHECK_FUNCS_ONCE([dup2])
|
||||||
|
if test $ac_cv_func_dup2 = no; then
|
||||||
|
HAVE_DUP2=0
|
||||||
|
fi
|
||||||
|
], [
|
||||||
|
AC_DEFINE([HAVE_DUP2], [1], [Define to 1 if you have the 'dup2' function.])
|
||||||
|
])
|
||||||
|
if test $HAVE_DUP2 = 1; then
|
||||||
|
AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works],
|
||||||
|
[AC_RUN_IFELSE([
|
||||||
|
AC_LANG_PROGRAM([[#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>]],
|
||||||
|
[int result = 0;
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
|
if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1)
|
||||||
|
result |= 1;
|
||||||
|
#endif
|
||||||
|
if (dup2 (1, 1) == 0)
|
||||||
|
result |= 2;
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
|
if (fcntl (1, F_GETFD) != FD_CLOEXEC)
|
||||||
|
result |= 4;
|
||||||
|
#endif
|
||||||
|
close (0);
|
||||||
|
if (dup2 (0, 0) != -1)
|
||||||
|
result |= 8;
|
||||||
|
/* Many gnulib modules require POSIX conformance of EBADF. */
|
||||||
|
if (dup2 (2, 1000000) == -1 && errno != EBADF)
|
||||||
|
result |= 16;
|
||||||
|
/* Flush out a cygwin core dump. */
|
||||||
|
if (dup2 (2, -1) != -1 || errno != EBADF)
|
||||||
|
result |= 32;
|
||||||
|
return result;
|
||||||
|
])
|
||||||
|
],
|
||||||
|
[gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no],
|
||||||
|
[case "$host_os" in
|
||||||
|
mingw*) # on this platform, dup2 always returns 0 for success
|
||||||
|
gl_cv_func_dup2_works="guessing no" ;;
|
||||||
|
cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0
|
||||||
|
gl_cv_func_dup2_works="guessing no" ;;
|
||||||
|
linux*) # On linux between 2008-07-27 and 2009-05-11, dup2 of a
|
||||||
|
# closed fd may yield -EBADF instead of -1 / errno=EBADF.
|
||||||
|
gl_cv_func_dup2_works="guessing no" ;;
|
||||||
|
freebsd*) # on FreeBSD 6.1, dup2(1,1000000) gives EMFILE, not EBADF.
|
||||||
|
gl_cv_func_dup2_works="guessing no" ;;
|
||||||
|
haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC.
|
||||||
|
gl_cv_func_dup2_works="guessing no" ;;
|
||||||
|
*) gl_cv_func_dup2_works="guessing yes" ;;
|
||||||
|
esac])
|
||||||
|
])
|
||||||
|
case "$gl_cv_func_dup2_works" in
|
||||||
|
*yes) ;;
|
||||||
|
*)
|
||||||
|
REPLACE_DUP2=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
dnl Replace dup2() for supporting the gnulib-defined fchdir() function,
|
||||||
|
dnl to keep fchdir's bookkeeping up-to-date.
|
||||||
|
m4_ifdef([gl_FUNC_FCHDIR], [
|
||||||
|
gl_TEST_FCHDIR
|
||||||
|
if test $HAVE_FCHDIR = 0; then
|
||||||
|
if test $HAVE_DUP2 = 1; then
|
||||||
|
REPLACE_DUP2=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
# Prerequisites of lib/dup2.c.
|
||||||
|
AC_DEFUN([gl_PREREQ_DUP2], [])
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
|
|
||||||
# Specification in the form of a command-line invocation:
|
# Specification in the form of a command-line invocation:
|
||||||
# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp full-read full-write func gendocs getaddrinfo getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe2 putenv recv recvfrom regex rename send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat trunc verify vsnprintf warnings wchar
|
# gnulib-tool --import --dir=. --local-dir=gnulib-local --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --lgpl=3 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files accept alignof alloca-opt announce-gen autobuild bind byteswap canonicalize-lgpl ceil clock-time close connect dirfd duplocale environ extensions flock floor fpieee frexp full-read full-write func gendocs getaddrinfo getpeername getsockname getsockopt git-version-gen gitlog-to-changelog gnu-web-doc-update gnupload havelib iconv_open-utf inet_ntop inet_pton isinf isnan ldexp lib-symbol-versions lib-symbol-visibility libunistring listen localcharset locale log1p maintainer-makefile malloc-gnu malloca nl_langinfo nproc open pipe2 putenv recv recvfrom regex rename select send sendto setenv setsockopt shutdown socket stat-time stdlib strftime striconveh string sys_stat trunc verify vsnprintf warnings wchar
|
||||||
|
|
||||||
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
||||||
gl_LOCAL_DIR([gnulib-local])
|
gl_LOCAL_DIR([gnulib-local])
|
||||||
|
@ -90,6 +90,7 @@ gl_MODULES([
|
||||||
recvfrom
|
recvfrom
|
||||||
regex
|
regex
|
||||||
rename
|
rename
|
||||||
|
select
|
||||||
send
|
send
|
||||||
sendto
|
sendto
|
||||||
setenv
|
setenv
|
||||||
|
|
|
@ -41,6 +41,7 @@ AC_DEFUN([gl_EARLY],
|
||||||
AC_REQUIRE([AM_PROG_CC_C_O])
|
AC_REQUIRE([AM_PROG_CC_C_O])
|
||||||
# Code from module accept:
|
# Code from module accept:
|
||||||
# Code from module alignof:
|
# Code from module alignof:
|
||||||
|
# Code from module alloca:
|
||||||
# Code from module alloca-opt:
|
# Code from module alloca-opt:
|
||||||
# Code from module announce-gen:
|
# Code from module announce-gen:
|
||||||
# Code from module arpa_inet:
|
# Code from module arpa_inet:
|
||||||
|
@ -65,6 +66,7 @@ AC_DEFUN([gl_EARLY],
|
||||||
# Code from module dirname-lgpl:
|
# Code from module dirname-lgpl:
|
||||||
# Code from module dosname:
|
# Code from module dosname:
|
||||||
# Code from module double-slash-root:
|
# Code from module double-slash-root:
|
||||||
|
# Code from module dup2:
|
||||||
# Code from module duplocale:
|
# Code from module duplocale:
|
||||||
# Code from module environ:
|
# Code from module environ:
|
||||||
# Code from module errno:
|
# Code from module errno:
|
||||||
|
@ -158,6 +160,7 @@ AC_DEFUN([gl_EARLY],
|
||||||
# Code from module safe-read:
|
# Code from module safe-read:
|
||||||
# Code from module safe-write:
|
# Code from module safe-write:
|
||||||
# Code from module same-inode:
|
# Code from module same-inode:
|
||||||
|
# Code from module select:
|
||||||
# Code from module send:
|
# Code from module send:
|
||||||
# Code from module sendto:
|
# Code from module sendto:
|
||||||
# Code from module servent:
|
# Code from module servent:
|
||||||
|
@ -190,6 +193,7 @@ AC_DEFUN([gl_EARLY],
|
||||||
# Code from module striconveh:
|
# Code from module striconveh:
|
||||||
# Code from module string:
|
# Code from module string:
|
||||||
# Code from module sys_file:
|
# Code from module sys_file:
|
||||||
|
# Code from module sys_select:
|
||||||
# Code from module sys_socket:
|
# Code from module sys_socket:
|
||||||
# Code from module sys_stat:
|
# Code from module sys_stat:
|
||||||
# Code from module sys_time:
|
# Code from module sys_time:
|
||||||
|
@ -238,6 +242,10 @@ AC_DEFUN([gl_INIT],
|
||||||
AC_LIBOBJ([accept])
|
AC_LIBOBJ([accept])
|
||||||
fi
|
fi
|
||||||
gl_SYS_SOCKET_MODULE_INDICATOR([accept])
|
gl_SYS_SOCKET_MODULE_INDICATOR([accept])
|
||||||
|
changequote(,)dnl
|
||||||
|
LTALLOCA=`echo "$ALLOCA" | sed -e 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'`
|
||||||
|
changequote([, ])dnl
|
||||||
|
AC_SUBST([LTALLOCA])
|
||||||
gl_FUNC_ALLOCA
|
gl_FUNC_ALLOCA
|
||||||
gl_HEADER_ARPA_INET
|
gl_HEADER_ARPA_INET
|
||||||
AC_PROG_MKDIR_P
|
AC_PROG_MKDIR_P
|
||||||
|
@ -287,6 +295,12 @@ AC_DEFUN([gl_INIT],
|
||||||
gl_DIRENT_MODULE_INDICATOR([dirfd])
|
gl_DIRENT_MODULE_INDICATOR([dirfd])
|
||||||
gl_DIRNAME_LGPL
|
gl_DIRNAME_LGPL
|
||||||
gl_DOUBLE_SLASH_ROOT
|
gl_DOUBLE_SLASH_ROOT
|
||||||
|
gl_FUNC_DUP2
|
||||||
|
if test $HAVE_DUP2 = 0 || test $REPLACE_DUP2 = 1; then
|
||||||
|
AC_LIBOBJ([dup2])
|
||||||
|
gl_PREREQ_DUP2
|
||||||
|
fi
|
||||||
|
gl_UNISTD_MODULE_INDICATOR([dup2])
|
||||||
gl_FUNC_DUPLOCALE
|
gl_FUNC_DUPLOCALE
|
||||||
if test $REPLACE_DUPLOCALE = 1; then
|
if test $REPLACE_DUPLOCALE = 1; then
|
||||||
AC_LIBOBJ([duplocale])
|
AC_LIBOBJ([duplocale])
|
||||||
|
@ -587,6 +601,11 @@ AC_DEFUN([gl_INIT],
|
||||||
gl_MATH_MODULE_INDICATOR([round])
|
gl_MATH_MODULE_INDICATOR([round])
|
||||||
gl_PREREQ_SAFE_READ
|
gl_PREREQ_SAFE_READ
|
||||||
gl_PREREQ_SAFE_WRITE
|
gl_PREREQ_SAFE_WRITE
|
||||||
|
gl_FUNC_SELECT
|
||||||
|
if test $REPLACE_SELECT = 1; then
|
||||||
|
AC_LIBOBJ([select])
|
||||||
|
fi
|
||||||
|
gl_SYS_SELECT_MODULE_INDICATOR([select])
|
||||||
AC_REQUIRE([gl_HEADER_SYS_SOCKET])
|
AC_REQUIRE([gl_HEADER_SYS_SOCKET])
|
||||||
if test "$ac_cv_header_winsock2_h" = yes; then
|
if test "$ac_cv_header_winsock2_h" = yes; then
|
||||||
AC_LIBOBJ([send])
|
AC_LIBOBJ([send])
|
||||||
|
@ -658,6 +677,8 @@ AC_DEFUN([gl_INIT],
|
||||||
gl_HEADER_STRING_H
|
gl_HEADER_STRING_H
|
||||||
gl_HEADER_SYS_FILE_H
|
gl_HEADER_SYS_FILE_H
|
||||||
AC_PROG_MKDIR_P
|
AC_PROG_MKDIR_P
|
||||||
|
gl_HEADER_SYS_SELECT
|
||||||
|
AC_PROG_MKDIR_P
|
||||||
gl_HEADER_SYS_SOCKET
|
gl_HEADER_SYS_SOCKET
|
||||||
AC_PROG_MKDIR_P
|
AC_PROG_MKDIR_P
|
||||||
gl_HEADER_SYS_STAT_H
|
gl_HEADER_SYS_STAT_H
|
||||||
|
@ -863,6 +884,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
doc/gendocs_template
|
doc/gendocs_template
|
||||||
lib/accept.c
|
lib/accept.c
|
||||||
lib/alignof.h
|
lib/alignof.h
|
||||||
|
lib/alloca.c
|
||||||
lib/alloca.in.h
|
lib/alloca.in.h
|
||||||
lib/arpa_inet.in.h
|
lib/arpa_inet.in.h
|
||||||
lib/asnprintf.c
|
lib/asnprintf.c
|
||||||
|
@ -888,6 +910,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
lib/dirname-lgpl.c
|
lib/dirname-lgpl.c
|
||||||
lib/dirname.h
|
lib/dirname.h
|
||||||
lib/dosname.h
|
lib/dosname.h
|
||||||
|
lib/dup2.c
|
||||||
lib/duplocale.c
|
lib/duplocale.c
|
||||||
lib/errno.in.h
|
lib/errno.in.h
|
||||||
lib/fcntl.in.h
|
lib/fcntl.in.h
|
||||||
|
@ -989,6 +1012,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
lib/safe-write.c
|
lib/safe-write.c
|
||||||
lib/safe-write.h
|
lib/safe-write.h
|
||||||
lib/same-inode.h
|
lib/same-inode.h
|
||||||
|
lib/select.c
|
||||||
lib/send.c
|
lib/send.c
|
||||||
lib/sendto.c
|
lib/sendto.c
|
||||||
lib/setenv.c
|
lib/setenv.c
|
||||||
|
@ -1017,6 +1041,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
lib/string.in.h
|
lib/string.in.h
|
||||||
lib/stripslash.c
|
lib/stripslash.c
|
||||||
lib/sys_file.in.h
|
lib/sys_file.in.h
|
||||||
|
lib/sys_select.in.h
|
||||||
lib/sys_socket.c
|
lib/sys_socket.c
|
||||||
lib/sys_socket.in.h
|
lib/sys_socket.in.h
|
||||||
lib/sys_stat.in.h
|
lib/sys_stat.in.h
|
||||||
|
@ -1068,6 +1093,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
m4/dirfd.m4
|
m4/dirfd.m4
|
||||||
m4/dirname.m4
|
m4/dirname.m4
|
||||||
m4/double-slash-root.m4
|
m4/double-slash-root.m4
|
||||||
|
m4/dup2.m4
|
||||||
m4/duplocale.m4
|
m4/duplocale.m4
|
||||||
m4/eealloc.m4
|
m4/eealloc.m4
|
||||||
m4/environ.m4
|
m4/environ.m4
|
||||||
|
@ -1158,6 +1184,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
m4/round.m4
|
m4/round.m4
|
||||||
m4/safe-read.m4
|
m4/safe-read.m4
|
||||||
m4/safe-write.m4
|
m4/safe-write.m4
|
||||||
|
m4/select.m4
|
||||||
m4/servent.m4
|
m4/servent.m4
|
||||||
m4/setenv.m4
|
m4/setenv.m4
|
||||||
m4/signal_h.m4
|
m4/signal_h.m4
|
||||||
|
@ -1180,6 +1207,7 @@ AC_DEFUN([gl_FILE_LIST], [
|
||||||
m4/strftime.m4
|
m4/strftime.m4
|
||||||
m4/string_h.m4
|
m4/string_h.m4
|
||||||
m4/sys_file_h.m4
|
m4/sys_file_h.m4
|
||||||
|
m4/sys_select_h.m4
|
||||||
m4/sys_socket_h.m4
|
m4/sys_socket_h.m4
|
||||||
m4/sys_stat_h.m4
|
m4/sys_stat_h.m4
|
||||||
m4/sys_time_h.m4
|
m4/sys_time_h.m4
|
||||||
|
|
113
m4/select.m4
Normal file
113
m4/select.m4
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
# select.m4 serial 7
|
||||||
|
dnl Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||||
|
dnl This file is free software; the Free Software Foundation
|
||||||
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
|
dnl with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
AC_DEFUN([gl_FUNC_SELECT],
|
||||||
|
[
|
||||||
|
AC_REQUIRE([gl_HEADER_SYS_SELECT])
|
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||||
|
AC_REQUIRE([gl_SOCKETS])
|
||||||
|
if test "$ac_cv_header_winsock2_h" = yes; then
|
||||||
|
REPLACE_SELECT=1
|
||||||
|
else
|
||||||
|
dnl On Interix 3.5, select(0, NULL, NULL, NULL, timeout) fails with error
|
||||||
|
dnl EFAULT.
|
||||||
|
AC_CHECK_HEADERS_ONCE([sys/select.h])
|
||||||
|
AC_CACHE_CHECK([whether select supports a 0 argument],
|
||||||
|
[gl_cv_func_select_supports0],
|
||||||
|
[
|
||||||
|
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#if HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 5;
|
||||||
|
return select (0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &timeout) < 0;
|
||||||
|
}]])], [gl_cv_func_select_supports0=yes], [gl_cv_func_select_supports0=no],
|
||||||
|
[
|
||||||
|
changequote(,)dnl
|
||||||
|
case "$host_os" in
|
||||||
|
# Guess no on Interix.
|
||||||
|
interix*) gl_cv_func_select_supports0="guessing no";;
|
||||||
|
# Guess yes otherwise.
|
||||||
|
*) gl_cv_func_select_supports0="guessing yes";;
|
||||||
|
esac
|
||||||
|
changequote([,])dnl
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case "$gl_cv_func_select_supports0" in
|
||||||
|
*yes) ;;
|
||||||
|
*) REPLACE_SELECT=1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
dnl On FreeBSD 8.2, select() doesn't always reject bad fds.
|
||||||
|
AC_CACHE_CHECK([whether select detects invalid fds],
|
||||||
|
[gl_cv_func_select_detects_ebadf],
|
||||||
|
[
|
||||||
|
AC_RUN_IFELSE([AC_LANG_PROGRAM([[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#if HAVE_SYS_SELECT_H
|
||||||
|
# include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
]],[[
|
||||||
|
fd_set set;
|
||||||
|
dup2(0, 16);
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(16, &set);
|
||||||
|
close(16);
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = 5;
|
||||||
|
return select (17, &set, NULL, NULL, &timeout) != -1 || errno != EBADF;
|
||||||
|
]])], [gl_cv_func_select_detects_ebadf=yes],
|
||||||
|
[gl_cv_func_select_detects_ebadf=no],
|
||||||
|
[
|
||||||
|
case "$host_os" in
|
||||||
|
# Guess yes on glibc systems.
|
||||||
|
*-gnu*) gl_cv_func_select_detects_ebadf="guessing yes" ;;
|
||||||
|
# If we don't know, assume the worst.
|
||||||
|
*) gl_cv_func_select_detects_ebadf="guessing no" ;;
|
||||||
|
esac
|
||||||
|
])
|
||||||
|
])
|
||||||
|
case $gl_cv_func_select_detects_ebadf in
|
||||||
|
*yes) ;;
|
||||||
|
*) REPLACE_SELECT=1 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Determine the needed libraries.
|
||||||
|
LIB_SELECT="$LIBSOCKET"
|
||||||
|
if test $REPLACE_SELECT = 1; then
|
||||||
|
case "$host_os" in
|
||||||
|
mingw*)
|
||||||
|
dnl On the MSVC platform, the function MsgWaitForMultipleObjects
|
||||||
|
dnl (used in lib/select.c) requires linking with -luser32. On mingw,
|
||||||
|
dnl it is implicit.
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_SOURCE([[
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
MsgWaitForMultipleObjects (0, NULL, 0, 0, 0);
|
||||||
|
return 0;
|
||||||
|
}]])],
|
||||||
|
[],
|
||||||
|
[LIB_SELECT="$LIB_SELECT -luser32"])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
AC_SUBST([LIB_SELECT])
|
||||||
|
])
|
95
m4/sys_select_h.m4
Normal file
95
m4/sys_select_h.m4
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# sys_select_h.m4 serial 20
|
||||||
|
dnl Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||||
|
dnl This file is free software; the Free Software Foundation
|
||||||
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
|
dnl with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
AC_DEFUN([gl_HEADER_SYS_SELECT],
|
||||||
|
[
|
||||||
|
AC_REQUIRE([AC_C_RESTRICT])
|
||||||
|
AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
|
||||||
|
AC_CACHE_CHECK([whether <sys/select.h> is self-contained],
|
||||||
|
[gl_cv_header_sys_select_h_selfcontained],
|
||||||
|
[
|
||||||
|
dnl Test against two bugs:
|
||||||
|
dnl 1. On many platforms, <sys/select.h> assumes prior inclusion of
|
||||||
|
dnl <sys/types.h>.
|
||||||
|
dnl 2. On OSF/1 4.0, <sys/select.h> provides only a forward declaration
|
||||||
|
dnl of 'struct timeval', and no definition of this type.
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/select.h>]],
|
||||||
|
[[struct timeval b;]])],
|
||||||
|
[gl_cv_header_sys_select_h_selfcontained=yes],
|
||||||
|
[gl_cv_header_sys_select_h_selfcontained=no])
|
||||||
|
dnl Test against another bug:
|
||||||
|
dnl 3. On Solaris 10, <sys/select.h> provides an FD_ZERO implementation
|
||||||
|
dnl that relies on memset(), but without including <string.h>.
|
||||||
|
if test $gl_cv_header_sys_select_h_selfcontained = yes; then
|
||||||
|
AC_COMPILE_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([[#include <sys/select.h>]],
|
||||||
|
[[int memset; int bzero;]])
|
||||||
|
],
|
||||||
|
[AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM([[#include <sys/select.h>]], [[
|
||||||
|
#undef memset
|
||||||
|
#define memset nonexistent_memset
|
||||||
|
extern
|
||||||
|
#ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
#endif
|
||||||
|
void *memset (void *, int, unsigned long);
|
||||||
|
#undef bzero
|
||||||
|
#define bzero nonexistent_bzero
|
||||||
|
extern
|
||||||
|
#ifdef __cplusplus
|
||||||
|
"C"
|
||||||
|
#endif
|
||||||
|
void bzero (void *, unsigned long);
|
||||||
|
fd_set fds;
|
||||||
|
FD_ZERO (&fds);
|
||||||
|
]])
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
[gl_cv_header_sys_select_h_selfcontained=no])
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
dnl <sys/select.h> is always overridden, because of GNULIB_POSIXCHECK.
|
||||||
|
gl_CHECK_NEXT_HEADERS([sys/select.h])
|
||||||
|
if test $ac_cv_header_sys_select_h = yes; then
|
||||||
|
HAVE_SYS_SELECT_H=1
|
||||||
|
else
|
||||||
|
HAVE_SYS_SELECT_H=0
|
||||||
|
fi
|
||||||
|
AC_SUBST([HAVE_SYS_SELECT_H])
|
||||||
|
gl_PREREQ_SYS_H_WINSOCK2
|
||||||
|
|
||||||
|
dnl Check for declarations of anything we want to poison if the
|
||||||
|
dnl corresponding gnulib module is not in use.
|
||||||
|
gl_WARN_ON_USE_PREPARE([[
|
||||||
|
/* Some systems require prerequisite headers. */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#if !(defined __GLIBC__ && !defined __UCLIBC__) && HAVE_SYS_TIME_H
|
||||||
|
# include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/select.h>
|
||||||
|
]], [pselect select])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([gl_SYS_SELECT_MODULE_INDICATOR],
|
||||||
|
[
|
||||||
|
dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
|
||||||
|
AC_REQUIRE([gl_SYS_SELECT_H_DEFAULTS])
|
||||||
|
gl_MODULE_INDICATOR_SET_VARIABLE([$1])
|
||||||
|
dnl Define it also as a C macro, for the benefit of the unit tests.
|
||||||
|
gl_MODULE_INDICATOR_FOR_TESTS([$1])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([gl_SYS_SELECT_H_DEFAULTS],
|
||||||
|
[
|
||||||
|
GNULIB_PSELECT=0; AC_SUBST([GNULIB_PSELECT])
|
||||||
|
GNULIB_SELECT=0; AC_SUBST([GNULIB_SELECT])
|
||||||
|
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||||
|
HAVE_PSELECT=1; AC_SUBST([HAVE_PSELECT])
|
||||||
|
REPLACE_PSELECT=0; AC_SUBST([REPLACE_PSELECT])
|
||||||
|
REPLACE_SELECT=0; AC_SUBST([REPLACE_SELECT])
|
||||||
|
])
|
Loading…
Add table
Add a link
Reference in a new issue