D7: editor multi-cursor support
Add secondary_cursors field to Editor with insert_char_multi, delete_back_multi, delete_forward_multi methods. Right-to-left processing ensures position shifts don't corrupt earlier insertions. 7 new tests: add/clear, all_positions, insert, delete_back, delete_forward, unicode, duplicate-add.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
include gnulib.mk
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,10 @@
|
||||
#if !defined _Noreturn && __STDC_VERSION__ < 201112
|
||||
# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \
|
||||
|| 0x5110 <= __SUNPRO_C)
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
# elif 1200 <= _MSC_VER
|
||||
# define _Noreturn __declspec (noreturn)
|
||||
# else
|
||||
# define _Noreturn
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/* accept.c --- wrappers for Windows accept function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* Get winsock2.h. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
#include "w32sock.h"
|
||||
|
||||
#undef accept
|
||||
|
||||
int
|
||||
rpl_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
SOCKET sock = FD_TO_SOCKET (fd);
|
||||
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SOCKET fh = accept (sock, addr, addrlen);
|
||||
if (fh == INVALID_SOCKET)
|
||||
{
|
||||
set_winsock_errno ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return SOCKET_TO_FD (fh);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/* A C macro for declaring that specific arguments must not be NULL.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU 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
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
|
||||
that the values passed as arguments n, ..., m must be non-NULL pointers.
|
||||
n = 1 stands for the first argument, n = 2 for the second argument etc. */
|
||||
#ifndef _GL_ARG_NONNULL
|
||||
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
|
||||
# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define _GL_ARG_NONNULL(params)
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
/* A GNU-like <arpa/inet.h>.
|
||||
|
||||
Copyright (C) 2005-2006, 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_ARPA_INET_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
#if @HAVE_FEATURES_H@
|
||||
# include <features.h> /* for __GLIBC__ */
|
||||
#endif
|
||||
|
||||
/* Gnulib's sys/socket.h is responsible for defining socklen_t (used below) and
|
||||
for pulling in winsock2.h etc. under MinGW.
|
||||
But avoid namespace pollution on glibc systems. */
|
||||
#ifndef __GLIBC__
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* On NonStop Kernel, inet_ntop and inet_pton are declared in <netdb.h>.
|
||||
But avoid namespace pollution on glibc systems. */
|
||||
#if defined __TANDEM && !defined __GLIBC__
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
|
||||
#if @HAVE_ARPA_INET_H@
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
# @INCLUDE_NEXT@ @NEXT_ARPA_INET_H@
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_ARPA_INET_H
|
||||
#define _@GUARD_PREFIX@_ARPA_INET_H
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
|
||||
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||
|
||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||
|
||||
|
||||
#if @GNULIB_INET_NTOP@
|
||||
/* Converts an internet address from internal format to a printable,
|
||||
presentable format.
|
||||
AF is an internet address family, such as AF_INET or AF_INET6.
|
||||
SRC points to a 'struct in_addr' (for AF_INET) or 'struct in6_addr'
|
||||
(for AF_INET6).
|
||||
DST points to a buffer having room for CNT bytes.
|
||||
The printable representation of the address (in numeric form, not
|
||||
surrounded by [...], no reverse DNS is done) is placed in DST, and
|
||||
DST is returned. If an error occurs, the return value is NULL and
|
||||
errno is set. If CNT bytes are not sufficient to hold the result,
|
||||
the return value is NULL and errno is set to ENOSPC. A good value
|
||||
for CNT is 46.
|
||||
|
||||
For more details, see the POSIX:2001 specification
|
||||
<http://www.opengroup.org/susv3xsh/inet_ntop.html>. */
|
||||
# if @REPLACE_INET_NTOP@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef inet_ntop
|
||||
# define inet_ntop rpl_inet_ntop
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (inet_ntop, const char *,
|
||||
(int af, const void *restrict src,
|
||||
char *restrict dst, socklen_t cnt)
|
||||
_GL_ARG_NONNULL ((2, 3)));
|
||||
_GL_CXXALIAS_RPL (inet_ntop, const char *,
|
||||
(int af, const void *restrict src,
|
||||
char *restrict dst, socklen_t cnt));
|
||||
# else
|
||||
# if !@HAVE_DECL_INET_NTOP@
|
||||
_GL_FUNCDECL_SYS (inet_ntop, const char *,
|
||||
(int af, const void *restrict src,
|
||||
char *restrict dst, socklen_t cnt)
|
||||
_GL_ARG_NONNULL ((2, 3)));
|
||||
# endif
|
||||
/* Need to cast, because on NonStop Kernel, the fourth parameter is
|
||||
size_t cnt. */
|
||||
_GL_CXXALIAS_SYS_CAST (inet_ntop, const char *,
|
||||
(int af, const void *restrict src,
|
||||
char *restrict dst, socklen_t cnt));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (inet_ntop);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef inet_ntop
|
||||
# if HAVE_RAW_DECL_INET_NTOP
|
||||
_GL_WARN_ON_USE (inet_ntop, "inet_ntop is unportable - "
|
||||
"use gnulib module inet_ntop for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_INET_PTON@
|
||||
# if @REPLACE_INET_PTON@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef inet_pton
|
||||
# define inet_pton rpl_inet_pton
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (inet_pton, int,
|
||||
(int af, const char *restrict src, void *restrict dst)
|
||||
_GL_ARG_NONNULL ((2, 3)));
|
||||
_GL_CXXALIAS_RPL (inet_pton, int,
|
||||
(int af, const char *restrict src, void *restrict dst));
|
||||
# else
|
||||
# if !@HAVE_DECL_INET_PTON@
|
||||
_GL_FUNCDECL_SYS (inet_pton, int,
|
||||
(int af, const char *restrict src, void *restrict dst)
|
||||
_GL_ARG_NONNULL ((2, 3)));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (inet_pton, int,
|
||||
(int af, const char *restrict src, void *restrict dst));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (inet_pton);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef inet_pton
|
||||
# if HAVE_RAW_DECL_INET_PTON
|
||||
_GL_WARN_ON_USE (inet_pton, "inet_pton is unportable - "
|
||||
"use gnulib module inet_pton for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_ARPA_INET_H */
|
||||
#endif /* _@GUARD_PREFIX@_ARPA_INET_H */
|
||||
@@ -0,0 +1,49 @@
|
||||
/* bind.c --- wrappers for Windows bind function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* Get winsock2.h. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
#include "w32sock.h"
|
||||
|
||||
#undef bind
|
||||
|
||||
int
|
||||
rpl_bind (int fd, const struct sockaddr *sockaddr, socklen_t len)
|
||||
{
|
||||
SOCKET sock = FD_TO_SOCKET (fd);
|
||||
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = bind (sock, sockaddr, len);
|
||||
if (r < 0)
|
||||
set_winsock_errno ();
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
/* C++ compatible function declaration macros.
|
||||
Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU 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
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GL_CXXDEFS_H
|
||||
#define _GL_CXXDEFS_H
|
||||
|
||||
/* Begin/end the GNULIB_NAMESPACE namespace. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
|
||||
# define _GL_END_NAMESPACE }
|
||||
#else
|
||||
# define _GL_BEGIN_NAMESPACE
|
||||
# define _GL_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
/* The three most frequent use cases of these macros are:
|
||||
|
||||
* For providing a substitute for a function that is missing on some
|
||||
platforms, but is declared and works fine on the platforms on which
|
||||
it exists:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if !@HAVE_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on all platforms,
|
||||
but is broken/insufficient and needs to be replaced on some platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on some platforms
|
||||
but is broken/insufficient and needs to be replaced on some of them and
|
||||
is additionally either missing or undeclared on some other platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* _GL_EXTERN_C declaration;
|
||||
performs the declaration with C linkage. */
|
||||
#if defined __cplusplus
|
||||
# define _GL_EXTERN_C extern "C"
|
||||
#else
|
||||
# define _GL_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
|
||||
declares a replacement function, named rpl_func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
|
||||
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
|
||||
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
|
||||
|
||||
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
|
||||
declares the system function, named func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype func parameters_and_attributes
|
||||
|
||||
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping rpl_func in an object with an inline conversion operator
|
||||
avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::rpl_func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
|
||||
except that the C function rpl_func may have a slightly different
|
||||
declaration. A cast is used to silence the "invalid conversion" error
|
||||
that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::rpl_func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to the system provided function func, if GNULIB_NAMESPACE
|
||||
is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping func in an object with an inline conversion operator
|
||||
avoids a reference to func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function func may have a slightly different declaration.
|
||||
A cast is used to silence the "invalid conversion" error that would
|
||||
otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function is picked among a set of overloaded functions,
|
||||
namely the one with rettype2 and parameters2. Two consecutive casts
|
||||
are used to silence the "cannot find a match" and "invalid conversion"
|
||||
errors that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* The outer cast must be a reinterpret_cast.
|
||||
The inner cast: When the function is defined as a set of overloaded
|
||||
functions, it works as a static_cast<>, choosing the designated variant.
|
||||
When the function is defined as a single variant, it works as a
|
||||
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN (func);
|
||||
causes a warning to be emitted when ::func is used but not when
|
||||
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
|
||||
variants. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN_1(func,namespace) \
|
||||
_GL_CXXALIASWARN_2 (func, namespace)
|
||||
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_WARN_ON_USE (func, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
|
||||
causes a warning to be emitted when the given overloaded variant of ::func
|
||||
is used but not when GNULIB_NAMESPACE::func is used. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
|
||||
GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
|
||||
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
#endif /* _GL_CXXDEFS_H */
|
||||
@@ -0,0 +1,56 @@
|
||||
/* connect.c --- wrappers for Windows connect function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* Get winsock2.h. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
#include "w32sock.h"
|
||||
|
||||
#undef connect
|
||||
|
||||
int
|
||||
rpl_connect (int fd, const struct sockaddr *sockaddr, socklen_t len)
|
||||
{
|
||||
SOCKET sock = FD_TO_SOCKET (fd);
|
||||
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = connect (sock, sockaddr, len);
|
||||
if (r < 0)
|
||||
{
|
||||
/* EINPROGRESS is not returned by WinSock 2.0; for backwards
|
||||
compatibility, connect(2) uses EWOULDBLOCK. */
|
||||
if (WSAGetLastError () == WSAEWOULDBLOCK)
|
||||
WSASetLastError (WSAEINPROGRESS);
|
||||
|
||||
set_winsock_errno ();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Convert double to timespec.
|
||||
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Paul Eggert */
|
||||
|
||||
/* Convert the double value SEC to a struct timespec. Round toward
|
||||
positive infinity. On overflow, return an extremal value. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "timespec.h"
|
||||
|
||||
#include "intprops.h"
|
||||
|
||||
struct timespec
|
||||
dtotimespec (double sec)
|
||||
{
|
||||
if (! (TYPE_MINIMUM (time_t) < sec))
|
||||
return make_timespec (TYPE_MINIMUM (time_t), 0);
|
||||
else if (! (sec < 1.0 + TYPE_MAXIMUM (time_t)))
|
||||
return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_RESOLUTION - 1);
|
||||
else
|
||||
{
|
||||
time_t s = sec;
|
||||
double frac = TIMESPEC_RESOLUTION * (sec - s);
|
||||
long ns = frac;
|
||||
ns += ns < frac;
|
||||
s += ns / TIMESPEC_RESOLUTION;
|
||||
ns %= TIMESPEC_RESOLUTION;
|
||||
|
||||
if (ns < 0)
|
||||
{
|
||||
s--;
|
||||
ns += TIMESPEC_RESOLUTION;
|
||||
}
|
||||
|
||||
return make_timespec (s, ns);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Open a stream with a given file descriptor.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
#endif
|
||||
|
||||
#undef fdopen
|
||||
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
static FILE *
|
||||
fdopen_nothrow (int fd, const char *mode)
|
||||
{
|
||||
FILE *result;
|
||||
|
||||
TRY_MSVC_INVAL
|
||||
{
|
||||
result = fdopen (fd, mode);
|
||||
}
|
||||
CATCH_MSVC_INVAL
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
DONE_MSVC_INVAL;
|
||||
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
# define fdopen_nothrow fdopen
|
||||
#endif
|
||||
|
||||
FILE *
|
||||
rpl_fdopen (int fd, const char *mode)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
FILE *fp;
|
||||
|
||||
errno = 0;
|
||||
fp = fdopen_nothrow (fd, mode);
|
||||
if (fp == NULL)
|
||||
{
|
||||
if (errno == 0)
|
||||
errno = EBADF;
|
||||
}
|
||||
else
|
||||
errno = saved_errno;
|
||||
|
||||
return fp;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/* Manipulating the FPU control word. -*- coding: utf-8 -*-
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2007.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FPUCW_H
|
||||
#define _FPUCW_H
|
||||
|
||||
/* The i386 floating point hardware (the 387 compatible FPU, not the modern
|
||||
SSE/SSE2 hardware) has a controllable rounding precision. It is specified
|
||||
through the 'PC' bits in the FPU control word ('fctrl' register). (See
|
||||
the GNU libc i386 <fpu_control.h> header for details.)
|
||||
|
||||
On some platforms, such as Linux or Solaris, the default precision setting
|
||||
is set to "extended precision". This means that 'long double' instructions
|
||||
operate correctly, but 'double' computations often produce slightly
|
||||
different results as on strictly IEEE 754 conforming systems.
|
||||
|
||||
On some platforms, such as NetBSD, the default precision is set to
|
||||
"double precision". This means that 'long double' instructions will operate
|
||||
only as 'double', i.e. lead to wrong results. Similarly on FreeBSD 6.4, at
|
||||
least for the division of 'long double' numbers.
|
||||
|
||||
The FPU control word is under control of the application, i.e. it is
|
||||
not required to be set either way by the ABI. (In fact, the i386 ABI
|
||||
http://refspecs.freestandards.org/elf/abi386-4.pdf page 3-12 = page 38
|
||||
is not clear about it. But in any case, gcc treats the control word
|
||||
like a "preserved" register: it emits code that assumes that the control
|
||||
word is preserved across calls, and it restores the control word at the
|
||||
end of functions that modify it.)
|
||||
|
||||
See Vincent Lefèvre's page http://www.vinc17.org/research/extended.en.html
|
||||
for a good explanation.
|
||||
See http://www.uwsg.iu.edu/hypermail/linux/kernel/0103.0/0453.html for
|
||||
some argumentation which setting should be the default. */
|
||||
|
||||
/* This header file provides the following facilities:
|
||||
fpucw_t integral type holding the value of 'fctrl'
|
||||
FPU_PC_MASK bit mask denoting the precision control
|
||||
FPU_PC_DOUBLE precision control for 53 bits mantissa
|
||||
FPU_PC_EXTENDED precision control for 64 bits mantissa
|
||||
GET_FPUCW () yields the current FPU control word
|
||||
SET_FPUCW (word) sets the FPU control word
|
||||
DECL_LONG_DOUBLE_ROUNDING variable declaration for
|
||||
BEGIN/END_LONG_DOUBLE_ROUNDING
|
||||
BEGIN_LONG_DOUBLE_ROUNDING () starts a sequence of instructions with
|
||||
'long double' safe operation precision
|
||||
END_LONG_DOUBLE_ROUNDING () ends a sequence of instructions with
|
||||
'long double' safe operation precision
|
||||
*/
|
||||
|
||||
/* Inline assembler like this works only with GNU C. */
|
||||
#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
|
||||
|
||||
typedef unsigned short fpucw_t; /* glibc calls this fpu_control_t */
|
||||
|
||||
# define FPU_PC_MASK 0x0300
|
||||
# define FPU_PC_DOUBLE 0x200 /* glibc calls this _FPU_DOUBLE */
|
||||
# define FPU_PC_EXTENDED 0x300 /* glibc calls this _FPU_EXTENDED */
|
||||
|
||||
# define GET_FPUCW() \
|
||||
({ fpucw_t _cw; \
|
||||
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&_cw)); \
|
||||
_cw; \
|
||||
})
|
||||
# define SET_FPUCW(word) \
|
||||
(void)({ fpucw_t _ncw = (word); \
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (*&_ncw)); \
|
||||
})
|
||||
|
||||
# define DECL_LONG_DOUBLE_ROUNDING \
|
||||
fpucw_t oldcw;
|
||||
# define BEGIN_LONG_DOUBLE_ROUNDING() \
|
||||
(void)(oldcw = GET_FPUCW (), \
|
||||
SET_FPUCW ((oldcw & ~FPU_PC_MASK) | FPU_PC_EXTENDED))
|
||||
# define END_LONG_DOUBLE_ROUNDING() \
|
||||
SET_FPUCW (oldcw)
|
||||
|
||||
#else
|
||||
|
||||
typedef unsigned int fpucw_t;
|
||||
|
||||
# define FPU_PC_MASK 0
|
||||
# define FPU_PC_DOUBLE 0
|
||||
# define FPU_PC_EXTENDED 0
|
||||
|
||||
# define GET_FPUCW() 0
|
||||
# define SET_FPUCW(word) (void)(word)
|
||||
|
||||
# define DECL_LONG_DOUBLE_ROUNDING
|
||||
# define BEGIN_LONG_DOUBLE_ROUNDING()
|
||||
# define END_LONG_DOUBLE_ROUNDING()
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _FPUCW_H */
|
||||
@@ -0,0 +1,193 @@
|
||||
/* ftruncate emulations for native Windows.
|
||||
Copyright (C) 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_CHSIZE
|
||||
/* A native Windows platform. */
|
||||
|
||||
# include <errno.h>
|
||||
|
||||
# if _GL_WINDOWS_64_BIT_OFF_T
|
||||
|
||||
/* Large File Support: off_t is 64-bit, but chsize() takes only a 32-bit
|
||||
argument. So, define a 64-bit safe SetFileSize function ourselves. */
|
||||
|
||||
/* Ensure that <windows.h> declares GetFileSizeEx. */
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT _WIN32_WINNT_WIN2K
|
||||
|
||||
/* Get declarations of the native Windows API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
static BOOL
|
||||
SetFileSize (HANDLE h, LONGLONG size)
|
||||
{
|
||||
LARGE_INTEGER old_size;
|
||||
|
||||
if (!GetFileSizeEx (h, &old_size))
|
||||
return FALSE;
|
||||
|
||||
if (size != old_size.QuadPart)
|
||||
{
|
||||
/* Duplicate the handle, so we are free to modify its file position. */
|
||||
HANDLE curr_process = GetCurrentProcess ();
|
||||
HANDLE tmph;
|
||||
|
||||
if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
|
||||
h, /* SourceHandle */
|
||||
curr_process, /* TargetProcessHandle */
|
||||
(PHANDLE) &tmph, /* TargetHandle */
|
||||
(DWORD) 0, /* DesiredAccess */
|
||||
FALSE, /* InheritHandle */
|
||||
DUPLICATE_SAME_ACCESS)) /* Options */
|
||||
return FALSE;
|
||||
|
||||
if (size < old_size.QuadPart)
|
||||
{
|
||||
/* Reduce the size. */
|
||||
LONG size_hi = (LONG) (size >> 32);
|
||||
if (SetFilePointer (tmph, (LONG) size, &size_hi, FILE_BEGIN)
|
||||
== INVALID_SET_FILE_POINTER
|
||||
&& GetLastError() != NO_ERROR)
|
||||
{
|
||||
CloseHandle (tmph);
|
||||
return FALSE;
|
||||
}
|
||||
if (!SetEndOfFile (tmph))
|
||||
{
|
||||
CloseHandle (tmph);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increase the size by adding zero bytes at the end. */
|
||||
static char zero_bytes[1024];
|
||||
LONG pos_hi = 0;
|
||||
LONG pos_lo = SetFilePointer (tmph, (LONG) 0, &pos_hi, FILE_END);
|
||||
LONGLONG pos;
|
||||
if (pos_lo == INVALID_SET_FILE_POINTER
|
||||
&& GetLastError() != NO_ERROR)
|
||||
{
|
||||
CloseHandle (tmph);
|
||||
return FALSE;
|
||||
}
|
||||
pos = ((LONGLONG) pos_hi << 32) | (ULONGLONG) (ULONG) pos_lo;
|
||||
while (pos < size)
|
||||
{
|
||||
DWORD written;
|
||||
LONGLONG count = size - pos;
|
||||
if (count > sizeof (zero_bytes))
|
||||
count = sizeof (zero_bytes);
|
||||
if (!WriteFile (tmph, zero_bytes, (DWORD) count, &written, NULL)
|
||||
|| written == 0)
|
||||
{
|
||||
CloseHandle (tmph);
|
||||
return FALSE;
|
||||
}
|
||||
pos += (ULONGLONG) (ULONG) written;
|
||||
}
|
||||
}
|
||||
/* Close the handle. */
|
||||
CloseHandle (tmph);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
ftruncate (int fd, off_t length)
|
||||
{
|
||||
HANDLE handle = (HANDLE) _get_osfhandle (fd);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (!SetFileSize (handle, length))
|
||||
{
|
||||
switch (GetLastError ())
|
||||
{
|
||||
case ERROR_ACCESS_DENIED:
|
||||
errno = EACCES;
|
||||
break;
|
||||
case ERROR_HANDLE_DISK_FULL:
|
||||
case ERROR_DISK_FULL:
|
||||
case ERROR_DISK_TOO_FRAGMENTED:
|
||||
errno = ENOSPC;
|
||||
break;
|
||||
default:
|
||||
errno = EIO;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# else
|
||||
|
||||
# include <io.h>
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
static int
|
||||
chsize_nothrow (int fd, long length)
|
||||
{
|
||||
int result;
|
||||
|
||||
TRY_MSVC_INVAL
|
||||
{
|
||||
result = chsize (fd, length);
|
||||
}
|
||||
CATCH_MSVC_INVAL
|
||||
{
|
||||
result = -1;
|
||||
errno = EBADF;
|
||||
}
|
||||
DONE_MSVC_INVAL;
|
||||
|
||||
return result;
|
||||
}
|
||||
# else
|
||||
# define chsize_nothrow chsize
|
||||
# endif
|
||||
|
||||
int
|
||||
ftruncate (int fd, off_t length)
|
||||
{
|
||||
return chsize_nothrow (fd, length);
|
||||
}
|
||||
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Copyright (C) 2011-2017 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 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if GNULIB_GETCWD
|
||||
/* Favor GPL getcwd.c if both getcwd and getcwd-lgpl modules are in use. */
|
||||
typedef int dummy;
|
||||
#else
|
||||
|
||||
/* Get the name of the current working directory, and put it in SIZE
|
||||
bytes of BUF. Returns NULL if the directory couldn't be determined
|
||||
(perhaps because the absolute name was longer than PATH_MAX, or
|
||||
because of missing read/search permissions on parent directories)
|
||||
or SIZE was too small. If successful, returns BUF. If BUF is
|
||||
NULL, an array is allocated with 'malloc'; the array is SIZE bytes
|
||||
long, unless SIZE == 0, in which case it is as big as
|
||||
necessary. */
|
||||
|
||||
# undef getcwd
|
||||
char *
|
||||
rpl_getcwd (char *buf, size_t size)
|
||||
{
|
||||
char *ptr;
|
||||
char *result;
|
||||
|
||||
/* Handle single size operations. */
|
||||
if (buf)
|
||||
{
|
||||
if (!size)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
return getcwd (buf, size);
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
buf = malloc (size);
|
||||
if (!buf)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
result = getcwd (buf, size);
|
||||
if (!result)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
free (buf);
|
||||
errno = saved_errno;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Flexible sizing requested. Avoid over-allocation for the common
|
||||
case of a name that fits within a 4k page, minus some space for
|
||||
local variables, to be sure we don't skip over a guard page. */
|
||||
{
|
||||
char tmp[4032];
|
||||
size = sizeof tmp;
|
||||
ptr = getcwd (tmp, size);
|
||||
if (ptr)
|
||||
{
|
||||
result = strdup (ptr);
|
||||
if (!result)
|
||||
errno = ENOMEM;
|
||||
return result;
|
||||
}
|
||||
if (errno != ERANGE)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* My what a large directory name we have. */
|
||||
do
|
||||
{
|
||||
size <<= 1;
|
||||
ptr = realloc (buf, size);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
free (buf);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
buf = ptr;
|
||||
result = getcwd (buf, size);
|
||||
}
|
||||
while (!result && errno == ERANGE);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
free (buf);
|
||||
errno = saved_errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Trim to fit, if possible. */
|
||||
result = realloc (buf, strlen (buf) + 1);
|
||||
if (!result)
|
||||
result = buf;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/* getpagesize emulation for systems where it cannot be done in a C macro.
|
||||
|
||||
Copyright (C) 2007, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible and Martin Lambers. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
/* This implementation is only for native Windows systems. */
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
int
|
||||
getpagesize (void)
|
||||
{
|
||||
SYSTEM_INFO system_info;
|
||||
GetSystemInfo (&system_info);
|
||||
return system_info.dwPageSize;
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
/* hash-pjw.c -- compute a hash value from a NUL-terminated string.
|
||||
|
||||
Copyright (C) 2001, 2003, 2006, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "hash-pjw.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
|
||||
|
||||
/* A hash function for NUL-terminated char* strings using
|
||||
the method described by Bruno Haible.
|
||||
See http://www.haible.de/bruno/hashfunc.html. */
|
||||
|
||||
size_t
|
||||
hash_pjw (const void *x, size_t tablesize)
|
||||
{
|
||||
const char *s;
|
||||
size_t h = 0;
|
||||
|
||||
for (s = x; *s; s++)
|
||||
h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
|
||||
|
||||
return h % tablesize;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/* hash-pjw.h -- declaration for a simple hash function
|
||||
Copyright (C) 2001, 2003, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Compute a hash code for a NUL-terminated string starting at X,
|
||||
and return the hash code modulo TABLESIZE.
|
||||
The result is platform dependent: it depends on the size of the 'size_t'
|
||||
type and on the signedness of the 'char' type. */
|
||||
extern size_t hash_pjw (void const *x, size_t tablesize) _GL_ATTRIBUTE_PURE;
|
||||
@@ -0,0 +1,268 @@
|
||||
/* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form
|
||||
|
||||
Copyright (C) 2006, 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if HAVE_DECL_INET_PTON
|
||||
|
||||
# undef inet_pton
|
||||
|
||||
int
|
||||
rpl_inet_pton (int af, const char *restrict src, void *restrict dst)
|
||||
{
|
||||
return inet_pton (af, src, dst);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# include <c-ctype.h>
|
||||
# include <string.h>
|
||||
# include <errno.h>
|
||||
|
||||
# define NS_INADDRSZ 4
|
||||
# define NS_IN6ADDRSZ 16
|
||||
# define NS_INT16SZ 2
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4 (const char *src, unsigned char *dst);
|
||||
# if HAVE_IPV6
|
||||
static int inet_pton6 (const char *src, unsigned char *dst);
|
||||
# endif
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid ('dst' is untouched in this case)
|
||||
* -1 if some other error occurred ('dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton (int af, const char *restrict src, void *restrict dst)
|
||||
{
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
return (inet_pton4 (src, dst));
|
||||
|
||||
# if HAVE_IPV6
|
||||
case AF_INET6:
|
||||
return (inet_pton6 (src, dst));
|
||||
# endif
|
||||
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal, octal (with the
|
||||
* exception of 0) and shorthand.
|
||||
* return:
|
||||
* 1 if 'src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch 'dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4 (const char *restrict src, unsigned char *restrict dst)
|
||||
{
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0')
|
||||
{
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
unsigned new = *tp * 10 + (ch - '0');
|
||||
|
||||
if (saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (!saw_digit)
|
||||
{
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
}
|
||||
else if (ch == '.' && saw_digit)
|
||||
{
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy (dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
# if HAVE_IPV6
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if 'src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch 'dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6 (const char *restrict src, unsigned char *restrict dst)
|
||||
{
|
||||
static const char xdigits[] = "0123456789abcdef";
|
||||
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *curtok;
|
||||
int ch, saw_xdigit;
|
||||
unsigned val;
|
||||
|
||||
tp = memset (tmp, '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = c_tolower (*src++)) != '\0')
|
||||
{
|
||||
const char *pch;
|
||||
|
||||
pch = strchr (xdigits, ch);
|
||||
if (pch != NULL)
|
||||
{
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = src;
|
||||
if (!saw_xdigit)
|
||||
{
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
else if (*src == '\0')
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4 (curtok, tp) > 0)
|
||||
{
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit)
|
||||
{
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL)
|
||||
{
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++)
|
||||
{
|
||||
endp[-i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy (dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,605 @@
|
||||
# source this file; set up for tests
|
||||
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Using this file in a test
|
||||
# =========================
|
||||
#
|
||||
# The typical skeleton of a test looks like this:
|
||||
#
|
||||
# #!/bin/sh
|
||||
# . "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
# Execute some commands.
|
||||
# Note that these commands are executed in a subdirectory, therefore you
|
||||
# need to prepend "../" to relative filenames in the build directory.
|
||||
# Note that the "path_prepend_ ." is useful only if the body of your
|
||||
# test invokes programs residing in the initial directory.
|
||||
# For example, if the programs you want to test are in src/, and this test
|
||||
# script is named tests/test-1, then you would use "path_prepend_ ../src",
|
||||
# or perhaps export PATH='$(abs_top_builddir)/src$(PATH_SEPARATOR)'"$$PATH"
|
||||
# to all tests via automake's TESTS_ENVIRONMENT.
|
||||
# Set the exit code 0 for success, 77 for skipped, or 1 or other for failure.
|
||||
# Use the skip_ and fail_ functions to print a diagnostic and then exit
|
||||
# with the corresponding exit code.
|
||||
# Exit $?
|
||||
|
||||
# Executing a test that uses this file
|
||||
# ====================================
|
||||
#
|
||||
# Running a single test:
|
||||
# $ make check TESTS=test-foo.sh
|
||||
#
|
||||
# Running a single test, with verbose output:
|
||||
# $ make check TESTS=test-foo.sh VERBOSE=yes
|
||||
#
|
||||
# Running a single test, keeping the temporary directory:
|
||||
# $ make check TESTS=test-foo.sh KEEP=yes
|
||||
#
|
||||
# Running a single test, with single-stepping:
|
||||
# 1. Go into a sub-shell:
|
||||
# $ bash
|
||||
# 2. Set relevant environment variables from TESTS_ENVIRONMENT in the
|
||||
# Makefile:
|
||||
# $ export srcdir=../../tests # this is an example
|
||||
# 3. Execute the commands from the test, copy&pasting them one by one:
|
||||
# $ . "$srcdir/init.sh"; path_prepend_ .
|
||||
# ...
|
||||
# 4. Finally
|
||||
# $ exit
|
||||
|
||||
ME_=`expr "./$0" : '.*/\(.*\)$'`
|
||||
|
||||
# We use a trap below for cleanup. This requires us to go through
|
||||
# hoops to get the right exit status transported through the handler.
|
||||
# So use 'Exit STATUS' instead of 'exit STATUS' inside of the tests.
|
||||
# Turn off errexit here so that we don't trip the bug with OSF1/Tru64
|
||||
# sh inside this function.
|
||||
Exit () { set +e; (exit $1); exit $1; }
|
||||
|
||||
# Print warnings (e.g., about skipped and failed tests) to this file number.
|
||||
# Override by defining to say, 9, in init.cfg, and putting say,
|
||||
# export ...ENVVAR_SETTINGS...; $(SHELL) 9>&2
|
||||
# in the definition of TESTS_ENVIRONMENT in your tests/Makefile.am file.
|
||||
# This is useful when using automake's parallel tests mode, to print
|
||||
# the reason for skip/failure to console, rather than to the .log files.
|
||||
: ${stderr_fileno_=2}
|
||||
|
||||
# Note that correct expansion of "$*" depends on IFS starting with ' '.
|
||||
# Always write the full diagnostic to stderr.
|
||||
# When stderr_fileno_ is not 2, also emit the first line of the
|
||||
# diagnostic to that file descriptor.
|
||||
warn_ ()
|
||||
{
|
||||
# If IFS does not start with ' ', set it and emit the warning in a subshell.
|
||||
case $IFS in
|
||||
' '*) printf '%s\n' "$*" >&2
|
||||
test $stderr_fileno_ = 2 \
|
||||
|| { printf '%s\n' "$*" | sed 1q >&$stderr_fileno_ ; } ;;
|
||||
*) (IFS=' '; warn_ "$@");;
|
||||
esac
|
||||
}
|
||||
fail_ () { warn_ "$ME_: failed test: $@"; Exit 1; }
|
||||
skip_ () { warn_ "$ME_: skipped test: $@"; Exit 77; }
|
||||
fatal_ () { warn_ "$ME_: hard error: $@"; Exit 99; }
|
||||
framework_failure_ () { warn_ "$ME_: set-up failure: $@"; Exit 99; }
|
||||
|
||||
# This is used to simplify checking of the return value
|
||||
# which is useful when ensuring a command fails as desired.
|
||||
# I.e., just doing `command ... &&fail=1` will not catch
|
||||
# a segfault in command for example. With this helper you
|
||||
# instead check an explicit exit code like
|
||||
# returns_ 1 command ... || fail
|
||||
returns_ () {
|
||||
# Disable tracing so it doesn't interfere with stderr of the wrapped command
|
||||
{ set +x; } 2>/dev/null
|
||||
|
||||
local exp_exit="$1"
|
||||
shift
|
||||
"$@"
|
||||
test $? -eq $exp_exit && ret_=0 || ret_=1
|
||||
|
||||
if test "$VERBOSE" = yes && test "$gl_set_x_corrupts_stderr_" = false; then
|
||||
set -x
|
||||
fi
|
||||
{ return $ret_; } 2>/dev/null
|
||||
}
|
||||
|
||||
# Sanitize this shell to POSIX mode, if possible.
|
||||
DUALCASE=1; export DUALCASE
|
||||
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
|
||||
emulate sh
|
||||
NULLCMD=:
|
||||
alias -g '${1+"$@"}'='"$@"'
|
||||
setopt NO_GLOB_SUBST
|
||||
else
|
||||
case `(set -o) 2>/dev/null` in
|
||||
*posix*) set -o posix ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# We require $(...) support unconditionally.
|
||||
# We require non-surprising "local" semantics (this eliminates dash).
|
||||
# This takes the admittedly draconian step of eliminating dash, because the
|
||||
# assignment tab=$(printf '\t') works fine, yet preceding it with "local "
|
||||
# transforms it into an assignment that sets the variable to the empty string.
|
||||
# That is too counter-intuitive, and can lead to subtle run-time malfunction.
|
||||
# The example below is less subtle in that with dash, it evokes the run-time
|
||||
# exception "dash: 1: local: 1: bad variable name".
|
||||
# We require a few additional shell features only when $EXEEXT is nonempty,
|
||||
# in order to support automatic $EXEEXT emulation:
|
||||
# - hyphen-containing alias names
|
||||
# - we prefer to use ${var#...} substitution, rather than having
|
||||
# to work around lack of support for that feature.
|
||||
# The following code attempts to find a shell with support for these features.
|
||||
# If the current shell passes the test, we're done. Otherwise, test other
|
||||
# shells until we find one that passes. If one is found, re-exec it.
|
||||
# If no acceptable shell is found, skip the current test.
|
||||
#
|
||||
# The "...set -x; P=1 true 2>err..." test is to disqualify any shell that
|
||||
# emits "P=1" into err, as /bin/sh from SunOS 5.11 and OpenBSD 4.7 do.
|
||||
#
|
||||
# Use "9" to indicate success (rather than 0), in case some shell acts
|
||||
# like Solaris 10's /bin/sh but exits successfully instead of with status 2.
|
||||
|
||||
# Eval this code in a subshell to determine a shell's suitability.
|
||||
# 10 - passes all tests; ok to use
|
||||
# 9 - ok, but enabling "set -x" corrupts app stderr; prefer higher score
|
||||
# ? - not ok
|
||||
gl_shell_test_script_='
|
||||
test $(echo y) = y || exit 1
|
||||
f_local_() { local v=1; }; f_local_ || exit 1
|
||||
f_dash_local_fail_() { local t=$(printf " 1"); }; f_dash_local_fail_
|
||||
score_=10
|
||||
if test "$VERBOSE" = yes; then
|
||||
test -n "$( (exec 3>&1; set -x; P=1 true 2>&3) 2> /dev/null)" && score_=9
|
||||
fi
|
||||
test -z "$EXEEXT" && exit $score_
|
||||
shopt -s expand_aliases
|
||||
alias a-b="echo zoo"
|
||||
v=abx
|
||||
test ${v%x} = ab \
|
||||
&& test ${v#a} = bx \
|
||||
&& test $(a-b) = zoo \
|
||||
&& exit $score_
|
||||
'
|
||||
|
||||
if test "x$1" = "x--no-reexec"; then
|
||||
shift
|
||||
else
|
||||
# Assume a working shell. Export to subshells (setup_ needs this).
|
||||
gl_set_x_corrupts_stderr_=false
|
||||
export gl_set_x_corrupts_stderr_
|
||||
|
||||
# Record the first marginally acceptable shell.
|
||||
marginal_=
|
||||
|
||||
# Search for a shell that meets our requirements.
|
||||
for re_shell_ in __current__ "${CONFIG_SHELL:-no_shell}" \
|
||||
/bin/sh bash dash zsh pdksh fail
|
||||
do
|
||||
test "$re_shell_" = no_shell && continue
|
||||
|
||||
# If we've made it all the way to the sentinel, "fail" without
|
||||
# finding even a marginal shell, skip this test.
|
||||
if test "$re_shell_" = fail; then
|
||||
test -z "$marginal_" && skip_ failed to find an adequate shell
|
||||
re_shell_=$marginal_
|
||||
break
|
||||
fi
|
||||
|
||||
# When testing the current shell, simply "eval" the test code.
|
||||
# Otherwise, run it via $re_shell_ -c ...
|
||||
if test "$re_shell_" = __current__; then
|
||||
# 'eval'ing this code makes Solaris 10's /bin/sh exit with
|
||||
# $? set to 2. It does not evaluate any of the code after the
|
||||
# "unexpected" first '('. Thus, we must run it in a subshell.
|
||||
( eval "$gl_shell_test_script_" ) > /dev/null 2>&1
|
||||
else
|
||||
"$re_shell_" -c "$gl_shell_test_script_" 2>/dev/null
|
||||
fi
|
||||
|
||||
st_=$?
|
||||
|
||||
# $re_shell_ works just fine. Use it.
|
||||
if test $st_ = 10; then
|
||||
gl_set_x_corrupts_stderr_=false
|
||||
break
|
||||
fi
|
||||
|
||||
# If this is our first marginally acceptable shell, remember it.
|
||||
if test "$st_:$marginal_" = 9: ; then
|
||||
marginal_="$re_shell_"
|
||||
gl_set_x_corrupts_stderr_=true
|
||||
fi
|
||||
done
|
||||
|
||||
if test "$re_shell_" != __current__; then
|
||||
# Found a usable shell. Preserve -v and -x.
|
||||
case $- in
|
||||
*v*x* | *x*v*) opts_=-vx ;;
|
||||
*v*) opts_=-v ;;
|
||||
*x*) opts_=-x ;;
|
||||
*) opts_= ;;
|
||||
esac
|
||||
re_shell=$re_shell_
|
||||
export re_shell
|
||||
exec "$re_shell_" $opts_ "$0" --no-reexec "$@"
|
||||
echo "$ME_: exec failed" 1>&2
|
||||
exit 127
|
||||
fi
|
||||
fi
|
||||
|
||||
# If this is bash, turn off all aliases.
|
||||
test -n "$BASH_VERSION" && unalias -a
|
||||
|
||||
# Note that when supporting $EXEEXT (transparently mapping from PROG_NAME to
|
||||
# PROG_NAME.exe), we want to support hyphen-containing names like test-acos.
|
||||
# That is part of the shell-selection test above. Why use aliases rather
|
||||
# than functions? Because support for hyphen-containing aliases is more
|
||||
# widespread than that for hyphen-containing function names.
|
||||
test -n "$EXEEXT" && shopt -s expand_aliases
|
||||
|
||||
# Enable glibc's malloc-perturbing option.
|
||||
# This is useful for exposing code that depends on the fact that
|
||||
# malloc-related functions often return memory that is mostly zeroed.
|
||||
# If you have the time and cycles, use valgrind to do an even better job.
|
||||
: ${MALLOC_PERTURB_=87}
|
||||
export MALLOC_PERTURB_
|
||||
|
||||
# This is a stub function that is run upon trap (upon regular exit and
|
||||
# interrupt). Override it with a per-test function, e.g., to unmount
|
||||
# a partition, or to undo any other global state changes.
|
||||
cleanup_ () { :; }
|
||||
|
||||
# Emit a header similar to that from diff -u; Print the simulated "diff"
|
||||
# command so that the order of arguments is clear. Don't bother with @@ lines.
|
||||
emit_diff_u_header_ ()
|
||||
{
|
||||
printf '%s\n' "diff -u $*" \
|
||||
"--- $1 1970-01-01" \
|
||||
"+++ $2 1970-01-01"
|
||||
}
|
||||
|
||||
# Arrange not to let diff or cmp operate on /dev/null,
|
||||
# since on some systems (at least OSF/1 5.1), that doesn't work.
|
||||
# When there are not two arguments, or no argument is /dev/null, return 2.
|
||||
# When one argument is /dev/null and the other is not empty,
|
||||
# cat the nonempty file to stderr and return 1.
|
||||
# Otherwise, return 0.
|
||||
compare_dev_null_ ()
|
||||
{
|
||||
test $# = 2 || return 2
|
||||
|
||||
if test "x$1" = x/dev/null; then
|
||||
test -s "$2" || return 0
|
||||
emit_diff_u_header_ "$@"; sed 's/^/+/' "$2"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if test "x$2" = x/dev/null; then
|
||||
test -s "$1" || return 0
|
||||
emit_diff_u_header_ "$@"; sed 's/^/-/' "$1"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 2
|
||||
}
|
||||
|
||||
for diff_opt_ in -u -U3 -c '' no; do
|
||||
test "$diff_opt_" != no &&
|
||||
diff_out_=`exec 2>/dev/null; diff $diff_opt_ "$0" "$0" < /dev/null` &&
|
||||
break
|
||||
done
|
||||
if test "$diff_opt_" != no; then
|
||||
if test -z "$diff_out_"; then
|
||||
compare_ () { diff $diff_opt_ "$@"; }
|
||||
else
|
||||
compare_ ()
|
||||
{
|
||||
# If no differences were found, AIX and HP-UX 'diff' produce output
|
||||
# like "No differences encountered". Hide this output.
|
||||
diff $diff_opt_ "$@" > diff.out
|
||||
diff_status_=$?
|
||||
test $diff_status_ -eq 0 || cat diff.out || diff_status_=2
|
||||
rm -f diff.out || diff_status_=2
|
||||
return $diff_status_
|
||||
}
|
||||
fi
|
||||
elif cmp -s /dev/null /dev/null 2>/dev/null; then
|
||||
compare_ () { cmp -s "$@"; }
|
||||
else
|
||||
compare_ () { cmp "$@"; }
|
||||
fi
|
||||
|
||||
# Usage: compare EXPECTED ACTUAL
|
||||
#
|
||||
# Given compare_dev_null_'s preprocessing, defer to compare_ if 2 or more.
|
||||
# Otherwise, propagate $? to caller: any diffs have already been printed.
|
||||
compare ()
|
||||
{
|
||||
# This looks like it can be factored to use a simple "case $?"
|
||||
# after unchecked compare_dev_null_ invocation, but that would
|
||||
# fail in a "set -e" environment.
|
||||
if compare_dev_null_ "$@"; then
|
||||
return 0
|
||||
else
|
||||
case $? in
|
||||
1) return 1;;
|
||||
*) compare_ "$@";;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
# An arbitrary prefix to help distinguish test directories.
|
||||
testdir_prefix_ () { printf gt; }
|
||||
|
||||
# Run the user-overridable cleanup_ function, remove the temporary
|
||||
# directory and exit with the incoming value of $?.
|
||||
remove_tmp_ ()
|
||||
{
|
||||
__st=$?
|
||||
cleanup_
|
||||
if test "$KEEP" = yes; then
|
||||
echo "Not removing temporary directory $test_dir_"
|
||||
else
|
||||
# cd out of the directory we're about to remove
|
||||
cd "$initial_cwd_" || cd / || cd /tmp
|
||||
chmod -R u+rwx "$test_dir_"
|
||||
# If removal fails and exit status was to be 0, then change it to 1.
|
||||
rm -rf "$test_dir_" || { test $__st = 0 && __st=1; }
|
||||
fi
|
||||
exit $__st
|
||||
}
|
||||
|
||||
# Given a directory name, DIR, if every entry in it that matches *.exe
|
||||
# contains only the specified bytes (see the case stmt below), then print
|
||||
# a space-separated list of those names and return 0. Otherwise, don't
|
||||
# print anything and return 1. Naming constraints apply also to DIR.
|
||||
find_exe_basenames_ ()
|
||||
{
|
||||
feb_dir_=$1
|
||||
feb_fail_=0
|
||||
feb_result_=
|
||||
feb_sp_=
|
||||
for feb_file_ in $feb_dir_/*.exe; do
|
||||
# If there was no *.exe file, or there existed a file named "*.exe" that
|
||||
# was deleted between the above glob expansion and the existence test
|
||||
# below, just skip it.
|
||||
test "x$feb_file_" = "x$feb_dir_/*.exe" && test ! -f "$feb_file_" \
|
||||
&& continue
|
||||
# Exempt [.exe, since we can't create a function by that name, yet
|
||||
# we can't invoke [ by PATH search anyways due to shell builtins.
|
||||
test "x$feb_file_" = "x$feb_dir_/[.exe" && continue
|
||||
case $feb_file_ in
|
||||
*[!-a-zA-Z/0-9_.+]*) feb_fail_=1; break;;
|
||||
*) # Remove leading file name components as well as the .exe suffix.
|
||||
feb_file_=${feb_file_##*/}
|
||||
feb_file_=${feb_file_%.exe}
|
||||
feb_result_="$feb_result_$feb_sp_$feb_file_";;
|
||||
esac
|
||||
feb_sp_=' '
|
||||
done
|
||||
test $feb_fail_ = 0 && printf %s "$feb_result_"
|
||||
return $feb_fail_
|
||||
}
|
||||
|
||||
# Consider the files in directory, $1.
|
||||
# For each file name of the form PROG.exe, create an alias named
|
||||
# PROG that simply invokes PROG.exe, then return 0. If any selected
|
||||
# file name or the directory name, $1, contains an unexpected character,
|
||||
# define no alias and return 1.
|
||||
create_exe_shims_ ()
|
||||
{
|
||||
case $EXEEXT in
|
||||
'') return 0 ;;
|
||||
.exe) ;;
|
||||
*) echo "$0: unexpected \$EXEEXT value: $EXEEXT" 1>&2; return 1 ;;
|
||||
esac
|
||||
|
||||
base_names_=`find_exe_basenames_ $1` \
|
||||
|| { echo "$0 (exe_shim): skipping directory: $1" 1>&2; return 0; }
|
||||
|
||||
if test -n "$base_names_"; then
|
||||
for base_ in $base_names_; do
|
||||
alias "$base_"="$base_$EXEEXT"
|
||||
done
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Use this function to prepend to PATH an absolute name for each
|
||||
# specified, possibly-$initial_cwd_-relative, directory.
|
||||
path_prepend_ ()
|
||||
{
|
||||
while test $# != 0; do
|
||||
path_dir_=$1
|
||||
case $path_dir_ in
|
||||
'') fail_ "invalid path dir: '$1'";;
|
||||
/*) abs_path_dir_=$path_dir_;;
|
||||
*) abs_path_dir_=$initial_cwd_/$path_dir_;;
|
||||
esac
|
||||
case $abs_path_dir_ in
|
||||
*:*) fail_ "invalid path dir: '$abs_path_dir_'";;
|
||||
esac
|
||||
PATH="$abs_path_dir_:$PATH"
|
||||
|
||||
# Create an alias, FOO, for each FOO.exe in this directory.
|
||||
create_exe_shims_ "$abs_path_dir_" \
|
||||
|| fail_ "something failed (above): $abs_path_dir_"
|
||||
shift
|
||||
done
|
||||
export PATH
|
||||
}
|
||||
|
||||
setup_ ()
|
||||
{
|
||||
if test "$VERBOSE" = yes; then
|
||||
# Test whether set -x may cause the selected shell to corrupt an
|
||||
# application's stderr. Many do, including zsh-4.3.10 and the /bin/sh
|
||||
# from SunOS 5.11, OpenBSD 4.7 and Irix 5.x and 6.5.
|
||||
# If enabling verbose output this way would cause trouble, simply
|
||||
# issue a warning and refrain.
|
||||
if $gl_set_x_corrupts_stderr_; then
|
||||
warn_ "using SHELL=$SHELL with 'set -x' corrupts stderr"
|
||||
else
|
||||
set -x
|
||||
fi
|
||||
fi
|
||||
|
||||
initial_cwd_=$PWD
|
||||
|
||||
pfx_=`testdir_prefix_`
|
||||
test_dir_=`mktempd_ "$initial_cwd_" "$pfx_-$ME_.XXXX"` \
|
||||
|| fail_ "failed to create temporary directory in $initial_cwd_"
|
||||
cd "$test_dir_" || fail_ "failed to cd to temporary directory"
|
||||
|
||||
# As autoconf-generated configure scripts do, ensure that IFS
|
||||
# is defined initially, so that saving and restoring $IFS works.
|
||||
gl_init_sh_nl_='
|
||||
'
|
||||
IFS=" "" $gl_init_sh_nl_"
|
||||
|
||||
# This trap statement, along with a trap on 0 below, ensure that the
|
||||
# temporary directory, $test_dir_, is removed upon exit as well as
|
||||
# upon receipt of any of the listed signals.
|
||||
for sig_ in 1 2 3 13 15; do
|
||||
eval "trap 'Exit $(expr $sig_ + 128)' $sig_"
|
||||
done
|
||||
}
|
||||
|
||||
# Create a temporary directory, much like mktemp -d does.
|
||||
# Written by Jim Meyering.
|
||||
#
|
||||
# Usage: mktempd_ /tmp phoey.XXXXXXXXXX
|
||||
#
|
||||
# First, try to use the mktemp program.
|
||||
# Failing that, we'll roll our own mktemp-like function:
|
||||
# - try to get random bytes from /dev/urandom
|
||||
# - failing that, generate output from a combination of quickly-varying
|
||||
# sources and gzip. Ignore non-varying gzip header, and extract
|
||||
# "random" bits from there.
|
||||
# - given those bits, map to file-name bytes using tr, and try to create
|
||||
# the desired directory.
|
||||
# - make only $MAX_TRIES_ attempts
|
||||
|
||||
# Helper function. Print $N pseudo-random bytes from a-zA-Z0-9.
|
||||
rand_bytes_ ()
|
||||
{
|
||||
n_=$1
|
||||
|
||||
# Maybe try openssl rand -base64 $n_prime_|tr '+/=\012' abcd first?
|
||||
# But if they have openssl, they probably have mktemp, too.
|
||||
|
||||
chars_=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
|
||||
dev_rand_=/dev/urandom
|
||||
if test -r "$dev_rand_"; then
|
||||
# Note: 256-length($chars_) == 194; 3 copies of $chars_ is 186 + 8 = 194.
|
||||
dd ibs=$n_ count=1 if=$dev_rand_ 2>/dev/null \
|
||||
| LC_ALL=C tr -c $chars_ 01234567$chars_$chars_$chars_
|
||||
return
|
||||
fi
|
||||
|
||||
n_plus_50_=`expr $n_ + 50`
|
||||
cmds_='date; date +%N; free; who -a; w; ps auxww; ps ef; netstat -n'
|
||||
data_=` (eval "$cmds_") 2>&1 | gzip `
|
||||
|
||||
# Ensure that $data_ has length at least 50+$n_
|
||||
while :; do
|
||||
len_=`echo "$data_"|wc -c`
|
||||
test $n_plus_50_ -le $len_ && break;
|
||||
data_=` (echo "$data_"; eval "$cmds_") 2>&1 | gzip `
|
||||
done
|
||||
|
||||
echo "$data_" \
|
||||
| dd bs=1 skip=50 count=$n_ 2>/dev/null \
|
||||
| LC_ALL=C tr -c $chars_ 01234567$chars_$chars_$chars_
|
||||
}
|
||||
|
||||
mktempd_ ()
|
||||
{
|
||||
case $# in
|
||||
2);;
|
||||
*) fail_ "Usage: mktempd_ DIR TEMPLATE";;
|
||||
esac
|
||||
|
||||
destdir_=$1
|
||||
template_=$2
|
||||
|
||||
MAX_TRIES_=4
|
||||
|
||||
# Disallow any trailing slash on specified destdir:
|
||||
# it would subvert the post-mktemp "case"-based destdir test.
|
||||
case $destdir_ in
|
||||
/ | //) destdir_slash_=$destdir;;
|
||||
*/) fail_ "invalid destination dir: remove trailing slash(es)";;
|
||||
*) destdir_slash_=$destdir_/;;
|
||||
esac
|
||||
|
||||
case $template_ in
|
||||
*XXXX) ;;
|
||||
*) fail_ \
|
||||
"invalid template: $template_ (must have a suffix of at least 4 X's)";;
|
||||
esac
|
||||
|
||||
# First, try to use mktemp.
|
||||
d=`unset TMPDIR; { mktemp -d -t -p "$destdir_" "$template_"; } 2>/dev/null` &&
|
||||
|
||||
# The resulting name must be in the specified directory.
|
||||
case $d in "$destdir_slash_"*) :;; *) false;; esac &&
|
||||
|
||||
# It must have created the directory.
|
||||
test -d "$d" &&
|
||||
|
||||
# It must have 0700 permissions. Handle sticky "S" bits.
|
||||
perms=`ls -dgo "$d" 2>/dev/null` &&
|
||||
case $perms in drwx--[-S]---*) :;; *) false;; esac && {
|
||||
echo "$d"
|
||||
return
|
||||
}
|
||||
|
||||
# If we reach this point, we'll have to create a directory manually.
|
||||
|
||||
# Get a copy of the template without its suffix of X's.
|
||||
base_template_=`echo "$template_"|sed 's/XX*$//'`
|
||||
|
||||
# Calculate how many X's we've just removed.
|
||||
template_length_=`echo "$template_" | wc -c`
|
||||
nx_=`echo "$base_template_" | wc -c`
|
||||
nx_=`expr $template_length_ - $nx_`
|
||||
|
||||
err_=
|
||||
i_=1
|
||||
while :; do
|
||||
X_=`rand_bytes_ $nx_`
|
||||
candidate_dir_="$destdir_slash_$base_template_$X_"
|
||||
err_=`mkdir -m 0700 "$candidate_dir_" 2>&1` \
|
||||
&& { echo "$candidate_dir_"; return; }
|
||||
test $MAX_TRIES_ -le $i_ && break;
|
||||
i_=`expr $i_ + 1`
|
||||
done
|
||||
fail_ "$err_"
|
||||
}
|
||||
|
||||
# If you want to override the testdir_prefix_ function,
|
||||
# or to add more utility functions, use this file.
|
||||
test -f "$srcdir/init.cfg" \
|
||||
&& . "$srcdir/init.cfg"
|
||||
|
||||
setup_ "$@"
|
||||
# This trap is here, rather than in the setup_ function, because some
|
||||
# shells run the exit trap at shell function exit, rather than script exit.
|
||||
trap remove_tmp_ 0
|
||||
@@ -0,0 +1,92 @@
|
||||
/* ioctl.c --- wrappers for Windows ioctl function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if HAVE_IOCTL
|
||||
|
||||
/* Provide a wrapper with the POSIX prototype. */
|
||||
# undef ioctl
|
||||
int
|
||||
rpl_ioctl (int fd, int request, ... /* {void *,char *} arg */)
|
||||
{
|
||||
void *buf;
|
||||
va_list args;
|
||||
|
||||
va_start (args, request);
|
||||
buf = va_arg (args, void *);
|
||||
va_end (args);
|
||||
|
||||
/* Cast 'request' so that when the system's ioctl function takes a 64-bit
|
||||
request argument, the value gets zero-extended, not sign-extended. */
|
||||
return ioctl (fd, (unsigned int) request, buf);
|
||||
}
|
||||
|
||||
#else /* mingw */
|
||||
|
||||
# include <errno.h>
|
||||
|
||||
/* Get HANDLE. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
# include "fd-hook.h"
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
static int
|
||||
primary_ioctl (int fd, int request, void *arg)
|
||||
{
|
||||
/* We don't support FIONBIO on pipes here. If you want to make pipe
|
||||
fds non-blocking, use the gnulib 'nonblocking' module, until
|
||||
gnulib implements fcntl F_GETFL / F_SETFL with O_NONBLOCK. */
|
||||
|
||||
if ((HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE)
|
||||
errno = ENOSYS;
|
||||
else
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ioctl (int fd, int request, ... /* {void *,char *} arg */)
|
||||
{
|
||||
void *arg;
|
||||
va_list args;
|
||||
|
||||
va_start (args, request);
|
||||
arg = va_arg (args, void *);
|
||||
va_end (args);
|
||||
|
||||
# if WINDOWS_SOCKETS
|
||||
return execute_all_ioctl_hooks (primary_ioctl, fd, request, arg);
|
||||
# else
|
||||
return primary_ioctl (fd, request, arg);
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/* listen.c --- wrappers for Windows listen function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* Get winsock2.h. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
#include "w32sock.h"
|
||||
|
||||
#undef listen
|
||||
|
||||
int
|
||||
rpl_listen (int fd, int backlog)
|
||||
{
|
||||
SOCKET sock = FD_TO_SOCKET (fd);
|
||||
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = listen (sock, backlog);
|
||||
if (r < 0)
|
||||
set_winsock_errno ();
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/* Common macros used by gnulib tests.
|
||||
Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
/* This file contains macros that are used by many gnulib tests.
|
||||
Put here only frequently used macros, say, used by 10 tests or more. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef FALLTHROUGH
|
||||
# if __GNUC__ < 7
|
||||
# define FALLTHROUGH ((void) 0)
|
||||
# else
|
||||
# define FALLTHROUGH __attribute__ ((__fallthrough__))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Define ASSERT_STREAM before including this file if ASSERT must
|
||||
target a stream other than stderr. */
|
||||
#ifndef ASSERT_STREAM
|
||||
# define ASSERT_STREAM stderr
|
||||
#endif
|
||||
|
||||
/* ASSERT (condition);
|
||||
verifies that the specified condition is fulfilled. If not, a message
|
||||
is printed to ASSERT_STREAM if defined (defaulting to stderr if
|
||||
undefined) and the program is terminated with an error code.
|
||||
|
||||
This macro has the following properties:
|
||||
- The programmer specifies the expected condition, not the failure
|
||||
condition. This simplifies thinking.
|
||||
- The condition is tested always, regardless of compilation flags.
|
||||
(Unlike the macro from <assert.h>.)
|
||||
- On Unix platforms, the tester can debug the test program with a
|
||||
debugger (provided core dumps are enabled: "ulimit -c unlimited").
|
||||
- For the sake of platforms where no debugger is available (such as
|
||||
some mingw systems), an error message is printed on the error
|
||||
stream that includes the source location of the ASSERT invocation.
|
||||
*/
|
||||
#define ASSERT(expr) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
fprintf (ASSERT_STREAM, "%s:%d: assertion '%s' failed\n", \
|
||||
__FILE__, __LINE__, #expr); \
|
||||
fflush (ASSERT_STREAM); \
|
||||
abort (); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* SIZEOF (array)
|
||||
returns the number of elements of an array. It works for arrays that are
|
||||
declared outside functions and for local variables of array type. It does
|
||||
*not* work for function parameters of array type, because they are actually
|
||||
parameters of pointer type. */
|
||||
#define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
|
||||
|
||||
/* STREQ (str1, str2)
|
||||
Return true if two strings compare equal. */
|
||||
#define STREQ(a, b) (strcmp (a, b) == 0)
|
||||
|
||||
/* Some numbers in the interval [0,1). */
|
||||
extern const float randomf[1000];
|
||||
extern const double randomd[1000];
|
||||
extern const long double randoml[1000];
|
||||
@@ -0,0 +1,276 @@
|
||||
/* Provide a replacement for the POSIX nanosleep function.
|
||||
|
||||
Copyright (C) 1999-2000, 2002, 2004-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Jim Meyering
|
||||
and Bruno Haible for the native Windows part */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "intprops.h"
|
||||
#include "sig-handler.h"
|
||||
#include "verify.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
enum { BILLION = 1000 * 1000 * 1000 };
|
||||
|
||||
#if HAVE_BUG_BIG_NANOSLEEP
|
||||
|
||||
int
|
||||
nanosleep (const struct timespec *requested_delay,
|
||||
struct timespec *remaining_delay)
|
||||
# undef nanosleep
|
||||
{
|
||||
/* nanosleep mishandles large sleeps due to internal overflow problems.
|
||||
The worst known case of this is Linux 2.6.9 with glibc 2.3.4, which
|
||||
can't sleep more than 24.85 days (2^31 milliseconds). Similarly,
|
||||
cygwin 1.5.x, which can't sleep more than 49.7 days (2^32 milliseconds).
|
||||
Solve this by breaking the sleep up into smaller chunks. */
|
||||
|
||||
if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
/* Verify that time_t is large enough. */
|
||||
verify (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60);
|
||||
const time_t limit = 24 * 24 * 60 * 60;
|
||||
time_t seconds = requested_delay->tv_sec;
|
||||
struct timespec intermediate;
|
||||
intermediate.tv_nsec = requested_delay->tv_nsec;
|
||||
|
||||
while (limit < seconds)
|
||||
{
|
||||
int result;
|
||||
intermediate.tv_sec = limit;
|
||||
result = nanosleep (&intermediate, remaining_delay);
|
||||
seconds -= limit;
|
||||
if (result)
|
||||
{
|
||||
if (remaining_delay)
|
||||
remaining_delay->tv_sec += seconds;
|
||||
return result;
|
||||
}
|
||||
intermediate.tv_nsec = 0;
|
||||
}
|
||||
intermediate.tv_sec = seconds;
|
||||
return nanosleep (&intermediate, remaining_delay);
|
||||
}
|
||||
}
|
||||
|
||||
#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Native Windows platforms. */
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
/* The Windows API function Sleep() has a resolution of about 15 ms and takes
|
||||
at least 5 ms to execute. We use this function for longer time periods.
|
||||
Additionally, we use busy-looping over short time periods, to get a
|
||||
resolution of about 0.01 ms. In order to measure such short timespans,
|
||||
we use the QueryPerformanceCounter() function. */
|
||||
|
||||
int
|
||||
nanosleep (const struct timespec *requested_delay,
|
||||
struct timespec *remaining_delay)
|
||||
{
|
||||
static bool initialized;
|
||||
/* Number of performance counter increments per nanosecond,
|
||||
or zero if it could not be determined. */
|
||||
static double ticks_per_nanosecond;
|
||||
|
||||
if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* For requested delays of one second or more, 15ms resolution is
|
||||
sufficient. */
|
||||
if (requested_delay->tv_sec == 0)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
/* Initialize ticks_per_nanosecond. */
|
||||
LARGE_INTEGER ticks_per_second;
|
||||
|
||||
if (QueryPerformanceFrequency (&ticks_per_second))
|
||||
ticks_per_nanosecond =
|
||||
(double) ticks_per_second.QuadPart / 1000000000.0;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
if (ticks_per_nanosecond)
|
||||
{
|
||||
/* QueryPerformanceFrequency worked. We can use
|
||||
QueryPerformanceCounter. Use a combination of Sleep and
|
||||
busy-looping. */
|
||||
/* Number of milliseconds to pass to the Sleep function.
|
||||
Since Sleep can take up to 8 ms less or 8 ms more than requested
|
||||
(or maybe more if the system is loaded), we subtract 10 ms. */
|
||||
int sleep_millis = (int) requested_delay->tv_nsec / 1000000 - 10;
|
||||
/* Determine how many ticks to delay. */
|
||||
LONGLONG wait_ticks = requested_delay->tv_nsec * ticks_per_nanosecond;
|
||||
/* Start. */
|
||||
LARGE_INTEGER counter_before;
|
||||
if (QueryPerformanceCounter (&counter_before))
|
||||
{
|
||||
/* Wait until the performance counter has reached this value.
|
||||
We don't need to worry about overflow, because the performance
|
||||
counter is reset at reboot, and with a frequency of 3.6E6
|
||||
ticks per second 63 bits suffice for over 80000 years. */
|
||||
LONGLONG wait_until = counter_before.QuadPart + wait_ticks;
|
||||
/* Use Sleep for the longest part. */
|
||||
if (sleep_millis > 0)
|
||||
Sleep (sleep_millis);
|
||||
/* Busy-loop for the rest. */
|
||||
for (;;)
|
||||
{
|
||||
LARGE_INTEGER counter_after;
|
||||
if (!QueryPerformanceCounter (&counter_after))
|
||||
/* QueryPerformanceCounter failed, but succeeded earlier.
|
||||
Should not happen. */
|
||||
break;
|
||||
if (counter_after.QuadPart >= wait_until)
|
||||
/* The requested time has elapsed. */
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Implementation for long delays and as fallback. */
|
||||
Sleep (requested_delay->tv_sec * 1000 + requested_delay->tv_nsec / 1000000);
|
||||
|
||||
done:
|
||||
/* Sleep is not interruptible. So there is no remaining delay. */
|
||||
if (remaining_delay != NULL)
|
||||
{
|
||||
remaining_delay->tv_sec = 0;
|
||||
remaining_delay->tv_nsec = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Unix platforms lacking nanosleep. */
|
||||
|
||||
/* Some systems (MSDOS) don't have SIGCONT.
|
||||
Using SIGTERM here turns the signal-handling code below
|
||||
into a no-op on such systems. */
|
||||
# ifndef SIGCONT
|
||||
# define SIGCONT SIGTERM
|
||||
# endif
|
||||
|
||||
static sig_atomic_t volatile suspended;
|
||||
|
||||
/* Handle SIGCONT. */
|
||||
|
||||
static void
|
||||
sighandler (int sig)
|
||||
{
|
||||
suspended = 1;
|
||||
}
|
||||
|
||||
/* Suspend execution for at least *TS_DELAY seconds. */
|
||||
|
||||
static int
|
||||
my_usleep (const struct timespec *ts_delay)
|
||||
{
|
||||
struct timeval tv_delay;
|
||||
tv_delay.tv_sec = ts_delay->tv_sec;
|
||||
tv_delay.tv_usec = (ts_delay->tv_nsec + 999) / 1000;
|
||||
if (tv_delay.tv_usec == 1000000)
|
||||
{
|
||||
if (tv_delay.tv_sec == TYPE_MAXIMUM (time_t))
|
||||
tv_delay.tv_usec = 1000000 - 1; /* close enough */
|
||||
else
|
||||
{
|
||||
tv_delay.tv_sec++;
|
||||
tv_delay.tv_usec = 0;
|
||||
}
|
||||
}
|
||||
return select (0, NULL, NULL, NULL, &tv_delay);
|
||||
}
|
||||
|
||||
/* Suspend execution for at least *REQUESTED_DELAY seconds. The
|
||||
*REMAINING_DELAY part isn't implemented yet. */
|
||||
|
||||
int
|
||||
nanosleep (const struct timespec *requested_delay,
|
||||
struct timespec *remaining_delay)
|
||||
{
|
||||
static bool initialized;
|
||||
|
||||
if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set up sig handler */
|
||||
if (! initialized)
|
||||
{
|
||||
struct sigaction oldact;
|
||||
|
||||
sigaction (SIGCONT, NULL, &oldact);
|
||||
if (get_handler (&oldact) != SIG_IGN)
|
||||
{
|
||||
struct sigaction newact;
|
||||
|
||||
newact.sa_handler = sighandler;
|
||||
sigemptyset (&newact.sa_mask);
|
||||
newact.sa_flags = 0;
|
||||
sigaction (SIGCONT, &newact, NULL);
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
suspended = 0;
|
||||
|
||||
if (my_usleep (requested_delay) == -1)
|
||||
{
|
||||
if (suspended)
|
||||
{
|
||||
/* Calculate time remaining. */
|
||||
/* FIXME: the code in sleep doesn't use this, so there's no
|
||||
rush to implement it. */
|
||||
|
||||
errno = EINTR;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* FIXME: Restore sig handler? */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/* Assist in file system timestamp tests.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
#ifndef GLTEST_NAP_H
|
||||
# define GLTEST_NAP_H
|
||||
|
||||
# include <limits.h>
|
||||
# include <stdbool.h>
|
||||
|
||||
/* Name of the witness file. */
|
||||
#define TEMPFILE BASE "nap.tmp"
|
||||
|
||||
/* File descriptor used for the witness file. */
|
||||
static int nap_fd = -1;
|
||||
|
||||
/* Return A - B, in ns.
|
||||
Return 0 if the true result would be negative.
|
||||
Return INT_MAX if the true result would be greater than INT_MAX. */
|
||||
static int
|
||||
diff_timespec (struct timespec a, struct timespec b)
|
||||
{
|
||||
time_t as = a.tv_sec;
|
||||
time_t bs = b.tv_sec;
|
||||
int ans = a.tv_nsec;
|
||||
int bns = b.tv_nsec;
|
||||
|
||||
if (! (bs < as || (bs == as && bns < ans)))
|
||||
return 0;
|
||||
if (as - bs <= INT_MAX / 1000000000)
|
||||
{
|
||||
int sdiff = (as - bs) * 1000000000;
|
||||
int usdiff = ans - bns;
|
||||
if (usdiff < INT_MAX - sdiff)
|
||||
return sdiff + usdiff;
|
||||
}
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
/* If DO_WRITE, bump the modification time of the file designated by NAP_FD.
|
||||
Then fetch the new STAT information of NAP_FD. */
|
||||
static void
|
||||
nap_get_stat (struct stat *st, int do_write)
|
||||
{
|
||||
if (do_write)
|
||||
{
|
||||
ASSERT (write (nap_fd, "\n", 1) == 1);
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On native Windows, the modification times are not changed until NAP_FD
|
||||
is closed. See
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx */
|
||||
close (nap_fd);
|
||||
nap_fd = open (TEMPFILE, O_RDWR, 0600);
|
||||
ASSERT (nap_fd != -1);
|
||||
lseek (nap_fd, 0, SEEK_END);
|
||||
#endif
|
||||
}
|
||||
ASSERT (fstat (nap_fd, st) == 0);
|
||||
}
|
||||
|
||||
/* Given a file whose descriptor is FD, see whether delaying by DELAY
|
||||
nanoseconds causes a change in a file's mtime.
|
||||
OLD_ST is the file's status, recently gotten. */
|
||||
static bool
|
||||
nap_works (int delay, struct stat old_st)
|
||||
{
|
||||
struct stat st;
|
||||
struct timespec delay_spec;
|
||||
delay_spec.tv_sec = delay / 1000000000;
|
||||
delay_spec.tv_nsec = delay % 1000000000;
|
||||
ASSERT (nanosleep (&delay_spec, 0) == 0);
|
||||
nap_get_stat (&st, 1);
|
||||
|
||||
if (diff_timespec (get_stat_mtime (&st), get_stat_mtime (&old_st)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_temp_file (void)
|
||||
{
|
||||
if (0 <= nap_fd)
|
||||
{
|
||||
ASSERT (close (nap_fd) != -1);
|
||||
ASSERT (unlink (TEMPFILE) != -1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sleep long enough to notice a timestamp difference on the file
|
||||
system in the current directory. Use an adaptive approach, trying
|
||||
to find the smallest delay which works on the current file system
|
||||
to make the timestamp difference appear. Assert a maximum delay of
|
||||
~2 seconds, more precisely sum(2^n) from 0 to 30 = 2^31 - 1 = 2.1s.
|
||||
Assumes that BASE is defined, and requires that the test module
|
||||
depends on nanosleep. */
|
||||
static void
|
||||
nap (void)
|
||||
{
|
||||
struct stat old_st;
|
||||
static int delay = 1;
|
||||
|
||||
if (-1 == nap_fd)
|
||||
{
|
||||
atexit (clear_temp_file);
|
||||
ASSERT ((nap_fd = creat (TEMPFILE, 0600)) != -1);
|
||||
nap_get_stat (&old_st, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (0 <= nap_fd);
|
||||
nap_get_stat (&old_st, 1);
|
||||
}
|
||||
|
||||
if (1 < delay)
|
||||
delay = delay / 2; /* Try half of the previous delay. */
|
||||
ASSERT (0 < delay);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (nap_works (delay, old_st))
|
||||
return;
|
||||
if (delay <= (2147483647 - 1) / 2)
|
||||
{
|
||||
delay = delay * 2 + 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* Bummer: even the highest nap delay didn't work. */
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
#endif /* GLTEST_NAP_H */
|
||||
@@ -0,0 +1,47 @@
|
||||
/* Substitute for <netinet/in.h>.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_NETINET_IN_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
#if @HAVE_NETINET_IN_H@
|
||||
|
||||
/* On many platforms, <netinet/in.h> assumes prior inclusion of
|
||||
<sys/types.h>. */
|
||||
# include <sys/types.h>
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
# @INCLUDE_NEXT@ @NEXT_NETINET_IN_H@
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_NETINET_IN_H
|
||||
#define _@GUARD_PREFIX@_NETINET_IN_H
|
||||
|
||||
#if !@HAVE_NETINET_IN_H@
|
||||
|
||||
/* A platform that lacks <netinet/in.h>. */
|
||||
|
||||
# include <sys/socket.h>
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_NETINET_IN_H */
|
||||
#endif /* _@GUARD_PREFIX@_NETINET_IN_H */
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Print a message describing error code.
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible and Simon Josefsson.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strerror-override.h"
|
||||
|
||||
/* Use the system functions, not the gnulib overrides in this file. */
|
||||
#undef fprintf
|
||||
|
||||
void
|
||||
perror (const char *string)
|
||||
{
|
||||
char stackbuf[STACKBUF_LEN];
|
||||
int ret;
|
||||
|
||||
/* Our implementation guarantees that this will be a non-empty
|
||||
string, even if it returns EINVAL; and stackbuf should be sized
|
||||
large enough to avoid ERANGE. */
|
||||
ret = strerror_r (errno, stackbuf, sizeof stackbuf);
|
||||
if (ret == ERANGE)
|
||||
abort ();
|
||||
|
||||
if (string != NULL && *string != '\0')
|
||||
fprintf (stderr, "%s: %s\n", string, stackbuf);
|
||||
else
|
||||
fprintf (stderr, "%s\n", stackbuf);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/* Create a pipe.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Native Windows API. */
|
||||
|
||||
/* Get _pipe(). */
|
||||
# include <io.h>
|
||||
|
||||
/* Get _O_BINARY. */
|
||||
# include <fcntl.h>
|
||||
|
||||
int
|
||||
pipe (int fd[2])
|
||||
{
|
||||
/* Mingw changes fd to {-1,-1} on failure, but this violates
|
||||
http://austingroupbugs.net/view.php?id=467 */
|
||||
int tmp[2];
|
||||
int result = _pipe (tmp, 4096, _O_BINARY);
|
||||
if (!result)
|
||||
{
|
||||
fd[0] = tmp[0];
|
||||
fd[1] = tmp[1];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# error "This platform lacks a pipe function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib."
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,194 @@
|
||||
/* Copyright (C) 1991, 1994, 1997-1998, 2000, 2003-2017 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C
|
||||
Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 3 of the License, or 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* Include errno.h *after* sys/types.h to work around header problems
|
||||
on AIX 3.2.5. */
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
# define __set_errno(ev) ((errno) = (ev))
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
# if HAVE_GNU_LD
|
||||
# define environ __environ
|
||||
# else
|
||||
extern char **environ;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _LIBC
|
||||
/* This lock protects against simultaneous modifications of 'environ'. */
|
||||
# include <bits/libc-lock.h>
|
||||
__libc_lock_define_initialized (static, envlock)
|
||||
# define LOCK __libc_lock_lock (envlock)
|
||||
# define UNLOCK __libc_lock_unlock (envlock)
|
||||
#else
|
||||
# define LOCK
|
||||
# define UNLOCK
|
||||
#endif
|
||||
|
||||
static int
|
||||
_unsetenv (const char *name)
|
||||
{
|
||||
size_t len;
|
||||
#if !HAVE_DECL__PUTENV
|
||||
char **ep;
|
||||
#endif
|
||||
|
||||
if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen (name);
|
||||
|
||||
#if HAVE_DECL__PUTENV
|
||||
{
|
||||
int putenv_result, putenv_errno;
|
||||
char *name_ = malloc (len + 2);
|
||||
memcpy (name_, name, len);
|
||||
name_[len] = '=';
|
||||
name_[len + 1] = 0;
|
||||
putenv_result = _putenv (name_);
|
||||
putenv_errno = errno;
|
||||
free (name_);
|
||||
__set_errno (putenv_errno);
|
||||
return putenv_result;
|
||||
}
|
||||
#else
|
||||
|
||||
LOCK;
|
||||
|
||||
ep = environ;
|
||||
while (*ep != NULL)
|
||||
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
{
|
||||
/* Found it. Remove this pointer by moving later ones back. */
|
||||
char **dp = ep;
|
||||
|
||||
do
|
||||
dp[0] = dp[1];
|
||||
while (*dp++);
|
||||
/* Continue the loop in case NAME appears again. */
|
||||
}
|
||||
else
|
||||
++ep;
|
||||
|
||||
UNLOCK;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Put STRING, which is of the form "NAME=VALUE", in the environment.
|
||||
If STRING contains no '=', then remove STRING from the environment. */
|
||||
int
|
||||
putenv (char *string)
|
||||
{
|
||||
const char *name_end = strchr (string, '=');
|
||||
char **ep;
|
||||
|
||||
if (name_end == NULL)
|
||||
{
|
||||
/* Remove the variable from the environment. */
|
||||
return _unsetenv (string);
|
||||
}
|
||||
|
||||
#if HAVE_DECL__PUTENV
|
||||
/* Rely on _putenv to allocate the new environment. If other
|
||||
parts of the application use _putenv, the !HAVE_DECL__PUTENV code
|
||||
would fight over who owns the environ vector, causing a crash. */
|
||||
if (name_end[1])
|
||||
return _putenv (string);
|
||||
else
|
||||
{
|
||||
/* _putenv ("NAME=") unsets NAME, so invoke _putenv ("NAME= ")
|
||||
to allocate the environ vector and then replace the new
|
||||
entry with "NAME=". */
|
||||
int putenv_result, putenv_errno;
|
||||
char *name_x = malloc (name_end - string + sizeof "= ");
|
||||
if (!name_x)
|
||||
return -1;
|
||||
memcpy (name_x, string, name_end - string + 1);
|
||||
name_x[name_end - string + 1] = ' ';
|
||||
name_x[name_end - string + 2] = 0;
|
||||
putenv_result = _putenv (name_x);
|
||||
putenv_errno = errno;
|
||||
for (ep = environ; *ep; ep++)
|
||||
if (strcmp (*ep, name_x) == 0)
|
||||
{
|
||||
*ep = string;
|
||||
break;
|
||||
}
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
if (putenv_result == 0)
|
||||
{
|
||||
/* _putenv propagated "NAME= " into the subprocess environment;
|
||||
fix that by calling SetEnvironmentVariable directly. */
|
||||
name_x[name_end - string] = 0;
|
||||
putenv_result = SetEnvironmentVariable (name_x, "") ? 0 : -1;
|
||||
putenv_errno = ENOMEM; /* ENOMEM is the only way to fail. */
|
||||
}
|
||||
# endif
|
||||
free (name_x);
|
||||
__set_errno (putenv_errno);
|
||||
return putenv_result;
|
||||
}
|
||||
#else
|
||||
for (ep = environ; *ep; ep++)
|
||||
if (strncmp (*ep, string, name_end - string) == 0
|
||||
&& (*ep)[name_end - string] == '=')
|
||||
break;
|
||||
|
||||
if (*ep)
|
||||
*ep = string;
|
||||
else
|
||||
{
|
||||
static char **last_environ = NULL;
|
||||
size_t size = ep - environ;
|
||||
char **new_environ = malloc ((size + 2) * sizeof *new_environ);
|
||||
if (! new_environ)
|
||||
return -1;
|
||||
new_environ[0] = string;
|
||||
memcpy (new_environ + 1, environ, (size + 1) * sizeof *new_environ);
|
||||
free (last_environ);
|
||||
last_environ = new_environ;
|
||||
environ = new_environ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/* Determine whether two stat buffers are known to refer to the same file.
|
||||
|
||||
Copyright (C) 2006, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef SAME_INODE_H
|
||||
# define SAME_INODE_H 1
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifdef __VMS
|
||||
# define SAME_INODE(a, b) \
|
||||
((a).st_ino[0] == (b).st_ino[0] \
|
||||
&& (a).st_ino[1] == (b).st_ino[1] \
|
||||
&& (a).st_ino[2] == (b).st_ino[2] \
|
||||
&& (a).st_dev == (b).st_dev)
|
||||
# elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Native Windows. */
|
||||
# if _GL_WINDOWS_STAT_INODES
|
||||
/* stat() and fstat() set st_dev and st_ino to 0 if information about
|
||||
the inode is not available. */
|
||||
# define SAME_INODE(a, b) \
|
||||
(!((a).st_ino == 0 && (a).st_dev == 0) \
|
||||
&& (a).st_ino == (b).st_ino && (a).st_dev == (b).st_dev)
|
||||
# else
|
||||
/* stat() and fstat() set st_ino to 0 always. */
|
||||
# define SAME_INODE(a, b) 0
|
||||
# endif
|
||||
# else
|
||||
# define SAME_INODE(a, b) \
|
||||
((a).st_ino == (b).st_ino \
|
||||
&& (a).st_dev == (b).st_dev)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,579 @@
|
||||
/* Emulation for select(2)
|
||||
Contributed by Paolo Bonzini.
|
||||
|
||||
Copyright 2008-2017 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 General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU 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>
|
||||
|
||||
#if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
#else
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
static BOOL IsConsoleHandle (HANDLE h)
|
||||
{
|
||||
DWORD mode;
|
||||
return GetConsoleMode (h, &mode) != 0;
|
||||
}
|
||||
|
||||
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;
|
||||
clock_t tend;
|
||||
|
||||
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;
|
||||
|
||||
/* When will the waiting period expire? */
|
||||
if (wait_timeout != INFINITE)
|
||||
tend = clock () + wait_timeout;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* How much is left to wait? */
|
||||
if (wait_timeout != INFINITE)
|
||||
{
|
||||
clock_t tnow = clock ();
|
||||
if (tend >= tnow)
|
||||
wait_timeout = tend - tnow;
|
||||
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
|
||||
/* If NHANDLES > 1, but no bits are set, it means we've
|
||||
been told incorrectly that some handle was signaled.
|
||||
This happens with anonymous pipes, which always cause
|
||||
MsgWaitForMultipleObjects to exit immediately, but no
|
||||
data is found ready to be read by windows_poll_handle.
|
||||
To avoid a total failure (whereby we return zero and
|
||||
don't wait at all), let's poll in a more busy loop. */
|
||||
|| (wait_timeout != 0 && nhandles > 1)))
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
if (timeout && wait_timeout == 0 && rc == 0)
|
||||
timeout->tv_sec = timeout->tv_usec = 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -0,0 +1,946 @@
|
||||
/* Set the current locale. -*- coding: utf-8 -*-
|
||||
Copyright (C) 2009, 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Override setlocale() so that when the default locale is requested
|
||||
(locale = ""), the environment variables LC_ALL, LC_*, and LANG are
|
||||
considered.
|
||||
Also include all the functionality from libintl's setlocale() override. */
|
||||
|
||||
/* Please keep this file in sync with
|
||||
gettext/gettext-runtime/intl/setlocale.c ! */
|
||||
|
||||
/* Specification. */
|
||||
#include <locale.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "localename.h"
|
||||
|
||||
#if 1
|
||||
|
||||
# undef setlocale
|
||||
|
||||
/* Return string representation of locale category CATEGORY. */
|
||||
static const char *
|
||||
category_to_name (int category)
|
||||
{
|
||||
const char *retval;
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case LC_COLLATE:
|
||||
retval = "LC_COLLATE";
|
||||
break;
|
||||
case LC_CTYPE:
|
||||
retval = "LC_CTYPE";
|
||||
break;
|
||||
case LC_MONETARY:
|
||||
retval = "LC_MONETARY";
|
||||
break;
|
||||
case LC_NUMERIC:
|
||||
retval = "LC_NUMERIC";
|
||||
break;
|
||||
case LC_TIME:
|
||||
retval = "LC_TIME";
|
||||
break;
|
||||
case LC_MESSAGES:
|
||||
retval = "LC_MESSAGES";
|
||||
break;
|
||||
default:
|
||||
/* If you have a better idea for a default value let me know. */
|
||||
retval = "LC_XXX";
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
|
||||
/* The native Windows setlocale() function expects locale names of the form
|
||||
"German" or "German_Germany" or "DEU", but not "de" or "de_DE". We need
|
||||
to convert the names from the form with ISO 639 language code and ISO 3166
|
||||
country code to the form with English names or with three-letter identifier.
|
||||
The three-letter identifiers known by a Windows XP SP2 or SP3 are:
|
||||
AFK Afrikaans_South Africa.1252
|
||||
ARA Arabic_Saudi Arabia.1256
|
||||
ARB Arabic_Lebanon.1256
|
||||
ARE Arabic_Egypt.1256
|
||||
ARG Arabic_Algeria.1256
|
||||
ARH Arabic_Bahrain.1256
|
||||
ARI Arabic_Iraq.1256
|
||||
ARJ Arabic_Jordan.1256
|
||||
ARK Arabic_Kuwait.1256
|
||||
ARL Arabic_Libya.1256
|
||||
ARM Arabic_Morocco.1256
|
||||
ARO Arabic_Oman.1256
|
||||
ARQ Arabic_Qatar.1256
|
||||
ARS Arabic_Syria.1256
|
||||
ART Arabic_Tunisia.1256
|
||||
ARU Arabic_U.A.E..1256
|
||||
ARY Arabic_Yemen.1256
|
||||
AZE Azeri (Latin)_Azerbaijan.1254
|
||||
BEL Belarusian_Belarus.1251
|
||||
BGR Bulgarian_Bulgaria.1251
|
||||
BSB Bosnian_Bosnia and Herzegovina.1250
|
||||
BSC Bosnian (Cyrillic)_Bosnia and Herzegovina.1250 (wrong encoding!)
|
||||
CAT Catalan_Spain.1252
|
||||
CHH Chinese_Hong Kong S.A.R..950
|
||||
CHI Chinese_Singapore.936
|
||||
CHS Chinese_People's Republic of China.936
|
||||
CHT Chinese_Taiwan.950
|
||||
CSY Czech_Czech Republic.1250
|
||||
CYM Welsh_United Kingdom.1252
|
||||
DAN Danish_Denmark.1252
|
||||
DEA German_Austria.1252
|
||||
DEC German_Liechtenstein.1252
|
||||
DEL German_Luxembourg.1252
|
||||
DES German_Switzerland.1252
|
||||
DEU German_Germany.1252
|
||||
ELL Greek_Greece.1253
|
||||
ENA English_Australia.1252
|
||||
ENB English_Caribbean.1252
|
||||
ENC English_Canada.1252
|
||||
ENG English_United Kingdom.1252
|
||||
ENI English_Ireland.1252
|
||||
ENJ English_Jamaica.1252
|
||||
ENL English_Belize.1252
|
||||
ENP English_Republic of the Philippines.1252
|
||||
ENS English_South Africa.1252
|
||||
ENT English_Trinidad and Tobago.1252
|
||||
ENU English_United States.1252
|
||||
ENW English_Zimbabwe.1252
|
||||
ENZ English_New Zealand.1252
|
||||
ESA Spanish_Panama.1252
|
||||
ESB Spanish_Bolivia.1252
|
||||
ESC Spanish_Costa Rica.1252
|
||||
ESD Spanish_Dominican Republic.1252
|
||||
ESE Spanish_El Salvador.1252
|
||||
ESF Spanish_Ecuador.1252
|
||||
ESG Spanish_Guatemala.1252
|
||||
ESH Spanish_Honduras.1252
|
||||
ESI Spanish_Nicaragua.1252
|
||||
ESL Spanish_Chile.1252
|
||||
ESM Spanish_Mexico.1252
|
||||
ESN Spanish_Spain.1252
|
||||
ESO Spanish_Colombia.1252
|
||||
ESP Spanish_Spain.1252
|
||||
ESR Spanish_Peru.1252
|
||||
ESS Spanish_Argentina.1252
|
||||
ESU Spanish_Puerto Rico.1252
|
||||
ESV Spanish_Venezuela.1252
|
||||
ESY Spanish_Uruguay.1252
|
||||
ESZ Spanish_Paraguay.1252
|
||||
ETI Estonian_Estonia.1257
|
||||
EUQ Basque_Spain.1252
|
||||
FAR Farsi_Iran.1256
|
||||
FIN Finnish_Finland.1252
|
||||
FOS Faroese_Faroe Islands.1252
|
||||
FPO Filipino_Philippines.1252
|
||||
FRA French_France.1252
|
||||
FRB French_Belgium.1252
|
||||
FRC French_Canada.1252
|
||||
FRL French_Luxembourg.1252
|
||||
FRM French_Principality of Monaco.1252
|
||||
FRS French_Switzerland.1252
|
||||
FYN Frisian_Netherlands.1252
|
||||
GLC Galician_Spain.1252
|
||||
HEB Hebrew_Israel.1255
|
||||
HRB Croatian_Bosnia and Herzegovina.1250
|
||||
HRV Croatian_Croatia.1250
|
||||
HUN Hungarian_Hungary.1250
|
||||
IND Indonesian_Indonesia.1252
|
||||
IRE Irish_Ireland.1252
|
||||
ISL Icelandic_Iceland.1252
|
||||
ITA Italian_Italy.1252
|
||||
ITS Italian_Switzerland.1252
|
||||
IUK Inuktitut (Latin)_Canada.1252
|
||||
JPN Japanese_Japan.932
|
||||
KKZ Kazakh_Kazakhstan.1251
|
||||
KOR Korean_Korea.949
|
||||
KYR Kyrgyz_Kyrgyzstan.1251
|
||||
LBX Luxembourgish_Luxembourg.1252
|
||||
LTH Lithuanian_Lithuania.1257
|
||||
LVI Latvian_Latvia.1257
|
||||
MKI FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251
|
||||
MON Mongolian_Mongolia.1251
|
||||
MPD Mapudungun_Chile.1252
|
||||
MSB Malay_Brunei Darussalam.1252
|
||||
MSL Malay_Malaysia.1252
|
||||
MWK Mohawk_Canada.1252
|
||||
NLB Dutch_Belgium.1252
|
||||
NLD Dutch_Netherlands.1252
|
||||
NON Norwegian-Nynorsk_Norway.1252
|
||||
NOR Norwegian (Bokmål)_Norway.1252
|
||||
NSO Northern Sotho_South Africa.1252
|
||||
PLK Polish_Poland.1250
|
||||
PTB Portuguese_Brazil.1252
|
||||
PTG Portuguese_Portugal.1252
|
||||
QUB Quechua_Bolivia.1252
|
||||
QUE Quechua_Ecuador.1252
|
||||
QUP Quechua_Peru.1252
|
||||
RMC Romansh_Switzerland.1252
|
||||
ROM Romanian_Romania.1250
|
||||
RUS Russian_Russia.1251
|
||||
SKY Slovak_Slovakia.1250
|
||||
SLV Slovenian_Slovenia.1250
|
||||
SMA Sami (Southern)_Norway.1252
|
||||
SMB Sami (Southern)_Sweden.1252
|
||||
SME Sami (Northern)_Norway.1252
|
||||
SMF Sami (Northern)_Sweden.1252
|
||||
SMG Sami (Northern)_Finland.1252
|
||||
SMJ Sami (Lule)_Norway.1252
|
||||
SMK Sami (Lule)_Sweden.1252
|
||||
SMN Sami (Inari)_Finland.1252
|
||||
SMS Sami (Skolt)_Finland.1252
|
||||
SQI Albanian_Albania.1250
|
||||
SRB Serbian (Cyrillic)_Serbia and Montenegro.1251
|
||||
SRL Serbian (Latin)_Serbia and Montenegro.1250
|
||||
SRN Serbian (Cyrillic)_Bosnia and Herzegovina.1251
|
||||
SRS Serbian (Latin)_Bosnia and Herzegovina.1250
|
||||
SVE Swedish_Sweden.1252
|
||||
SVF Swedish_Finland.1252
|
||||
SWK Swahili_Kenya.1252
|
||||
THA Thai_Thailand.874
|
||||
TRK Turkish_Turkey.1254
|
||||
TSN Tswana_South Africa.1252
|
||||
TTT Tatar_Russia.1251
|
||||
UKR Ukrainian_Ukraine.1251
|
||||
URD Urdu_Islamic Republic of Pakistan.1256
|
||||
USA English_United States.1252
|
||||
UZB Uzbek (Latin)_Uzbekistan.1254
|
||||
VIT Vietnamese_Viet Nam.1258
|
||||
XHO Xhosa_South Africa.1252
|
||||
ZHH Chinese_Hong Kong S.A.R..950
|
||||
ZHI Chinese_Singapore.936
|
||||
ZHM Chinese_Macau S.A.R..950
|
||||
ZUL Zulu_South Africa.1252
|
||||
*/
|
||||
|
||||
/* Table from ISO 639 language code, optionally with country or script suffix,
|
||||
to English name.
|
||||
Keep in sync with the gl_locale_name_from_win32_LANGID function in
|
||||
localename.c! */
|
||||
struct table_entry
|
||||
{
|
||||
const char *code;
|
||||
const char *english;
|
||||
};
|
||||
static const struct table_entry language_table[] =
|
||||
{
|
||||
{ "af", "Afrikaans" },
|
||||
{ "am", "Amharic" },
|
||||
{ "ar", "Arabic" },
|
||||
{ "arn", "Mapudungun" },
|
||||
{ "as", "Assamese" },
|
||||
{ "az@cyrillic", "Azeri (Cyrillic)" },
|
||||
{ "az@latin", "Azeri (Latin)" },
|
||||
{ "ba", "Bashkir" },
|
||||
{ "be", "Belarusian" },
|
||||
{ "ber", "Tamazight" },
|
||||
{ "ber@arabic", "Tamazight (Arabic)" },
|
||||
{ "ber@latin", "Tamazight (Latin)" },
|
||||
{ "bg", "Bulgarian" },
|
||||
{ "bin", "Edo" },
|
||||
{ "bn", "Bengali" },
|
||||
{ "bn_BD", "Bengali (Bangladesh)" },
|
||||
{ "bn_IN", "Bengali (India)" },
|
||||
{ "bnt", "Sutu" },
|
||||
{ "bo", "Tibetan" },
|
||||
{ "br", "Breton" },
|
||||
{ "bs", "BSB" }, /* "Bosnian (Latin)" */
|
||||
{ "bs@cyrillic", "BSC" }, /* Bosnian (Cyrillic) */
|
||||
{ "ca", "Catalan" },
|
||||
{ "chr", "Cherokee" },
|
||||
{ "co", "Corsican" },
|
||||
{ "cpe", "Hawaiian" },
|
||||
{ "cs", "Czech" },
|
||||
{ "cy", "Welsh" },
|
||||
{ "da", "Danish" },
|
||||
{ "de", "German" },
|
||||
{ "dsb", "Lower Sorbian" },
|
||||
{ "dv", "Divehi" },
|
||||
{ "el", "Greek" },
|
||||
{ "en", "English" },
|
||||
{ "es", "Spanish" },
|
||||
{ "et", "Estonian" },
|
||||
{ "eu", "Basque" },
|
||||
{ "fa", "Farsi" },
|
||||
{ "ff", "Fulfulde" },
|
||||
{ "fi", "Finnish" },
|
||||
{ "fo", "Faroese" }, /* "Faeroese" does not work */
|
||||
{ "fr", "French" },
|
||||
{ "fy", "Frisian" },
|
||||
{ "ga", "IRE" }, /* Gaelic (Ireland) */
|
||||
{ "gd", "Gaelic (Scotland)" },
|
||||
{ "gd", "Scottish Gaelic" },
|
||||
{ "gl", "Galician" },
|
||||
{ "gn", "Guarani" },
|
||||
{ "gsw", "Alsatian" },
|
||||
{ "gu", "Gujarati" },
|
||||
{ "ha", "Hausa" },
|
||||
{ "he", "Hebrew" },
|
||||
{ "hi", "Hindi" },
|
||||
{ "hr", "Croatian" },
|
||||
{ "hsb", "Upper Sorbian" },
|
||||
{ "hu", "Hungarian" },
|
||||
{ "hy", "Armenian" },
|
||||
{ "id", "Indonesian" },
|
||||
{ "ig", "Igbo" },
|
||||
{ "ii", "Yi" },
|
||||
{ "is", "Icelandic" },
|
||||
{ "it", "Italian" },
|
||||
{ "iu", "IUK" }, /* Inuktitut */
|
||||
{ "ja", "Japanese" },
|
||||
{ "ka", "Georgian" },
|
||||
{ "kk", "Kazakh" },
|
||||
{ "kl", "Greenlandic" },
|
||||
{ "km", "Cambodian" },
|
||||
{ "km", "Khmer" },
|
||||
{ "kn", "Kannada" },
|
||||
{ "ko", "Korean" },
|
||||
{ "kok", "Konkani" },
|
||||
{ "kr", "Kanuri" },
|
||||
{ "ks", "Kashmiri" },
|
||||
{ "ks_IN", "Kashmiri_India" },
|
||||
{ "ks_PK", "Kashmiri (Arabic)_Pakistan" },
|
||||
{ "ky", "Kyrgyz" },
|
||||
{ "la", "Latin" },
|
||||
{ "lb", "Luxembourgish" },
|
||||
{ "lo", "Lao" },
|
||||
{ "lt", "Lithuanian" },
|
||||
{ "lv", "Latvian" },
|
||||
{ "mi", "Maori" },
|
||||
{ "mk", "FYRO Macedonian" },
|
||||
{ "mk", "Macedonian" },
|
||||
{ "ml", "Malayalam" },
|
||||
{ "mn", "Mongolian" },
|
||||
{ "mni", "Manipuri" },
|
||||
{ "moh", "Mohawk" },
|
||||
{ "mr", "Marathi" },
|
||||
{ "ms", "Malay" },
|
||||
{ "mt", "Maltese" },
|
||||
{ "my", "Burmese" },
|
||||
{ "nb", "NOR" }, /* Norwegian Bokmål */
|
||||
{ "ne", "Nepali" },
|
||||
{ "nic", "Ibibio" },
|
||||
{ "nl", "Dutch" },
|
||||
{ "nn", "NON" }, /* Norwegian Nynorsk */
|
||||
{ "no", "Norwegian" },
|
||||
{ "nso", "Northern Sotho" },
|
||||
{ "nso", "Sepedi" },
|
||||
{ "oc", "Occitan" },
|
||||
{ "om", "Oromo" },
|
||||
{ "or", "Oriya" },
|
||||
{ "pa", "Punjabi" },
|
||||
{ "pap", "Papiamentu" },
|
||||
{ "pl", "Polish" },
|
||||
{ "prs", "Dari" },
|
||||
{ "ps", "Pashto" },
|
||||
{ "pt", "Portuguese" },
|
||||
{ "qu", "Quechua" },
|
||||
{ "qut", "K'iche'" },
|
||||
{ "rm", "Romansh" },
|
||||
{ "ro", "Romanian" },
|
||||
{ "ru", "Russian" },
|
||||
{ "rw", "Kinyarwanda" },
|
||||
{ "sa", "Sanskrit" },
|
||||
{ "sah", "Yakut" },
|
||||
{ "sd", "Sindhi" },
|
||||
{ "se", "Sami (Northern)" },
|
||||
{ "se", "Northern Sami" },
|
||||
{ "si", "Sinhalese" },
|
||||
{ "sk", "Slovak" },
|
||||
{ "sl", "Slovenian" },
|
||||
{ "sma", "Sami (Southern)" },
|
||||
{ "sma", "Southern Sami" },
|
||||
{ "smj", "Sami (Lule)" },
|
||||
{ "smj", "Lule Sami" },
|
||||
{ "smn", "Sami (Inari)" },
|
||||
{ "smn", "Inari Sami" },
|
||||
{ "sms", "Sami (Skolt)" },
|
||||
{ "sms", "Skolt Sami" },
|
||||
{ "so", "Somali" },
|
||||
{ "sq", "Albanian" },
|
||||
{ "sr", "Serbian (Latin)" },
|
||||
{ "sr@cyrillic", "SRB" }, /* Serbian (Cyrillic) */
|
||||
{ "sv", "Swedish" },
|
||||
{ "sw", "Swahili" },
|
||||
{ "syr", "Syriac" },
|
||||
{ "ta", "Tamil" },
|
||||
{ "te", "Telugu" },
|
||||
{ "tg", "Tajik" },
|
||||
{ "th", "Thai" },
|
||||
{ "ti", "Tigrinya" },
|
||||
{ "tk", "Turkmen" },
|
||||
{ "tl", "Filipino" },
|
||||
{ "tn", "Tswana" },
|
||||
{ "tr", "Turkish" },
|
||||
{ "ts", "Tsonga" },
|
||||
{ "tt", "Tatar" },
|
||||
{ "ug", "Uighur" },
|
||||
{ "uk", "Ukrainian" },
|
||||
{ "ur", "Urdu" },
|
||||
{ "uz", "Uzbek" },
|
||||
{ "uz", "Uzbek (Latin)" },
|
||||
{ "uz@cyrillic", "Uzbek (Cyrillic)" },
|
||||
{ "ve", "Venda" },
|
||||
{ "vi", "Vietnamese" },
|
||||
{ "wen", "Sorbian" },
|
||||
{ "wo", "Wolof" },
|
||||
{ "xh", "Xhosa" },
|
||||
{ "yi", "Yiddish" },
|
||||
{ "yo", "Yoruba" },
|
||||
{ "zh", "Chinese" },
|
||||
{ "zu", "Zulu" }
|
||||
};
|
||||
|
||||
/* Table from ISO 3166 country code to English name.
|
||||
Keep in sync with the gl_locale_name_from_win32_LANGID function in
|
||||
localename.c! */
|
||||
static const struct table_entry country_table[] =
|
||||
{
|
||||
{ "AE", "U.A.E." },
|
||||
{ "AF", "Afghanistan" },
|
||||
{ "AL", "Albania" },
|
||||
{ "AM", "Armenia" },
|
||||
{ "AN", "Netherlands Antilles" },
|
||||
{ "AR", "Argentina" },
|
||||
{ "AT", "Austria" },
|
||||
{ "AU", "Australia" },
|
||||
{ "AZ", "Azerbaijan" },
|
||||
{ "BA", "Bosnia and Herzegovina" },
|
||||
{ "BD", "Bangladesh" },
|
||||
{ "BE", "Belgium" },
|
||||
{ "BG", "Bulgaria" },
|
||||
{ "BH", "Bahrain" },
|
||||
{ "BN", "Brunei Darussalam" },
|
||||
{ "BO", "Bolivia" },
|
||||
{ "BR", "Brazil" },
|
||||
{ "BT", "Bhutan" },
|
||||
{ "BY", "Belarus" },
|
||||
{ "BZ", "Belize" },
|
||||
{ "CA", "Canada" },
|
||||
{ "CG", "Congo" },
|
||||
{ "CH", "Switzerland" },
|
||||
{ "CI", "Cote d'Ivoire" },
|
||||
{ "CL", "Chile" },
|
||||
{ "CM", "Cameroon" },
|
||||
{ "CN", "People's Republic of China" },
|
||||
{ "CO", "Colombia" },
|
||||
{ "CR", "Costa Rica" },
|
||||
{ "CS", "Serbia and Montenegro" },
|
||||
{ "CZ", "Czech Republic" },
|
||||
{ "DE", "Germany" },
|
||||
{ "DK", "Denmark" },
|
||||
{ "DO", "Dominican Republic" },
|
||||
{ "DZ", "Algeria" },
|
||||
{ "EC", "Ecuador" },
|
||||
{ "EE", "Estonia" },
|
||||
{ "EG", "Egypt" },
|
||||
{ "ER", "Eritrea" },
|
||||
{ "ES", "Spain" },
|
||||
{ "ET", "Ethiopia" },
|
||||
{ "FI", "Finland" },
|
||||
{ "FO", "Faroe Islands" },
|
||||
{ "FR", "France" },
|
||||
{ "GB", "United Kingdom" },
|
||||
{ "GD", "Caribbean" },
|
||||
{ "GE", "Georgia" },
|
||||
{ "GL", "Greenland" },
|
||||
{ "GR", "Greece" },
|
||||
{ "GT", "Guatemala" },
|
||||
{ "HK", "Hong Kong" },
|
||||
{ "HK", "Hong Kong S.A.R." },
|
||||
{ "HN", "Honduras" },
|
||||
{ "HR", "Croatia" },
|
||||
{ "HT", "Haiti" },
|
||||
{ "HU", "Hungary" },
|
||||
{ "ID", "Indonesia" },
|
||||
{ "IE", "Ireland" },
|
||||
{ "IL", "Israel" },
|
||||
{ "IN", "India" },
|
||||
{ "IQ", "Iraq" },
|
||||
{ "IR", "Iran" },
|
||||
{ "IS", "Iceland" },
|
||||
{ "IT", "Italy" },
|
||||
{ "JM", "Jamaica" },
|
||||
{ "JO", "Jordan" },
|
||||
{ "JP", "Japan" },
|
||||
{ "KE", "Kenya" },
|
||||
{ "KG", "Kyrgyzstan" },
|
||||
{ "KH", "Cambodia" },
|
||||
{ "KR", "South Korea" },
|
||||
{ "KW", "Kuwait" },
|
||||
{ "KZ", "Kazakhstan" },
|
||||
{ "LA", "Laos" },
|
||||
{ "LB", "Lebanon" },
|
||||
{ "LI", "Liechtenstein" },
|
||||
{ "LK", "Sri Lanka" },
|
||||
{ "LT", "Lithuania" },
|
||||
{ "LU", "Luxembourg" },
|
||||
{ "LV", "Latvia" },
|
||||
{ "LY", "Libya" },
|
||||
{ "MA", "Morocco" },
|
||||
{ "MC", "Principality of Monaco" },
|
||||
{ "MD", "Moldava" },
|
||||
{ "MD", "Moldova" },
|
||||
{ "ME", "Montenegro" },
|
||||
{ "MK", "Former Yugoslav Republic of Macedonia" },
|
||||
{ "ML", "Mali" },
|
||||
{ "MM", "Myanmar" },
|
||||
{ "MN", "Mongolia" },
|
||||
{ "MO", "Macau S.A.R." },
|
||||
{ "MT", "Malta" },
|
||||
{ "MV", "Maldives" },
|
||||
{ "MX", "Mexico" },
|
||||
{ "MY", "Malaysia" },
|
||||
{ "NG", "Nigeria" },
|
||||
{ "NI", "Nicaragua" },
|
||||
{ "NL", "Netherlands" },
|
||||
{ "NO", "Norway" },
|
||||
{ "NP", "Nepal" },
|
||||
{ "NZ", "New Zealand" },
|
||||
{ "OM", "Oman" },
|
||||
{ "PA", "Panama" },
|
||||
{ "PE", "Peru" },
|
||||
{ "PH", "Philippines" },
|
||||
{ "PK", "Islamic Republic of Pakistan" },
|
||||
{ "PL", "Poland" },
|
||||
{ "PR", "Puerto Rico" },
|
||||
{ "PT", "Portugal" },
|
||||
{ "PY", "Paraguay" },
|
||||
{ "QA", "Qatar" },
|
||||
{ "RE", "Reunion" },
|
||||
{ "RO", "Romania" },
|
||||
{ "RS", "Serbia" },
|
||||
{ "RU", "Russia" },
|
||||
{ "RW", "Rwanda" },
|
||||
{ "SA", "Saudi Arabia" },
|
||||
{ "SE", "Sweden" },
|
||||
{ "SG", "Singapore" },
|
||||
{ "SI", "Slovenia" },
|
||||
{ "SK", "Slovak" },
|
||||
{ "SN", "Senegal" },
|
||||
{ "SO", "Somalia" },
|
||||
{ "SR", "Suriname" },
|
||||
{ "SV", "El Salvador" },
|
||||
{ "SY", "Syria" },
|
||||
{ "TH", "Thailand" },
|
||||
{ "TJ", "Tajikistan" },
|
||||
{ "TM", "Turkmenistan" },
|
||||
{ "TN", "Tunisia" },
|
||||
{ "TR", "Turkey" },
|
||||
{ "TT", "Trinidad and Tobago" },
|
||||
{ "TW", "Taiwan" },
|
||||
{ "TZ", "Tanzania" },
|
||||
{ "UA", "Ukraine" },
|
||||
{ "US", "United States" },
|
||||
{ "UY", "Uruguay" },
|
||||
{ "VA", "Vatican" },
|
||||
{ "VE", "Venezuela" },
|
||||
{ "VN", "Viet Nam" },
|
||||
{ "YE", "Yemen" },
|
||||
{ "ZA", "South Africa" },
|
||||
{ "ZW", "Zimbabwe" }
|
||||
};
|
||||
|
||||
/* Given a string STRING, find the set of indices i such that TABLE[i].code is
|
||||
the given STRING. It is a range [lo,hi-1]. */
|
||||
typedef struct { size_t lo; size_t hi; } range_t;
|
||||
static void
|
||||
search (const struct table_entry *table, size_t table_size, const char *string,
|
||||
range_t *result)
|
||||
{
|
||||
/* The table is sorted. Perform a binary search. */
|
||||
size_t hi = table_size;
|
||||
size_t lo = 0;
|
||||
while (lo < hi)
|
||||
{
|
||||
/* Invariant:
|
||||
for i < lo, strcmp (table[i].code, string) < 0,
|
||||
for i >= hi, strcmp (table[i].code, string) > 0. */
|
||||
size_t mid = (hi + lo) >> 1; /* >= lo, < hi */
|
||||
int cmp = strcmp (table[mid].code, string);
|
||||
if (cmp < 0)
|
||||
lo = mid + 1;
|
||||
else if (cmp > 0)
|
||||
hi = mid;
|
||||
else
|
||||
{
|
||||
/* Found an i with
|
||||
strcmp (language_table[i].code, string) == 0.
|
||||
Find the entire interval of such i. */
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = mid; i > lo; )
|
||||
{
|
||||
i--;
|
||||
if (strcmp (table[i].code, string) < 0)
|
||||
{
|
||||
lo = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = mid; i < hi; i++)
|
||||
{
|
||||
if (strcmp (table[i].code, string) > 0)
|
||||
{
|
||||
hi = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* The set of i with
|
||||
strcmp (language_table[i].code, string) == 0
|
||||
is the interval [lo, hi-1]. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
result->lo = lo;
|
||||
result->hi = hi;
|
||||
}
|
||||
|
||||
/* Like setlocale, but accept also locale names in the form ll or ll_CC,
|
||||
where ll is an ISO 639 language code and CC is an ISO 3166 country code. */
|
||||
static char *
|
||||
setlocale_unixlike (int category, const char *locale)
|
||||
{
|
||||
char *result;
|
||||
char llCC_buf[64];
|
||||
char ll_buf[64];
|
||||
char CC_buf[64];
|
||||
|
||||
/* The native Windows implementation of setlocale understands the special
|
||||
locale name "C", but not "POSIX". Therefore map "POSIX" to "C". */
|
||||
#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
|
||||
if (locale != NULL && strcmp (locale, "POSIX") == 0)
|
||||
locale = "C";
|
||||
#endif
|
||||
|
||||
/* First, try setlocale with the original argument unchanged. */
|
||||
result = setlocale (category, locale);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
|
||||
/* Otherwise, assume the argument is in the form
|
||||
language[_territory][.codeset][@modifier]
|
||||
and try to map it using the tables. */
|
||||
if (strlen (locale) < sizeof (llCC_buf))
|
||||
{
|
||||
/* Second try: Remove the codeset part. */
|
||||
{
|
||||
const char *p = locale;
|
||||
char *q = llCC_buf;
|
||||
|
||||
/* Copy the part before the dot. */
|
||||
for (; *p != '\0' && *p != '.'; p++, q++)
|
||||
*q = *p;
|
||||
if (*p == '.')
|
||||
/* Skip the part up to the '@', if any. */
|
||||
for (; *p != '\0' && *p != '@'; p++)
|
||||
;
|
||||
/* Copy the part starting with '@', if any. */
|
||||
for (; *p != '\0'; p++, q++)
|
||||
*q = *p;
|
||||
*q = '\0';
|
||||
}
|
||||
/* llCC_buf now contains
|
||||
language[_territory][@modifier]
|
||||
*/
|
||||
if (strcmp (llCC_buf, locale) != 0)
|
||||
{
|
||||
result = setlocale (category, llCC_buf);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
/* Look it up in language_table. */
|
||||
{
|
||||
range_t range;
|
||||
size_t i;
|
||||
|
||||
search (language_table,
|
||||
sizeof (language_table) / sizeof (language_table[0]),
|
||||
llCC_buf,
|
||||
&range);
|
||||
|
||||
for (i = range.lo; i < range.hi; i++)
|
||||
{
|
||||
/* Try the replacement in language_table[i]. */
|
||||
result = setlocale (category, language_table[i].english);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/* Split language[_territory][@modifier]
|
||||
into ll_buf = language[@modifier]
|
||||
and CC_buf = territory
|
||||
*/
|
||||
{
|
||||
const char *underscore = strchr (llCC_buf, '_');
|
||||
if (underscore != NULL)
|
||||
{
|
||||
const char *territory_start = underscore + 1;
|
||||
const char *territory_end = strchr (territory_start, '@');
|
||||
if (territory_end == NULL)
|
||||
territory_end = territory_start + strlen (territory_start);
|
||||
|
||||
memcpy (ll_buf, llCC_buf, underscore - llCC_buf);
|
||||
strcpy (ll_buf + (underscore - llCC_buf), territory_end);
|
||||
|
||||
memcpy (CC_buf, territory_start, territory_end - territory_start);
|
||||
CC_buf[territory_end - territory_start] = '\0';
|
||||
|
||||
{
|
||||
/* Look up ll_buf in language_table
|
||||
and CC_buf in country_table. */
|
||||
range_t language_range;
|
||||
|
||||
search (language_table,
|
||||
sizeof (language_table) / sizeof (language_table[0]),
|
||||
ll_buf,
|
||||
&language_range);
|
||||
if (language_range.lo < language_range.hi)
|
||||
{
|
||||
range_t country_range;
|
||||
|
||||
search (country_table,
|
||||
sizeof (country_table) / sizeof (country_table[0]),
|
||||
CC_buf,
|
||||
&country_range);
|
||||
if (country_range.lo < country_range.hi)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
for (i = language_range.lo; i < language_range.hi; i++)
|
||||
for (j = country_range.lo; j < country_range.hi; j++)
|
||||
{
|
||||
/* Concatenate the replacements. */
|
||||
const char *part1 = language_table[i].english;
|
||||
size_t part1_len = strlen (part1);
|
||||
const char *part2 = country_table[j].english;
|
||||
size_t part2_len = strlen (part2) + 1;
|
||||
char buf[64+64];
|
||||
|
||||
if (!(part1_len + 1 + part2_len <= sizeof (buf)))
|
||||
abort ();
|
||||
memcpy (buf, part1, part1_len);
|
||||
buf[part1_len] = '_';
|
||||
memcpy (buf + part1_len + 1, part2, part2_len);
|
||||
|
||||
/* Try the concatenated replacements. */
|
||||
result = setlocale (category, buf);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try omitting the country entirely. This may set a locale
|
||||
corresponding to the wrong country, but is better than
|
||||
failing entirely. */
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = language_range.lo; i < language_range.hi; i++)
|
||||
{
|
||||
/* Try only the language replacement. */
|
||||
result =
|
||||
setlocale (category, language_table[i].english);
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Failed. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
# else
|
||||
# define setlocale_unixlike setlocale
|
||||
# endif
|
||||
|
||||
# if LC_MESSAGES == 1729
|
||||
|
||||
/* The system does not store an LC_MESSAGES locale category. Do it here. */
|
||||
static char lc_messages_name[64] = "C";
|
||||
|
||||
/* Like setlocale, but support also LC_MESSAGES. */
|
||||
static char *
|
||||
setlocale_single (int category, const char *locale)
|
||||
{
|
||||
if (category == LC_MESSAGES)
|
||||
{
|
||||
if (locale != NULL)
|
||||
{
|
||||
lc_messages_name[sizeof (lc_messages_name) - 1] = '\0';
|
||||
strncpy (lc_messages_name, locale, sizeof (lc_messages_name) - 1);
|
||||
}
|
||||
return lc_messages_name;
|
||||
}
|
||||
else
|
||||
return setlocale_unixlike (category, locale);
|
||||
}
|
||||
|
||||
# else
|
||||
# define setlocale_single setlocale_unixlike
|
||||
# endif
|
||||
|
||||
char *
|
||||
rpl_setlocale (int category, const char *locale)
|
||||
{
|
||||
if (locale != NULL && locale[0] == '\0')
|
||||
{
|
||||
/* A request to the set the current locale to the default locale. */
|
||||
if (category == LC_ALL)
|
||||
{
|
||||
/* Set LC_CTYPE first. Then the other categories. */
|
||||
static int const categories[] =
|
||||
{
|
||||
LC_NUMERIC,
|
||||
LC_TIME,
|
||||
LC_COLLATE,
|
||||
LC_MONETARY,
|
||||
LC_MESSAGES
|
||||
};
|
||||
char *saved_locale;
|
||||
const char *base_name;
|
||||
unsigned int i;
|
||||
|
||||
/* Back up the old locale, in case one of the steps fails. */
|
||||
saved_locale = setlocale (LC_ALL, NULL);
|
||||
if (saved_locale == NULL)
|
||||
return NULL;
|
||||
saved_locale = strdup (saved_locale);
|
||||
if (saved_locale == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Set LC_CTYPE category. Set all other categories (except possibly
|
||||
LC_MESSAGES) to the same value in the same call; this is likely to
|
||||
save calls. */
|
||||
base_name =
|
||||
gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
|
||||
if (base_name == NULL)
|
||||
base_name = gl_locale_name_default ();
|
||||
|
||||
if (setlocale_unixlike (LC_ALL, base_name) == NULL)
|
||||
goto fail;
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On native Windows, setlocale(LC_ALL,...) may succeed but set the
|
||||
LC_CTYPE category to an invalid value ("C") when it does not
|
||||
support the specified encoding. Report a failure instead. */
|
||||
if (strchr (base_name, '.') != NULL
|
||||
&& strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
|
||||
goto fail;
|
||||
# endif
|
||||
|
||||
for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++)
|
||||
{
|
||||
int cat = categories[i];
|
||||
const char *name;
|
||||
|
||||
name = gl_locale_name_environ (cat, category_to_name (cat));
|
||||
if (name == NULL)
|
||||
name = gl_locale_name_default ();
|
||||
|
||||
/* If name is the same as base_name, it has already been set
|
||||
through the setlocale call before the loop. */
|
||||
if (strcmp (name, base_name) != 0
|
||||
# if LC_MESSAGES == 1729
|
||||
|| cat == LC_MESSAGES
|
||||
# endif
|
||||
)
|
||||
if (setlocale_single (cat, name) == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* All steps were successful. */
|
||||
free (saved_locale);
|
||||
return setlocale (LC_ALL, NULL);
|
||||
|
||||
fail:
|
||||
if (saved_locale[0] != '\0') /* don't risk an endless recursion */
|
||||
setlocale (LC_ALL, saved_locale);
|
||||
free (saved_locale);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *name =
|
||||
gl_locale_name_environ (category, category_to_name (category));
|
||||
if (name == NULL)
|
||||
name = gl_locale_name_default ();
|
||||
|
||||
return setlocale_single (category, name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
if (category == LC_ALL && locale != NULL && strchr (locale, '.') != NULL)
|
||||
{
|
||||
char *saved_locale;
|
||||
|
||||
/* Back up the old locale. */
|
||||
saved_locale = setlocale (LC_ALL, NULL);
|
||||
if (saved_locale == NULL)
|
||||
return NULL;
|
||||
saved_locale = strdup (saved_locale);
|
||||
if (saved_locale == NULL)
|
||||
return NULL;
|
||||
|
||||
if (setlocale_unixlike (LC_ALL, locale) == NULL)
|
||||
{
|
||||
free (saved_locale);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* On native Windows, setlocale(LC_ALL,...) may succeed but set the
|
||||
LC_CTYPE category to an invalid value ("C") when it does not
|
||||
support the specified encoding. Report a failure instead. */
|
||||
if (strcmp (setlocale (LC_CTYPE, NULL), "C") == 0)
|
||||
{
|
||||
if (saved_locale[0] != '\0') /* don't risk an endless recursion */
|
||||
setlocale (LC_ALL, saved_locale);
|
||||
free (saved_locale);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* It was really successful. */
|
||||
free (saved_locale);
|
||||
return setlocale (LC_ALL, NULL);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
return setlocale_single (category, locale);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/* setsockopt.c --- wrappers for Windows setsockopt function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* Get winsock2.h. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Get struct timeval. */
|
||||
#include <sys/time.h>
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
#include "w32sock.h"
|
||||
|
||||
#undef setsockopt
|
||||
|
||||
int
|
||||
rpl_setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
SOCKET sock = FD_TO_SOCKET (fd);
|
||||
int r;
|
||||
|
||||
if (sock == INVALID_SOCKET)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (level == SOL_SOCKET
|
||||
&& (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO))
|
||||
{
|
||||
const struct timeval *tv = optval;
|
||||
int milliseconds = tv->tv_sec * 1000 + tv->tv_usec / 1000;
|
||||
optval = &milliseconds;
|
||||
r = setsockopt (sock, level, optname, optval, sizeof (int));
|
||||
}
|
||||
else
|
||||
{
|
||||
r = setsockopt (sock, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
set_winsock_errno ();
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Macro for checking that a function declaration is compliant.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef SIGNATURE_CHECK
|
||||
|
||||
/* Check that the function FN takes the specified arguments ARGS with
|
||||
a return type of RET. This header is designed to be included after
|
||||
<config.h> and the one system header that is supposed to contain
|
||||
the function being checked, but prior to any other system headers
|
||||
that are necessary for the unit test. Therefore, this file does
|
||||
not include any system headers, nor reference anything outside of
|
||||
the macro arguments. For an example, if foo.h should provide:
|
||||
|
||||
extern int foo (char, float);
|
||||
|
||||
then the unit test named test-foo.c would start out with:
|
||||
|
||||
#include <config.h>
|
||||
#include <foo.h>
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (foo, int, (char, float));
|
||||
#include <other.h>
|
||||
...
|
||||
*/
|
||||
# define SIGNATURE_CHECK(fn, ret, args) \
|
||||
SIGNATURE_CHECK1 (fn, ret, args, __LINE__)
|
||||
|
||||
/* Necessary to allow multiple SIGNATURE_CHECK lines in a unit test.
|
||||
Note that the checks must not occupy the same line. */
|
||||
# define SIGNATURE_CHECK1(fn, ret, args, id) \
|
||||
SIGNATURE_CHECK2 (fn, ret, args, id) /* macroexpand line */
|
||||
# define SIGNATURE_CHECK2(fn, ret, args, id) \
|
||||
static ret (* _GL_UNUSED signature_check ## id) args = fn
|
||||
|
||||
#endif /* SIGNATURE_CHECK */
|
||||
@@ -0,0 +1,76 @@
|
||||
/* Pausing execution of the current thread.
|
||||
Copyright (C) 2007, 2009-2017 Free Software Foundation, Inc.
|
||||
Written by Bruno Haible <bruno@clisp.org>, 2007.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "verify.h"
|
||||
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN /* avoid including junk */
|
||||
# include <windows.h>
|
||||
|
||||
unsigned int
|
||||
sleep (unsigned int seconds)
|
||||
{
|
||||
unsigned int remaining;
|
||||
|
||||
/* Sleep for 1 second many times, because
|
||||
1. Sleep is not interruptible by Ctrl-C,
|
||||
2. we want to avoid arithmetic overflow while multiplying with 1000. */
|
||||
for (remaining = seconds; remaining > 0; remaining--)
|
||||
Sleep (1000);
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
#elif HAVE_SLEEP
|
||||
|
||||
# undef sleep
|
||||
|
||||
/* Guarantee unlimited sleep and a reasonable return value. Cygwin
|
||||
1.5.x rejects attempts to sleep more than 49.7 days (2**32
|
||||
milliseconds), but uses uninitialized memory which results in a
|
||||
garbage answer. Similarly, Linux 2.6.9 with glibc 2.3.4 has a too
|
||||
small return value when asked to sleep more than 24.85 days. */
|
||||
unsigned int
|
||||
rpl_sleep (unsigned int seconds)
|
||||
{
|
||||
/* This requires int larger than 16 bits. */
|
||||
verify (UINT_MAX / 24 / 24 / 60 / 60);
|
||||
const unsigned int limit = 24 * 24 * 60 * 60;
|
||||
while (limit < seconds)
|
||||
{
|
||||
unsigned int result;
|
||||
seconds -= limit;
|
||||
result = sleep (limit);
|
||||
if (result)
|
||||
return seconds + result;
|
||||
}
|
||||
return sleep (seconds);
|
||||
}
|
||||
|
||||
#else /* !HAVE_SLEEP */
|
||||
|
||||
#error "Please port gnulib sleep.c to your platform, possibly using usleep() or select(), then report this to bug-gnulib."
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
/* Formatted output to strings.
|
||||
Copyright (C) 2004, 2006-2017 Free Software Foundation, Inc.
|
||||
Written by Simon Josefsson and Paul Eggert.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vasnprintf.h"
|
||||
|
||||
/* Print formatted output to string STR. Similar to sprintf, but
|
||||
additional length SIZE limit how much is written into STR. Returns
|
||||
string length of formatted string (which may be larger than SIZE).
|
||||
STR may be NULL, in which case nothing will be written. On error,
|
||||
return a negative value. */
|
||||
int
|
||||
snprintf (char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
char *output;
|
||||
size_t len;
|
||||
size_t lenbuf = size;
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
output = vasnprintf (str, &lenbuf, format, args);
|
||||
len = lenbuf;
|
||||
va_end (args);
|
||||
|
||||
if (!output)
|
||||
return -1;
|
||||
|
||||
if (output != str)
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
size_t pruned_len = (len < size ? len : size - 1);
|
||||
memcpy (str, output, pruned_len);
|
||||
str[pruned_len] = '\0';
|
||||
}
|
||||
|
||||
free (output);
|
||||
}
|
||||
|
||||
if (INT_MAX < len)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* socket.c --- wrappers for Windows socket function
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paolo Bonzini */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
/* Get winsock2.h. */
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
#include "w32sock.h"
|
||||
|
||||
#include "sockets.h"
|
||||
|
||||
int
|
||||
rpl_socket (int domain, int type, int protocol)
|
||||
{
|
||||
SOCKET fh;
|
||||
|
||||
gl_sockets_startup (SOCKETS_1_1);
|
||||
|
||||
/* We have to use WSASocket() to create non-overlapped IO sockets.
|
||||
Overlapped IO sockets cannot be used with read/write. */
|
||||
fh = WSASocket (domain, type, protocol, NULL, 0, 0);
|
||||
|
||||
if (fh == INVALID_SOCKET)
|
||||
{
|
||||
set_winsock_errno ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return SOCKET_TO_FD (fh);
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
/* sockets.c --- wrappers for Windows socket functions
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Simon Josefsson */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "sockets.h"
|
||||
|
||||
#if WINDOWS_SOCKETS
|
||||
|
||||
/* This includes winsock2.h on MinGW. */
|
||||
# include <sys/socket.h>
|
||||
|
||||
# include "fd-hook.h"
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
/* Get set_winsock_errno, FD_TO_SOCKET etc. */
|
||||
# include "w32sock.h"
|
||||
|
||||
static int
|
||||
close_fd_maybe_socket (const struct fd_hook *remaining_list,
|
||||
gl_close_fn primary,
|
||||
int fd)
|
||||
{
|
||||
/* Note about multithread-safety: There is a race condition where, between
|
||||
our calls to closesocket() and the primary close(), some other thread
|
||||
could make system calls that allocate precisely the same HANDLE value
|
||||
as sock; then the primary close() would call CloseHandle() on it. */
|
||||
SOCKET sock;
|
||||
WSANETWORKEVENTS ev;
|
||||
|
||||
/* Test whether fd refers to a socket. */
|
||||
sock = FD_TO_SOCKET (fd);
|
||||
ev.lNetworkEvents = 0xDEADBEEF;
|
||||
WSAEnumNetworkEvents (sock, NULL, &ev);
|
||||
if (ev.lNetworkEvents != 0xDEADBEEF)
|
||||
{
|
||||
/* fd refers to a socket. */
|
||||
/* FIXME: other applications, like squid, use an undocumented
|
||||
_free_osfhnd free function. But this is not enough: The 'osfile'
|
||||
flags for fd also needs to be cleared, but it is hard to access it.
|
||||
Instead, here we just close twice the file descriptor. */
|
||||
if (closesocket (sock))
|
||||
{
|
||||
set_winsock_errno ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This call frees the file descriptor and does a
|
||||
CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails. */
|
||||
_close (fd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Some other type of file descriptor. */
|
||||
return execute_close_hooks (remaining_list, primary, fd);
|
||||
}
|
||||
|
||||
static int
|
||||
ioctl_fd_maybe_socket (const struct fd_hook *remaining_list,
|
||||
gl_ioctl_fn primary,
|
||||
int fd, int request, void *arg)
|
||||
{
|
||||
SOCKET sock;
|
||||
WSANETWORKEVENTS ev;
|
||||
|
||||
/* Test whether fd refers to a socket. */
|
||||
sock = FD_TO_SOCKET (fd);
|
||||
ev.lNetworkEvents = 0xDEADBEEF;
|
||||
WSAEnumNetworkEvents (sock, NULL, &ev);
|
||||
if (ev.lNetworkEvents != 0xDEADBEEF)
|
||||
{
|
||||
/* fd refers to a socket. */
|
||||
if (ioctlsocket (sock, request, arg) < 0)
|
||||
{
|
||||
set_winsock_errno ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
/* Some other type of file descriptor. */
|
||||
return execute_ioctl_hooks (remaining_list, primary, fd, request, arg);
|
||||
}
|
||||
|
||||
static struct fd_hook fd_sockets_hook;
|
||||
|
||||
static int initialized_sockets_version /* = 0 */;
|
||||
|
||||
#endif /* WINDOWS_SOCKETS */
|
||||
|
||||
int
|
||||
gl_sockets_startup (int version _GL_UNUSED)
|
||||
{
|
||||
#if WINDOWS_SOCKETS
|
||||
if (version > initialized_sockets_version)
|
||||
{
|
||||
WSADATA data;
|
||||
int err;
|
||||
|
||||
err = WSAStartup (version, &data);
|
||||
if (err != 0)
|
||||
return 1;
|
||||
|
||||
if (data.wVersion != version)
|
||||
{
|
||||
WSACleanup ();
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (initialized_sockets_version == 0)
|
||||
register_fd_hook (close_fd_maybe_socket, ioctl_fd_maybe_socket,
|
||||
&fd_sockets_hook);
|
||||
|
||||
initialized_sockets_version = version;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gl_sockets_cleanup (void)
|
||||
{
|
||||
#if WINDOWS_SOCKETS
|
||||
int err;
|
||||
|
||||
initialized_sockets_version = 0;
|
||||
|
||||
unregister_fd_hook (&fd_sockets_hook);
|
||||
|
||||
err = WSACleanup ();
|
||||
if (err != 0)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* sockets.h - wrappers for Windows socket functions
|
||||
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Simon Josefsson */
|
||||
|
||||
#ifndef SOCKETS_H
|
||||
#define SOCKETS_H 1
|
||||
|
||||
#define SOCKETS_1_0 0x0001
|
||||
#define SOCKETS_1_1 0x0101
|
||||
#define SOCKETS_2_0 0x0002
|
||||
#define SOCKETS_2_1 0x0102
|
||||
#define SOCKETS_2_2 0x0202
|
||||
|
||||
int gl_sockets_startup (int version)
|
||||
#ifndef WINDOWS_SOCKETS
|
||||
_GL_ATTRIBUTE_CONST
|
||||
#endif
|
||||
;
|
||||
|
||||
int gl_sockets_cleanup (void)
|
||||
#ifndef WINDOWS_SOCKETS
|
||||
_GL_ATTRIBUTE_CONST
|
||||
#endif
|
||||
;
|
||||
|
||||
/* This function is useful it you create a socket using gnulib's
|
||||
Winsock wrappers but needs to pass on the socket handle to some
|
||||
other library that only accepts sockets. */
|
||||
#ifdef WINDOWS_SOCKETS
|
||||
|
||||
# include <sys/socket.h>
|
||||
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
||||
static inline SOCKET
|
||||
gl_fd_to_handle (int fd)
|
||||
{
|
||||
return _get_osfhandle (fd);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# define gl_fd_to_handle(x) (x)
|
||||
|
||||
#endif /* WINDOWS_SOCKETS */
|
||||
|
||||
#endif /* SOCKETS_H */
|
||||
@@ -0,0 +1,121 @@
|
||||
/* A substitute for ISO C11 <stdalign.h>.
|
||||
|
||||
Copyright 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Paul Eggert and Bruno Haible. */
|
||||
|
||||
#ifndef _GL_STDALIGN_H
|
||||
#define _GL_STDALIGN_H
|
||||
|
||||
/* ISO C11 <stdalign.h> for platforms that lack it.
|
||||
|
||||
References:
|
||||
ISO C11 (latest free draft
|
||||
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>)
|
||||
sections 6.5.3.4, 6.7.5, 7.15.
|
||||
C++11 (latest free draft
|
||||
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>)
|
||||
section 18.10. */
|
||||
|
||||
/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment
|
||||
requirement of a structure member (i.e., slot or field) that is of
|
||||
type TYPE, as an integer constant expression.
|
||||
|
||||
This differs from GCC's __alignof__ operator, which can yield a
|
||||
better-performing alignment for an object of that type. For
|
||||
example, on x86 with GCC, __alignof__ (double) and __alignof__
|
||||
(long long) are 8, whereas alignof (double) and alignof (long long)
|
||||
are 4 unless the option '-malign-double' is used.
|
||||
|
||||
The result cannot be used as a value for an 'enum' constant, if you
|
||||
want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc.
|
||||
|
||||
Include <stddef.h> for offsetof. */
|
||||
#include <stddef.h>
|
||||
|
||||
/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
|
||||
standard headers, defines conflicting implementations of _Alignas
|
||||
and _Alignof that are no better than ours; override them. */
|
||||
#undef _Alignas
|
||||
#undef _Alignof
|
||||
|
||||
/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
|
||||
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>. */
|
||||
#if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
|
||||
|| (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9)))
|
||||
# ifdef __cplusplus
|
||||
# if 201103 <= __cplusplus
|
||||
# define _Alignof(type) alignof (type)
|
||||
# else
|
||||
template <class __t> struct __alignof_helper { char __a; __t __b; };
|
||||
# define _Alignof(type) offsetof (__alignof_helper<type>, __b)
|
||||
# endif
|
||||
# else
|
||||
# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b)
|
||||
# endif
|
||||
#endif
|
||||
#if ! (defined __cplusplus && 201103 <= __cplusplus)
|
||||
# define alignof _Alignof
|
||||
#endif
|
||||
#define __alignof_is_defined 1
|
||||
|
||||
/* alignas (A), also known as _Alignas (A), aligns a variable or type
|
||||
to the alignment A, where A is an integer constant expression. For
|
||||
example:
|
||||
|
||||
int alignas (8) foo;
|
||||
struct s { int a; int alignas (8) bar; };
|
||||
|
||||
aligns the address of FOO and the offset of BAR to be multiples of 8.
|
||||
|
||||
A should be a power of two that is at least the type's alignment
|
||||
and at most the implementation's alignment limit. This limit is
|
||||
2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable
|
||||
to MSVC through at least version 10.0, A should be an integer
|
||||
constant, as MSVC does not support expressions such as 1 << 3.
|
||||
To be portable to Sun C 5.11, do not align auto variables to
|
||||
anything stricter than their default alignment.
|
||||
|
||||
The following C11 requirements are not supported here:
|
||||
|
||||
- If A is zero, alignas has no effect.
|
||||
- alignas can be used multiple times; the strictest one wins.
|
||||
- alignas (TYPE) is equivalent to alignas (alignof (TYPE)).
|
||||
|
||||
*/
|
||||
|
||||
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
|
||||
# if defined __cplusplus && 201103 <= __cplusplus
|
||||
# define _Alignas(a) alignas (a)
|
||||
# elif ((defined __APPLE__ && defined __MACH__ \
|
||||
? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
|
||||
: __GNUC__) \
|
||||
|| (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \
|
||||
|| __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__)
|
||||
# define _Alignas(a) __attribute__ ((__aligned__ (a)))
|
||||
# elif 1300 <= _MSC_VER
|
||||
# define _Alignas(a) __declspec (align (a))
|
||||
# endif
|
||||
#endif
|
||||
#if ((defined _Alignas && ! (defined __cplusplus && 201103 <= __cplusplus)) \
|
||||
|| (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__))
|
||||
# define alignas _Alignas
|
||||
#endif
|
||||
#if defined alignas || (defined __cplusplus && 201103 <= __cplusplus)
|
||||
# define __alignas_is_defined 1
|
||||
#endif
|
||||
|
||||
#endif /* _GL_STDALIGN_H */
|
||||
@@ -0,0 +1,450 @@
|
||||
/* strerror_r.c --- POSIX compatible system error routine
|
||||
|
||||
Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Enable declaration of sys_nerr and sys_errlist in <errno.h> on NetBSD. */
|
||||
#define _NETBSD_SOURCE 1
|
||||
|
||||
/* Specification. */
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if !HAVE_SNPRINTF
|
||||
# include <stdarg.h>
|
||||
#endif
|
||||
|
||||
#include "strerror-override.h"
|
||||
|
||||
#if (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) && HAVE___XPG_STRERROR_R /* glibc >= 2.3.4, cygwin >= 1.7.9 */
|
||||
|
||||
# define USE_XPG_STRERROR_R 1
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
int __xpg_strerror_r (int errnum, char *buf, size_t buflen);
|
||||
|
||||
#elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__)
|
||||
|
||||
/* The system's strerror_r function is OK, except that its third argument
|
||||
is 'int', not 'size_t', or its return type is wrong. */
|
||||
|
||||
# include <limits.h>
|
||||
|
||||
# define USE_SYSTEM_STRERROR_R 1
|
||||
|
||||
#else /* (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */
|
||||
|
||||
/* Use the system's strerror(). Exclude glibc and cygwin because the
|
||||
system strerror_r has the wrong return type, and cygwin 1.7.9
|
||||
strerror_r clobbers strerror. */
|
||||
# undef strerror
|
||||
|
||||
# define USE_SYSTEM_STRERROR 1
|
||||
|
||||
# if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__
|
||||
|
||||
/* No locking needed. */
|
||||
|
||||
/* Get catgets internationalization functions. */
|
||||
# if HAVE_CATGETS
|
||||
# include <nl_types.h>
|
||||
# endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Get sys_nerr, sys_errlist on HP-UX (otherwise only declared in C++ mode).
|
||||
Get sys_nerr, sys_errlist on IRIX (otherwise only declared with _SGIAPI). */
|
||||
# if defined __hpux || defined __sgi
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
# endif
|
||||
|
||||
/* Get sys_nerr on Solaris. */
|
||||
# if defined __sun && !defined _LP64
|
||||
extern int sys_nerr;
|
||||
# endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
# else
|
||||
|
||||
# include "glthread/lock.h"
|
||||
|
||||
/* This lock protects the buffer returned by strerror(). We assume that
|
||||
no other uses of strerror() exist in the program. */
|
||||
gl_lock_define_initialized(static, strerror_lock)
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* On MSVC, there is no snprintf() function, just a _snprintf().
|
||||
It is of lower quality, but sufficient for the simple use here.
|
||||
We only have to make sure to NUL terminate the result (_snprintf
|
||||
does not NUL terminate, like strncpy). */
|
||||
#if !HAVE_SNPRINTF
|
||||
static int
|
||||
local_snprintf (char *buf, size_t buflen, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int result;
|
||||
|
||||
va_start (args, format);
|
||||
result = _vsnprintf (buf, buflen, format, args);
|
||||
va_end (args);
|
||||
if (buflen > 0 && (result < 0 || result >= buflen))
|
||||
buf[buflen - 1] = '\0';
|
||||
return result;
|
||||
}
|
||||
# define snprintf local_snprintf
|
||||
#endif
|
||||
|
||||
/* Copy as much of MSG into BUF as possible, without corrupting errno.
|
||||
Return 0 if MSG fit in BUFLEN, otherwise return ERANGE. */
|
||||
static int
|
||||
safe_copy (char *buf, size_t buflen, const char *msg)
|
||||
{
|
||||
size_t len = strlen (msg);
|
||||
int ret;
|
||||
|
||||
if (len < buflen)
|
||||
{
|
||||
/* Although POSIX allows memcpy() to corrupt errno, we don't
|
||||
know of any implementation where this is a real problem. */
|
||||
memcpy (buf, msg, len + 1);
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (buf, msg, buflen - 1);
|
||||
buf[buflen - 1] = '\0';
|
||||
ret = ERANGE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
strerror_r (int errnum, char *buf, size_t buflen)
|
||||
#undef strerror_r
|
||||
{
|
||||
/* Filter this out now, so that rest of this replacement knows that
|
||||
there is room for a non-empty message and trailing NUL. */
|
||||
if (buflen <= 1)
|
||||
{
|
||||
if (buflen)
|
||||
*buf = '\0';
|
||||
return ERANGE;
|
||||
}
|
||||
*buf = '\0';
|
||||
|
||||
/* Check for gnulib overrides. */
|
||||
{
|
||||
char const *msg = strerror_override (errnum);
|
||||
|
||||
if (msg)
|
||||
return safe_copy (buf, buflen, msg);
|
||||
}
|
||||
|
||||
{
|
||||
int ret;
|
||||
int saved_errno = errno;
|
||||
|
||||
#if USE_XPG_STRERROR_R
|
||||
|
||||
{
|
||||
ret = __xpg_strerror_r (errnum, buf, buflen);
|
||||
if (ret < 0)
|
||||
ret = errno;
|
||||
if (!*buf)
|
||||
{
|
||||
/* glibc 2.13 would not touch buf on err, so we have to fall
|
||||
back to GNU strerror_r which always returns a thread-safe
|
||||
untruncated string to (partially) copy into our buf. */
|
||||
safe_copy (buf, buflen, strerror_r (errnum, buf, buflen));
|
||||
}
|
||||
}
|
||||
|
||||
#elif USE_SYSTEM_STRERROR_R
|
||||
|
||||
if (buflen > INT_MAX)
|
||||
buflen = INT_MAX;
|
||||
|
||||
# ifdef __hpux
|
||||
/* On HP-UX 11.31, strerror_r always fails when buflen < 80; it
|
||||
also fails to change buf on EINVAL. */
|
||||
{
|
||||
char stackbuf[80];
|
||||
|
||||
if (buflen < sizeof stackbuf)
|
||||
{
|
||||
ret = strerror_r (errnum, stackbuf, sizeof stackbuf);
|
||||
if (ret == 0)
|
||||
ret = safe_copy (buf, buflen, stackbuf);
|
||||
}
|
||||
else
|
||||
ret = strerror_r (errnum, buf, buflen);
|
||||
}
|
||||
# else
|
||||
ret = strerror_r (errnum, buf, buflen);
|
||||
|
||||
/* Some old implementations may return (-1, EINVAL) instead of EINVAL. */
|
||||
if (ret < 0)
|
||||
ret = errno;
|
||||
# endif
|
||||
|
||||
# ifdef _AIX
|
||||
/* AIX returns 0 rather than ERANGE when truncating strings; try
|
||||
again until we are sure we got the entire string. */
|
||||
if (!ret && strlen (buf) == buflen - 1)
|
||||
{
|
||||
char stackbuf[STACKBUF_LEN];
|
||||
size_t len;
|
||||
strerror_r (errnum, stackbuf, sizeof stackbuf);
|
||||
len = strlen (stackbuf);
|
||||
/* STACKBUF_LEN should have been large enough. */
|
||||
if (len + 1 == sizeof stackbuf)
|
||||
abort ();
|
||||
if (buflen <= len)
|
||||
ret = ERANGE;
|
||||
}
|
||||
# else
|
||||
/* Solaris 10 does not populate buf on ERANGE. OpenBSD 4.7
|
||||
truncates early on ERANGE rather than return a partial integer.
|
||||
We prefer the maximal string. We set buf[0] earlier, and we
|
||||
know of no implementation that modifies buf to be an
|
||||
unterminated string, so this strlen should be portable in
|
||||
practice (rather than pulling in a safer strnlen). */
|
||||
if (ret == ERANGE && strlen (buf) < buflen - 1)
|
||||
{
|
||||
char stackbuf[STACKBUF_LEN];
|
||||
|
||||
/* STACKBUF_LEN should have been large enough. */
|
||||
if (strerror_r (errnum, stackbuf, sizeof stackbuf) == ERANGE)
|
||||
abort ();
|
||||
safe_copy (buf, buflen, stackbuf);
|
||||
}
|
||||
# endif
|
||||
|
||||
#else /* USE_SYSTEM_STRERROR */
|
||||
|
||||
/* Try to do what strerror (errnum) does, but without clobbering the
|
||||
buffer used by strerror(). */
|
||||
|
||||
# if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Windows, Cygwin */
|
||||
|
||||
/* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE
|
||||
and <errno.h> above.
|
||||
HP-UX: sys_nerr, sys_errlist are declared explicitly above.
|
||||
native Windows: sys_nerr, sys_errlist are declared in <stdlib.h>.
|
||||
Cygwin: sys_nerr, sys_errlist are declared in <errno.h>. */
|
||||
if (errnum >= 0 && errnum < sys_nerr)
|
||||
{
|
||||
# if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
|
||||
# if defined __NetBSD__
|
||||
nl_catd catd = catopen ("libc", NL_CAT_LOCALE);
|
||||
const char *errmsg =
|
||||
(catd != (nl_catd)-1
|
||||
? catgets (catd, 1, errnum, sys_errlist[errnum])
|
||||
: sys_errlist[errnum]);
|
||||
# endif
|
||||
# if defined __hpux
|
||||
nl_catd catd = catopen ("perror", NL_CAT_LOCALE);
|
||||
const char *errmsg =
|
||||
(catd != (nl_catd)-1
|
||||
? catgets (catd, 1, 1 + errnum, sys_errlist[errnum])
|
||||
: sys_errlist[errnum]);
|
||||
# endif
|
||||
# else
|
||||
const char *errmsg = sys_errlist[errnum];
|
||||
# endif
|
||||
if (errmsg == NULL || *errmsg == '\0')
|
||||
ret = EINVAL;
|
||||
else
|
||||
ret = safe_copy (buf, buflen, errmsg);
|
||||
# if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux)
|
||||
if (catd != (nl_catd)-1)
|
||||
catclose (catd);
|
||||
# endif
|
||||
}
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
# elif defined __sgi || (defined __sun && !defined _LP64) /* IRIX, Solaris <= 9 32-bit */
|
||||
|
||||
/* For a valid error number, the system's strerror() function returns
|
||||
a pointer to a not copied string, not to a buffer. */
|
||||
if (errnum >= 0 && errnum < sys_nerr)
|
||||
{
|
||||
char *errmsg = strerror (errnum);
|
||||
|
||||
if (errmsg == NULL || *errmsg == '\0')
|
||||
ret = EINVAL;
|
||||
else
|
||||
ret = safe_copy (buf, buflen, errmsg);
|
||||
}
|
||||
else
|
||||
ret = EINVAL;
|
||||
|
||||
# else
|
||||
|
||||
gl_lock_lock (strerror_lock);
|
||||
|
||||
{
|
||||
char *errmsg = strerror (errnum);
|
||||
|
||||
/* For invalid error numbers, strerror() on
|
||||
- IRIX 6.5 returns NULL,
|
||||
- HP-UX 11 returns an empty string. */
|
||||
if (errmsg == NULL || *errmsg == '\0')
|
||||
ret = EINVAL;
|
||||
else
|
||||
ret = safe_copy (buf, buflen, errmsg);
|
||||
}
|
||||
|
||||
gl_lock_unlock (strerror_lock);
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
|
||||
/* MSVC 14 defines names for many error codes in the range 100..140,
|
||||
but _sys_errlist contains strings only for the error codes
|
||||
< _sys_nerr = 43. */
|
||||
if (ret == EINVAL)
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
switch (errnum)
|
||||
{
|
||||
case 100 /* EADDRINUSE */:
|
||||
errmsg = "Address already in use";
|
||||
break;
|
||||
case 101 /* EADDRNOTAVAIL */:
|
||||
errmsg = "Cannot assign requested address";
|
||||
break;
|
||||
case 102 /* EAFNOSUPPORT */:
|
||||
errmsg = "Address family not supported by protocol";
|
||||
break;
|
||||
case 103 /* EALREADY */:
|
||||
errmsg = "Operation already in progress";
|
||||
break;
|
||||
case 105 /* ECANCELED */:
|
||||
errmsg = "Operation canceled";
|
||||
break;
|
||||
case 106 /* ECONNABORTED */:
|
||||
errmsg = "Software caused connection abort";
|
||||
break;
|
||||
case 107 /* ECONNREFUSED */:
|
||||
errmsg = "Connection refused";
|
||||
break;
|
||||
case 108 /* ECONNRESET */:
|
||||
errmsg = "Connection reset by peer";
|
||||
break;
|
||||
case 109 /* EDESTADDRREQ */:
|
||||
errmsg = "Destination address required";
|
||||
break;
|
||||
case 110 /* EHOSTUNREACH */:
|
||||
errmsg = "No route to host";
|
||||
break;
|
||||
case 112 /* EINPROGRESS */:
|
||||
errmsg = "Operation now in progress";
|
||||
break;
|
||||
case 113 /* EISCONN */:
|
||||
errmsg = "Transport endpoint is already connected";
|
||||
break;
|
||||
case 114 /* ELOOP */:
|
||||
errmsg = "Too many levels of symbolic links";
|
||||
break;
|
||||
case 115 /* EMSGSIZE */:
|
||||
errmsg = "Message too long";
|
||||
break;
|
||||
case 116 /* ENETDOWN */:
|
||||
errmsg = "Network is down";
|
||||
break;
|
||||
case 117 /* ENETRESET */:
|
||||
errmsg = "Network dropped connection on reset";
|
||||
break;
|
||||
case 118 /* ENETUNREACH */:
|
||||
errmsg = "Network is unreachable";
|
||||
break;
|
||||
case 119 /* ENOBUFS */:
|
||||
errmsg = "No buffer space available";
|
||||
break;
|
||||
case 123 /* ENOPROTOOPT */:
|
||||
errmsg = "Protocol not available";
|
||||
break;
|
||||
case 126 /* ENOTCONN */:
|
||||
errmsg = "Transport endpoint is not connected";
|
||||
break;
|
||||
case 128 /* ENOTSOCK */:
|
||||
errmsg = "Socket operation on non-socket";
|
||||
break;
|
||||
case 129 /* ENOTSUP */:
|
||||
errmsg = "Not supported";
|
||||
break;
|
||||
case 130 /* EOPNOTSUPP */:
|
||||
errmsg = "Operation not supported";
|
||||
break;
|
||||
case 132 /* EOVERFLOW */:
|
||||
errmsg = "Value too large for defined data type";
|
||||
break;
|
||||
case 133 /* EOWNERDEAD */:
|
||||
errmsg = "Owner died";
|
||||
break;
|
||||
case 134 /* EPROTO */:
|
||||
errmsg = "Protocol error";
|
||||
break;
|
||||
case 135 /* EPROTONOSUPPORT */:
|
||||
errmsg = "Protocol not supported";
|
||||
break;
|
||||
case 136 /* EPROTOTYPE */:
|
||||
errmsg = "Protocol wrong type for socket";
|
||||
break;
|
||||
case 138 /* ETIMEDOUT */:
|
||||
errmsg = "Connection timed out";
|
||||
break;
|
||||
case 140 /* EWOULDBLOCK */:
|
||||
errmsg = "Operation would block";
|
||||
break;
|
||||
default:
|
||||
errmsg = NULL;
|
||||
break;
|
||||
}
|
||||
if (errmsg != NULL)
|
||||
ret = safe_copy (buf, buflen, errmsg);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == EINVAL && !*buf)
|
||||
snprintf (buf, buflen, "Unknown error %d", errnum);
|
||||
|
||||
errno = saved_errno;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/* Stub for symlink().
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
#if HAVE_SYMLINK
|
||||
|
||||
# undef symlink
|
||||
|
||||
/* Create a symlink, but reject trailing slash. */
|
||||
int
|
||||
rpl_symlink (char const *contents, char const *name)
|
||||
{
|
||||
size_t len = strlen (name);
|
||||
if (len && name[len - 1] == '/')
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat (name, &st) == 0)
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
return symlink (contents, name);
|
||||
}
|
||||
|
||||
#else /* !HAVE_SYMLINK */
|
||||
|
||||
/* The system does not support symlinks. */
|
||||
int
|
||||
symlink (char const *contents _GL_UNUSED,
|
||||
char const *name _GL_UNUSED)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_SYMLINK */
|
||||
@@ -0,0 +1,78 @@
|
||||
/* Substitute for and wrapper around <sys/ioctl.h>.
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_SYS_IOCTL_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#if @HAVE_SYS_IOCTL_H@
|
||||
# @INCLUDE_NEXT@ @NEXT_SYS_IOCTL_H@
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_SYS_IOCTL_H
|
||||
#define _@GUARD_PREFIX@_SYS_IOCTL_H
|
||||
|
||||
/* AIX 5.1 and Solaris 10 declare ioctl() in <unistd.h> and in <stropts.h>,
|
||||
but not in <sys/ioctl.h>.
|
||||
But avoid namespace pollution on glibc systems. */
|
||||
#ifndef __GLIBC__
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
|
||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||
|
||||
|
||||
/* Declare overridden functions. */
|
||||
|
||||
#if @GNULIB_IOCTL@
|
||||
# if @REPLACE_IOCTL@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef ioctl
|
||||
# define ioctl rpl_ioctl
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (ioctl, int,
|
||||
(int fd, int request, ... /* {void *,char *} arg */));
|
||||
_GL_CXXALIAS_RPL (ioctl, int,
|
||||
(int fd, int request, ... /* {void *,char *} arg */));
|
||||
# else
|
||||
# if @SYS_IOCTL_H_HAVE_WINSOCK2_H@ || 1
|
||||
_GL_FUNCDECL_SYS (ioctl, int,
|
||||
(int fd, int request, ... /* {void *,char *} arg */));
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (ioctl, int,
|
||||
(int fd, int request, ... /* {void *,char *} arg */));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (ioctl);
|
||||
#elif @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
|
||||
# undef ioctl
|
||||
# define ioctl ioctl_used_without_requesting_gnulib_module_ioctl
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef ioctl
|
||||
# if HAVE_RAW_DECL_IOCTL
|
||||
_GL_WARN_ON_USE (ioctl, "ioctl does not portably work on sockets - "
|
||||
"use gnulib module ioctl for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_SYS_IOCTL_H */
|
||||
#endif /* _@GUARD_PREFIX@_SYS_IOCTL_H */
|
||||
@@ -0,0 +1,319 @@
|
||||
/* Substitute for <sys/select.h>.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU 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>.
|
||||
On Cygwin, <sys/time.h> includes <sys/select.h>.
|
||||
Simply delegate to the system's header in this case. */
|
||||
#if (@HAVE_SYS_SELECT_H@ \
|
||||
&& !defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_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__))))
|
||||
|
||||
# define _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TYPES_H
|
||||
# @INCLUDE_NEXT@ @NEXT_SYS_SELECT_H@
|
||||
|
||||
#elif (@HAVE_SYS_SELECT_H@ \
|
||||
&& (defined _CYGWIN_SYS_TIME_H \
|
||||
|| (!defined _GL_SYS_SELECT_H_REDIRECT_FROM_SYS_TIME_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__))))))
|
||||
|
||||
# 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 and "unknown type
|
||||
name" problems on Cygwin. */
|
||||
# if !(defined __GLIBC__ || defined __CYGWIN__)
|
||||
# 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 and "unknown type
|
||||
name" problems on Cygwin.
|
||||
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 __CYGWIN__) && !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 *restrict, fd_set *restrict, fd_set *restrict,
|
||||
struct timeval *restrict));
|
||||
_GL_CXXALIAS_RPL (select, int,
|
||||
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
|
||||
struct timeval *restrict));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (select, int,
|
||||
(int, fd_set *restrict, fd_set *restrict, fd_set *restrict,
|
||||
struct timeval *restrict));
|
||||
# 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 */
|
||||
@@ -0,0 +1,4 @@
|
||||
#include <config.h>
|
||||
#define _GL_SYS_SOCKET_INLINE _GL_EXTERN_INLINE
|
||||
#include "sys/socket.h"
|
||||
typedef int dummy;
|
||||
@@ -0,0 +1,697 @@
|
||||
/* Provide a sys/socket header file for systems lacking it (read: MinGW)
|
||||
and for systems where it is incomplete.
|
||||
Copyright (C) 2005-2017 Free Software Foundation, Inc.
|
||||
Written by Simon Josefsson.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This file is supposed to be used on platforms that lack <sys/socket.h>,
|
||||
on platforms where <sys/socket.h> cannot be included standalone, and on
|
||||
platforms where <sys/socket.h> does not provide all necessary definitions.
|
||||
It is intended to provide definitions and prototypes needed by an
|
||||
application. */
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
#endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
#if defined _GL_ALREADY_INCLUDING_SYS_SOCKET_H
|
||||
/* Special invocation convention:
|
||||
- On Cygwin 1.5.x we have a sequence of nested includes
|
||||
<sys/socket.h> -> <cygwin/socket.h> -> <asm/socket.h> -> <cygwin/if.h>,
|
||||
and the latter includes <sys/socket.h>. In this situation, the functions
|
||||
are not yet declared, therefore we cannot provide the C++ aliases. */
|
||||
|
||||
#@INCLUDE_NEXT@ @NEXT_SYS_SOCKET_H@
|
||||
|
||||
#else
|
||||
/* Normal invocation convention. */
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_SYS_SOCKET_H
|
||||
|
||||
#if @HAVE_SYS_SOCKET_H@
|
||||
|
||||
# define _GL_ALREADY_INCLUDING_SYS_SOCKET_H
|
||||
|
||||
/* On many platforms, <sys/socket.h> assumes prior inclusion of
|
||||
<sys/types.h>. */
|
||||
# include <sys/types.h>
|
||||
|
||||
/* On FreeBSD 6.4, <sys/socket.h> defines some macros that assume that NULL
|
||||
is defined. */
|
||||
# include <stddef.h>
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
# @INCLUDE_NEXT@ @NEXT_SYS_SOCKET_H@
|
||||
|
||||
# undef _GL_ALREADY_INCLUDING_SYS_SOCKET_H
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_SYS_SOCKET_H
|
||||
#define _@GUARD_PREFIX@_SYS_SOCKET_H
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef _GL_SYS_SOCKET_INLINE
|
||||
# define _GL_SYS_SOCKET_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
|
||||
/* The definition of _GL_ARG_NONNULL is copied here. */
|
||||
|
||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||
|
||||
#if !@HAVE_SA_FAMILY_T@
|
||||
# if !GNULIB_defined_sa_family_t
|
||||
/* On OS/2 kLIBC, sa_family_t is unsigned char unless TCPV40HDRS is defined. */
|
||||
# if !defined __KLIBC__ || defined TCPV40HDRS
|
||||
typedef unsigned short sa_family_t;
|
||||
# else
|
||||
typedef unsigned char sa_family_t;
|
||||
# endif
|
||||
# define GNULIB_defined_sa_family_t 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @HAVE_STRUCT_SOCKADDR_STORAGE@
|
||||
/* Make the 'struct sockaddr_storage' field 'ss_family' visible on AIX 7.1. */
|
||||
# if !@HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@
|
||||
# ifndef ss_family
|
||||
# define ss_family __ss_family
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# include <stdalign.h>
|
||||
/* Code taken from glibc sysdeps/unix/sysv/linux/bits/socket.h on
|
||||
2009-05-08, licensed under LGPLv2.1+, plus portability fixes. */
|
||||
# define __ss_aligntype unsigned long int
|
||||
# define _SS_SIZE 256
|
||||
# define _SS_PADSIZE \
|
||||
(_SS_SIZE - ((sizeof (sa_family_t) >= alignof (__ss_aligntype) \
|
||||
? sizeof (sa_family_t) \
|
||||
: alignof (__ss_aligntype)) \
|
||||
+ sizeof (__ss_aligntype)))
|
||||
|
||||
# if !GNULIB_defined_struct_sockaddr_storage
|
||||
struct sockaddr_storage
|
||||
{
|
||||
sa_family_t ss_family; /* Address family, etc. */
|
||||
__ss_aligntype __ss_align; /* Force desired alignment. */
|
||||
char __ss_padding[_SS_PADSIZE];
|
||||
};
|
||||
# define GNULIB_defined_struct_sockaddr_storage 1
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Get struct iovec. */
|
||||
/* But avoid namespace pollution on glibc systems. */
|
||||
#if ! defined __GLIBC__
|
||||
# include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
#if @HAVE_SYS_SOCKET_H@
|
||||
|
||||
/* A platform that has <sys/socket.h>. */
|
||||
|
||||
/* For shutdown(). */
|
||||
# if !defined SHUT_RD
|
||||
# define SHUT_RD 0
|
||||
# endif
|
||||
# if !defined SHUT_WR
|
||||
# define SHUT_WR 1
|
||||
# endif
|
||||
# if !defined SHUT_RDWR
|
||||
# define SHUT_RDWR 2
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
# ifdef __CYGWIN__
|
||||
# error "Cygwin does have a sys/socket.h, doesn't it?!?"
|
||||
# endif
|
||||
|
||||
/* A platform that lacks <sys/socket.h>.
|
||||
|
||||
Currently only MinGW is supported. See the gnulib manual regarding
|
||||
Windows sockets. MinGW has the header files winsock2.h and
|
||||
ws2tcpip.h that declare the sys/socket.h definitions we need. Note
|
||||
that you can influence which definitions you get by setting the
|
||||
WINVER symbol before including these two files. For example,
|
||||
getaddrinfo is only available if _WIN32_WINNT >= 0x0501 (that
|
||||
symbol is set indirectly through WINVER). You can set this by
|
||||
adding AC_DEFINE(WINVER, 0x0501) to configure.ac. Note that your
|
||||
code may not run on older Windows releases then. My Windows 2000
|
||||
box was not able to run the code, for example. The situation is
|
||||
slightly confusing because
|
||||
<http://msdn.microsoft.com/en-us/library/ms738520>
|
||||
suggests that getaddrinfo should be available on all Windows
|
||||
releases. */
|
||||
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
# if @HAVE_WS2TCPIP_H@
|
||||
# include <ws2tcpip.h>
|
||||
# endif
|
||||
|
||||
/* For shutdown(). */
|
||||
# if !defined SHUT_RD && defined SD_RECEIVE
|
||||
# define SHUT_RD SD_RECEIVE
|
||||
# endif
|
||||
# if !defined SHUT_WR && defined SD_SEND
|
||||
# define SHUT_WR SD_SEND
|
||||
# endif
|
||||
# if !defined SHUT_RDWR && defined SD_BOTH
|
||||
# define SHUT_RDWR SD_BOTH
|
||||
# endif
|
||||
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
/* Include headers needed by the emulation code. */
|
||||
# include <sys/types.h>
|
||||
# include <io.h>
|
||||
|
||||
# if !GNULIB_defined_socklen_t
|
||||
typedef int socklen_t;
|
||||
# define GNULIB_defined_socklen_t 1
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
/* Rudimentary 'struct msghdr'; this works as long as you don't try to
|
||||
access msg_control or msg_controllen. */
|
||||
struct msghdr {
|
||||
void *msg_name;
|
||||
socklen_t msg_namelen;
|
||||
struct iovec *msg_iov;
|
||||
int msg_iovlen;
|
||||
int msg_flags;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
_GL_SYS_SOCKET_INLINE 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_SELECT_H
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef select
|
||||
# define select select_used_without_including_sys_select_h
|
||||
# else
|
||||
_GL_WARN_ON_USE (select,
|
||||
"select() used without including <sys/select.h>");
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Wrap everything else to use libc file descriptors for sockets. */
|
||||
|
||||
#if @GNULIB_SOCKET@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef socket
|
||||
# define socket rpl_socket
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (socket, int, (int domain, int type, int protocol));
|
||||
_GL_CXXALIAS_RPL (socket, int, (int domain, int type, int protocol));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (socket, int, (int domain, int type, int protocol));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (socket);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef socket
|
||||
# define socket socket_used_without_requesting_gnulib_module_socket
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef socket
|
||||
# if HAVE_RAW_DECL_SOCKET
|
||||
_GL_WARN_ON_USE (socket, "socket is not always POSIX compliant - "
|
||||
"use gnulib module socket for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_CONNECT@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef connect
|
||||
# define connect rpl_connect
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (connect, int,
|
||||
(int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (connect, int,
|
||||
(int fd, const struct sockaddr *addr, socklen_t addrlen));
|
||||
# else
|
||||
/* Need to cast, because on NonStop Kernel, the third parameter is
|
||||
size_t addrlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (connect, int,
|
||||
(int fd,
|
||||
const struct sockaddr *addr, socklen_t addrlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (connect);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef connect
|
||||
# define connect socket_used_without_requesting_gnulib_module_connect
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef connect
|
||||
# if HAVE_RAW_DECL_CONNECT
|
||||
_GL_WARN_ON_USE (connect, "connect is not always POSIX compliant - "
|
||||
"use gnulib module connect for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_ACCEPT@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef accept
|
||||
# define accept rpl_accept
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (accept, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
_GL_CXXALIAS_RPL (accept, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
# else
|
||||
/* Need to cast, because on Solaris 10 systems, the third parameter is
|
||||
void *addrlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (accept, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (accept);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef accept
|
||||
# define accept accept_used_without_requesting_gnulib_module_accept
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef accept
|
||||
# if HAVE_RAW_DECL_ACCEPT
|
||||
_GL_WARN_ON_USE (accept, "accept is not always POSIX compliant - "
|
||||
"use gnulib module accept for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_BIND@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef bind
|
||||
# define bind rpl_bind
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (bind, int,
|
||||
(int fd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (bind, int,
|
||||
(int fd, const struct sockaddr *addr, socklen_t addrlen));
|
||||
# else
|
||||
/* Need to cast, because on NonStop Kernel, the third parameter is
|
||||
size_t addrlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (bind, int,
|
||||
(int fd,
|
||||
const struct sockaddr *addr, socklen_t addrlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (bind);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef bind
|
||||
# define bind bind_used_without_requesting_gnulib_module_bind
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef bind
|
||||
# if HAVE_RAW_DECL_BIND
|
||||
_GL_WARN_ON_USE (bind, "bind is not always POSIX compliant - "
|
||||
"use gnulib module bind for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_GETPEERNAME@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef getpeername
|
||||
# define getpeername rpl_getpeername
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (getpeername, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
_GL_ARG_NONNULL ((2, 3)));
|
||||
_GL_CXXALIAS_RPL (getpeername, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
# else
|
||||
/* Need to cast, because on Solaris 10 systems, the third parameter is
|
||||
void *addrlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (getpeername, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (getpeername);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef getpeername
|
||||
# define getpeername getpeername_used_without_requesting_gnulib_module_getpeername
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getpeername
|
||||
# if HAVE_RAW_DECL_GETPEERNAME
|
||||
_GL_WARN_ON_USE (getpeername, "getpeername is not always POSIX compliant - "
|
||||
"use gnulib module getpeername for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_GETSOCKNAME@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef getsockname
|
||||
# define getsockname rpl_getsockname
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (getsockname, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
_GL_ARG_NONNULL ((2, 3)));
|
||||
_GL_CXXALIAS_RPL (getsockname, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
# else
|
||||
/* Need to cast, because on Solaris 10 systems, the third parameter is
|
||||
void *addrlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (getsockname, int,
|
||||
(int fd, struct sockaddr *addr, socklen_t *addrlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (getsockname);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef getsockname
|
||||
# define getsockname getsockname_used_without_requesting_gnulib_module_getsockname
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getsockname
|
||||
# if HAVE_RAW_DECL_GETSOCKNAME
|
||||
_GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - "
|
||||
"use gnulib module getsockname for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_GETSOCKOPT@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef getsockopt
|
||||
# define getsockopt rpl_getsockopt
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (getsockopt, int, (int fd, int level, int optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
_GL_ARG_NONNULL ((4, 5)));
|
||||
_GL_CXXALIAS_RPL (getsockopt, int, (int fd, int level, int optname,
|
||||
void *optval, socklen_t *optlen));
|
||||
# else
|
||||
/* Need to cast, because on Solaris 10 systems, the fifth parameter is
|
||||
void *optlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (getsockopt, int, (int fd, int level, int optname,
|
||||
void *optval, socklen_t *optlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (getsockopt);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef getsockopt
|
||||
# define getsockopt getsockopt_used_without_requesting_gnulib_module_getsockopt
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef getsockopt
|
||||
# if HAVE_RAW_DECL_GETSOCKOPT
|
||||
_GL_WARN_ON_USE (getsockopt, "getsockopt is not always POSIX compliant - "
|
||||
"use gnulib module getsockopt for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_LISTEN@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef listen
|
||||
# define listen rpl_listen
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (listen, int, (int fd, int backlog));
|
||||
_GL_CXXALIAS_RPL (listen, int, (int fd, int backlog));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (listen, int, (int fd, int backlog));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (listen);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef listen
|
||||
# define listen listen_used_without_requesting_gnulib_module_listen
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef listen
|
||||
# if HAVE_RAW_DECL_LISTEN
|
||||
_GL_WARN_ON_USE (listen, "listen is not always POSIX compliant - "
|
||||
"use gnulib module listen for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_RECV@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef recv
|
||||
# define recv rpl_recv
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (recv, ssize_t, (int fd, void *buf, size_t len, int flags));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (recv, ssize_t, (int fd, void *buf, size_t len, int flags));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (recv);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef recv
|
||||
# define recv recv_used_without_requesting_gnulib_module_recv
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef recv
|
||||
# if HAVE_RAW_DECL_RECV
|
||||
_GL_WARN_ON_USE (recv, "recv is not always POSIX compliant - "
|
||||
"use gnulib module recv for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_SEND@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef send
|
||||
# define send rpl_send
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (send, ssize_t,
|
||||
(int fd, const void *buf, size_t len, int flags)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (send, ssize_t,
|
||||
(int fd, const void *buf, size_t len, int flags));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (send, ssize_t,
|
||||
(int fd, const void *buf, size_t len, int flags));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (send);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef send
|
||||
# define send send_used_without_requesting_gnulib_module_send
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef send
|
||||
# if HAVE_RAW_DECL_SEND
|
||||
_GL_WARN_ON_USE (send, "send is not always POSIX compliant - "
|
||||
"use gnulib module send for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_RECVFROM@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef recvfrom
|
||||
# define recvfrom rpl_recvfrom
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (recvfrom, ssize_t,
|
||||
(int fd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (recvfrom, ssize_t,
|
||||
(int fd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen));
|
||||
# else
|
||||
/* Need to cast, because on Solaris 10 systems, the sixth parameter is
|
||||
void *fromlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (recvfrom, ssize_t,
|
||||
(int fd, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (recvfrom);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef recvfrom
|
||||
# define recvfrom recvfrom_used_without_requesting_gnulib_module_recvfrom
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef recvfrom
|
||||
# if HAVE_RAW_DECL_RECVFROM
|
||||
_GL_WARN_ON_USE (recvfrom, "recvfrom is not always POSIX compliant - "
|
||||
"use gnulib module recvfrom for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_SENDTO@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef sendto
|
||||
# define sendto rpl_sendto
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (sendto, ssize_t,
|
||||
(int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
_GL_ARG_NONNULL ((2)));
|
||||
_GL_CXXALIAS_RPL (sendto, ssize_t,
|
||||
(int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen));
|
||||
# else
|
||||
/* Need to cast, because on NonStop Kernel, the sixth parameter is
|
||||
size_t tolen. */
|
||||
_GL_CXXALIAS_SYS_CAST (sendto, ssize_t,
|
||||
(int fd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (sendto);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef sendto
|
||||
# define sendto sendto_used_without_requesting_gnulib_module_sendto
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef sendto
|
||||
# if HAVE_RAW_DECL_SENDTO
|
||||
_GL_WARN_ON_USE (sendto, "sendto is not always POSIX compliant - "
|
||||
"use gnulib module sendto for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_SETSOCKOPT@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef setsockopt
|
||||
# define setsockopt rpl_setsockopt
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (setsockopt, int, (int fd, int level, int optname,
|
||||
const void * optval, socklen_t optlen)
|
||||
_GL_ARG_NONNULL ((4)));
|
||||
_GL_CXXALIAS_RPL (setsockopt, int, (int fd, int level, int optname,
|
||||
const void * optval, socklen_t optlen));
|
||||
# else
|
||||
/* Need to cast, because on NonStop Kernel, the fifth parameter is
|
||||
size_t optlen. */
|
||||
_GL_CXXALIAS_SYS_CAST (setsockopt, int,
|
||||
(int fd, int level, int optname,
|
||||
const void * optval, socklen_t optlen));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (setsockopt);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef setsockopt
|
||||
# define setsockopt setsockopt_used_without_requesting_gnulib_module_setsockopt
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef setsockopt
|
||||
# if HAVE_RAW_DECL_SETSOCKOPT
|
||||
_GL_WARN_ON_USE (setsockopt, "setsockopt is not always POSIX compliant - "
|
||||
"use gnulib module setsockopt for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_SHUTDOWN@
|
||||
# if @HAVE_WINSOCK2_H@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef shutdown
|
||||
# define shutdown rpl_shutdown
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (shutdown, int, (int fd, int how));
|
||||
_GL_CXXALIAS_RPL (shutdown, int, (int fd, int how));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (shutdown, int, (int fd, int how));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (shutdown);
|
||||
#elif @HAVE_WINSOCK2_H@
|
||||
# undef shutdown
|
||||
# define shutdown shutdown_used_without_requesting_gnulib_module_shutdown
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef shutdown
|
||||
# if HAVE_RAW_DECL_SHUTDOWN
|
||||
_GL_WARN_ON_USE (shutdown, "shutdown is not always POSIX compliant - "
|
||||
"use gnulib module shutdown for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if @GNULIB_ACCEPT4@
|
||||
/* Accept a connection on a socket, with specific opening flags.
|
||||
The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
|
||||
and O_TEXT, O_BINARY (defined in "binary-io.h").
|
||||
See also the Linux man page at
|
||||
<http://www.kernel.org/doc/man-pages/online/pages/man2/accept4.2.html>. */
|
||||
# if @HAVE_ACCEPT4@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# define accept4 rpl_accept4
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (accept4, int,
|
||||
(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
|
||||
int flags));
|
||||
_GL_CXXALIAS_RPL (accept4, int,
|
||||
(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
|
||||
int flags));
|
||||
# else
|
||||
_GL_FUNCDECL_SYS (accept4, int,
|
||||
(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
|
||||
int flags));
|
||||
_GL_CXXALIAS_SYS (accept4, int,
|
||||
(int sockfd, struct sockaddr *addr, socklen_t *addrlen,
|
||||
int flags));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (accept4);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef accept4
|
||||
# if HAVE_RAW_DECL_ACCEPT4
|
||||
_GL_WARN_ON_USE (accept4, "accept4 is unportable - "
|
||||
"use gnulib module accept4 for portability");
|
||||
# endif
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_SYS_SOCKET_H */
|
||||
#endif /* _@GUARD_PREFIX@_SYS_SOCKET_H */
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Substitute for <sys/uio.h>.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
# if __GNUC__ >= 3
|
||||
@PRAGMA_SYSTEM_HEADER@
|
||||
# endif
|
||||
@PRAGMA_COLUMNS@
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_SYS_UIO_H
|
||||
|
||||
#if @HAVE_SYS_UIO_H@
|
||||
|
||||
/* On OpenBSD 4.4, <sys/uio.h> assumes prior inclusion of <sys/types.h>. */
|
||||
# include <sys/types.h>
|
||||
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
# @INCLUDE_NEXT@ @NEXT_SYS_UIO_H@
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _@GUARD_PREFIX@_SYS_UIO_H
|
||||
#define _@GUARD_PREFIX@_SYS_UIO_H
|
||||
|
||||
#if !@HAVE_SYS_UIO_H@
|
||||
/* A platform that lacks <sys/uio.h>. */
|
||||
/* Get 'size_t' and 'ssize_t'. */
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# if !GNULIB_defined_struct_iovec
|
||||
/* All known platforms that lack <sys/uio.h> also lack any declaration
|
||||
of struct iovec in any other header. */
|
||||
struct iovec {
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
# define GNULIB_defined_struct_iovec 1
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _@GUARD_PREFIX@_SYS_UIO_H */
|
||||
#endif /* _@GUARD_PREFIX@_SYS_UIO_H */
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Test accepting a connection to a server socket.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (accept, int, (int, struct sockaddr *, socklen_t *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
(void) gl_sockets_startup (SOCKETS_1_1);
|
||||
|
||||
/* Test behaviour for invalid file descriptors. */
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
|
||||
errno = 0;
|
||||
ASSERT (accept (-1, (struct sockaddr *) &addr, &addrlen) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addrlen = sizeof (addr);
|
||||
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (accept (99, (struct sockaddr *) &addr, &addrlen) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Test of optional automatic memory allocation.
|
||||
Copyright (C) 2005, 2007, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <alloca.h>
|
||||
|
||||
#if HAVE_ALLOCA
|
||||
|
||||
static void
|
||||
do_allocation (int n)
|
||||
{
|
||||
void *ptr = alloca (n);
|
||||
(void) ptr;
|
||||
}
|
||||
|
||||
void (*func) (int) = do_allocation;
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
#if HAVE_ALLOCA
|
||||
int i;
|
||||
|
||||
/* Repeat a lot of times, to make sure there's no memory leak. */
|
||||
for (i = 0; i < 100000; i++)
|
||||
{
|
||||
/* Try various values.
|
||||
n = 0 gave a crash on Alpha with gcc-2.5.8.
|
||||
Some versions of Mac OS X have a stack size limit of 512 KB. */
|
||||
func (34);
|
||||
func (134);
|
||||
func (399);
|
||||
func (510823);
|
||||
func (129321);
|
||||
func (0);
|
||||
func (4070);
|
||||
func (4095);
|
||||
func (1);
|
||||
func (16582);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Tests of areadlink.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "areadlink.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ignore-value.h"
|
||||
#include "macros.h"
|
||||
|
||||
#define BASE "test-areadlink.t"
|
||||
|
||||
#include "test-areadlink.h"
|
||||
|
||||
/* Wrapper for testing areadlink. */
|
||||
static char *
|
||||
do_areadlink (char const *name, size_t ignored _GL_UNUSED)
|
||||
{
|
||||
return areadlink (name);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Remove any leftovers from a previous partial run. */
|
||||
ignore_value (system ("rm -rf " BASE "*"));
|
||||
|
||||
return test_areadlink (do_areadlink, true);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/* Tests of areadlink and friends.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
/* This file is designed to test areadlink(a),
|
||||
areadlink_with_size(a,b), and areadlinkat(AT_FDCWD,a). FUNC is the
|
||||
function to test; a length is always supplied, but may be ignored.
|
||||
Assumes that BASE and ASSERT are already defined, and that
|
||||
appropriate headers are already included. If PRINT, warn before
|
||||
skipping symlink tests with status 77. */
|
||||
|
||||
static int
|
||||
test_areadlink (char * (*func) (char const *, size_t), bool print)
|
||||
{
|
||||
/* Sanity checks of failures. Mingw lacks symlink, but areadlink can
|
||||
still distinguish between various errors. */
|
||||
errno = 0;
|
||||
ASSERT (func ("no_such", 1) == NULL);
|
||||
ASSERT (errno == ENOENT);
|
||||
errno = 0;
|
||||
ASSERT (func ("no_such/", 1) == NULL);
|
||||
ASSERT (errno == ENOENT);
|
||||
errno = 0;
|
||||
ASSERT (func ("", 1) == NULL);
|
||||
ASSERT (errno == ENOENT || errno == EINVAL);
|
||||
errno = 0;
|
||||
ASSERT (func (".", 1) == NULL);
|
||||
ASSERT (errno == EINVAL);
|
||||
errno = 0;
|
||||
ASSERT (func ("./", 1) == NULL);
|
||||
ASSERT (errno == EINVAL);
|
||||
ASSERT (close (creat (BASE "file", 0600)) == 0);
|
||||
errno = 0;
|
||||
ASSERT (func (BASE "file", 1) == NULL);
|
||||
ASSERT (errno == EINVAL);
|
||||
errno = 0;
|
||||
ASSERT (func (BASE "file/", 1) == NULL);
|
||||
ASSERT (errno == ENOTDIR || errno == EINVAL); /* AIX yields EINVAL */
|
||||
ASSERT (unlink (BASE "file") == 0);
|
||||
|
||||
/* Now test actual symlinks. */
|
||||
if (symlink (BASE "dir", BASE "link"))
|
||||
{
|
||||
if (print)
|
||||
fputs ("skipping test: symlinks not supported on this file system\n",
|
||||
stderr);
|
||||
return 77;
|
||||
}
|
||||
ASSERT (mkdir (BASE "dir", 0700) == 0);
|
||||
errno = 0;
|
||||
ASSERT (func (BASE "link/", 1) == NULL);
|
||||
ASSERT (errno == EINVAL);
|
||||
{
|
||||
/* Too small a guess is okay. */
|
||||
char *buf = func (BASE "link", 1);
|
||||
ASSERT (buf);
|
||||
ASSERT (strcmp (buf, BASE "dir") == 0);
|
||||
free (buf);
|
||||
/* Too large a guess is okay. */
|
||||
buf = func (BASE "link", 10000000);
|
||||
ASSERT (buf);
|
||||
ASSERT (strcmp (buf, BASE "dir") == 0);
|
||||
free (buf);
|
||||
}
|
||||
ASSERT (rmdir (BASE "dir") == 0);
|
||||
ASSERT (unlink (BASE "link") == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Test of exact or abbreviated match search.
|
||||
Copyright (C) 1990, 1998-1999, 2001-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007, based on test code
|
||||
by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "argmatch.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
/* Some packages define ARGMATCH_DIE and ARGMATCH_DIE_DECL in <config.h>, and
|
||||
thus must link with a definition of that function. Provide it here. */
|
||||
#ifdef ARGMATCH_DIE_DECL
|
||||
|
||||
_Noreturn ARGMATCH_DIE_DECL;
|
||||
ARGMATCH_DIE_DECL { exit (1); }
|
||||
|
||||
#endif
|
||||
|
||||
enum backup_type
|
||||
{
|
||||
no_backups,
|
||||
simple_backups,
|
||||
numbered_existing_backups,
|
||||
numbered_backups
|
||||
};
|
||||
|
||||
static const char *const backup_args[] =
|
||||
{
|
||||
"no", "none", "off",
|
||||
"simple", "never", "single",
|
||||
"existing", "nil", "numbered-existing",
|
||||
"numbered", "t", "newstyle",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const enum backup_type backup_vals[] =
|
||||
{
|
||||
no_backups, no_backups, no_backups,
|
||||
simple_backups, simple_backups, simple_backups,
|
||||
numbered_existing_backups, numbered_existing_backups, numbered_existing_backups,
|
||||
numbered_backups, numbered_backups, numbered_backups
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
/* Not found. */
|
||||
ASSERT (ARGMATCH ("klingon", backup_args, backup_vals) == -1);
|
||||
|
||||
/* Exact match. */
|
||||
ASSERT (ARGMATCH ("none", backup_args, backup_vals) == 1);
|
||||
ASSERT (ARGMATCH ("nil", backup_args, backup_vals) == 7);
|
||||
|
||||
/* Too long. */
|
||||
ASSERT (ARGMATCH ("nilpotent", backup_args, backup_vals) == -1);
|
||||
|
||||
/* Abbreviated. */
|
||||
ASSERT (ARGMATCH ("simpl", backup_args, backup_vals) == 3);
|
||||
ASSERT (ARGMATCH ("simp", backup_args, backup_vals) == 3);
|
||||
ASSERT (ARGMATCH ("sim", backup_args, backup_vals) == 3);
|
||||
|
||||
/* Exact match and abbreviated. */
|
||||
ASSERT (ARGMATCH ("numbered", backup_args, backup_vals) == 9);
|
||||
ASSERT (ARGMATCH ("numbere", backup_args, backup_vals) == -2);
|
||||
ASSERT (ARGMATCH ("number", backup_args, backup_vals) == -2);
|
||||
ASSERT (ARGMATCH ("numbe", backup_args, backup_vals) == -2);
|
||||
ASSERT (ARGMATCH ("numb", backup_args, backup_vals) == -2);
|
||||
ASSERT (ARGMATCH ("num", backup_args, backup_vals) == -2);
|
||||
ASSERT (ARGMATCH ("nu", backup_args, backup_vals) == -2);
|
||||
ASSERT (ARGMATCH ("n", backup_args, backup_vals) == -2);
|
||||
|
||||
/* Ambiguous abbreviated. */
|
||||
ASSERT (ARGMATCH ("ne", backup_args, backup_vals) == -2);
|
||||
|
||||
/* Ambiguous abbreviated, but same value. */
|
||||
ASSERT (ARGMATCH ("si", backup_args, backup_vals) == 3);
|
||||
ASSERT (ARGMATCH ("s", backup_args, backup_vals) == 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Test of <arpa/inet.h> substitute.
|
||||
Copyright (C) 2007, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Test of binary mode I/O.
|
||||
Copyright (C) 2005, 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "binary-io.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
/* Test the O_BINARY macro. */
|
||||
{
|
||||
int fd =
|
||||
open ("t-bin-out0.tmp", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600);
|
||||
if (write (fd, "Hello\n", 6) < 0)
|
||||
exit (1);
|
||||
close (fd);
|
||||
}
|
||||
{
|
||||
struct stat statbuf;
|
||||
if (stat ("t-bin-out0.tmp", &statbuf) < 0)
|
||||
exit (1);
|
||||
ASSERT (statbuf.st_size == 6);
|
||||
}
|
||||
|
||||
switch (argv[1][0])
|
||||
{
|
||||
case '1':
|
||||
/* Test the set_binary_mode() function. */
|
||||
set_binary_mode (1, O_BINARY);
|
||||
fputs ("Hello\n", stdout);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
tmpfiles=""
|
||||
trap 'rm -fr $tmpfiles' 1 2 3 15
|
||||
|
||||
tmpfiles="$tmpfiles t-bin-out0.tmp t-bin-out1.tmp"
|
||||
./test-binary-io${EXEEXT} 1 > t-bin-out1.tmp || exit 1
|
||||
cmp t-bin-out0.tmp t-bin-out1.tmp > /dev/null || exit 1
|
||||
|
||||
rm -fr $tmpfiles
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Test binding a server socket to a port.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (bind, int, (int, const struct sockaddr *, socklen_t));
|
||||
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
(void) gl_sockets_startup (SOCKETS_1_1);
|
||||
|
||||
/* Test behaviour for invalid file descriptors. */
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
inet_pton (AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||
addr.sin_port = htons (80);
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (bind (-1, (const struct sockaddr *) &addr, sizeof (addr)) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
{
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (bind (99, (const struct sockaddr *) &addr, sizeof (addr)) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
/* Test of <bitrotate.h> substitute.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Simon Josefsson <simon@josefsson.org>, 2008. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "bitrotate.h"
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
ASSERT (rotl8 (42, 0) == 42);
|
||||
ASSERT (rotl8 (42, 1) == 84);
|
||||
ASSERT (rotl8 (42, 2) == 168);
|
||||
ASSERT (rotl8 (42, 3) == 81);
|
||||
ASSERT (rotl8 (42, 4) == 162);
|
||||
ASSERT (rotl8 (42, 5) == 69);
|
||||
ASSERT (rotl8 (42, 6) == 138);
|
||||
ASSERT (rotl8 (42, 7) == 21);
|
||||
ASSERT (rotl8 (42, 8) == 42);
|
||||
|
||||
ASSERT (rotr8 (42, 0) == 42);
|
||||
ASSERT (rotr8 (42, 1) == 21);
|
||||
ASSERT (rotr8 (42, 2) == 138);
|
||||
ASSERT (rotr8 (42, 3) == 69);
|
||||
ASSERT (rotr8 (42, 4) == 162);
|
||||
ASSERT (rotr8 (42, 5) == 81);
|
||||
ASSERT (rotr8 (42, 6) == 168);
|
||||
ASSERT (rotr8 (42, 7) == 84);
|
||||
ASSERT (rotr8 (42, 8) == 42);
|
||||
|
||||
ASSERT (rotl16 (43981, 0) == 43981);
|
||||
ASSERT (rotl16 (43981, 1) == 22427);
|
||||
ASSERT (rotl16 (43981, 2) == 44854);
|
||||
ASSERT (rotl16 (43981, 3) == 24173);
|
||||
ASSERT (rotl16 (43981, 4) == 48346);
|
||||
ASSERT (rotl16 (43981, 5) == 31157);
|
||||
ASSERT (rotl16 (43981, 6) == 62314);
|
||||
ASSERT (rotl16 (43981, 7) == 59093);
|
||||
ASSERT (rotl16 (43981, 8) == 52651);
|
||||
ASSERT (rotl16 (43981, 9) == 39767);
|
||||
ASSERT (rotl16 (43981, 10) == 13999);
|
||||
ASSERT (rotl16 (43981, 11) == 27998);
|
||||
ASSERT (rotl16 (43981, 12) == 55996);
|
||||
ASSERT (rotl16 (43981, 13) == 46457);
|
||||
ASSERT (rotl16 (43981, 14) == 27379);
|
||||
ASSERT (rotl16 (43981, 15) == 54758);
|
||||
ASSERT (rotl16 (43981, 16) == 43981);
|
||||
|
||||
ASSERT (rotr16 (43981, 0) == 43981);
|
||||
ASSERT (rotr16 (43981, 1) == 54758);
|
||||
ASSERT (rotr16 (43981, 2) == 27379);
|
||||
ASSERT (rotr16 (43981, 3) == 46457);
|
||||
ASSERT (rotr16 (43981, 4) == 55996);
|
||||
ASSERT (rotr16 (43981, 5) == 27998);
|
||||
ASSERT (rotr16 (43981, 6) == 13999);
|
||||
ASSERT (rotr16 (43981, 7) == 39767);
|
||||
ASSERT (rotr16 (43981, 8) == 52651);
|
||||
ASSERT (rotr16 (43981, 9) == 59093);
|
||||
ASSERT (rotr16 (43981, 10) == 62314);
|
||||
ASSERT (rotr16 (43981, 11) == 31157);
|
||||
ASSERT (rotr16 (43981, 12) == 48346);
|
||||
ASSERT (rotr16 (43981, 13) == 24173);
|
||||
ASSERT (rotr16 (43981, 14) == 44854);
|
||||
ASSERT (rotr16 (43981, 15) == 22427);
|
||||
ASSERT (rotr16 (43981, 16) == 43981);
|
||||
|
||||
ASSERT (rotl32 (2309737967U, 1) == 324508639U);
|
||||
ASSERT (rotl32 (2309737967U, 2) == 649017278U);
|
||||
ASSERT (rotl32 (2309737967U, 3) == 1298034556U);
|
||||
ASSERT (rotl32 (2309737967U, 4) == 2596069112U);
|
||||
ASSERT (rotl32 (2309737967U, 5) == 897170929U);
|
||||
ASSERT (rotl32 (2309737967U, 6) == 1794341858U);
|
||||
ASSERT (rotl32 (2309737967U, 7) == 3588683716U);
|
||||
ASSERT (rotl32 (2309737967U, 8) == 2882400137U);
|
||||
ASSERT (rotl32 (2309737967U, 9) == 1469832979U);
|
||||
ASSERT (rotl32 (2309737967U, 10) == 2939665958U);
|
||||
ASSERT (rotl32 (2309737967U, 11) == 1584364621U);
|
||||
ASSERT (rotl32 (2309737967U, 12) == 3168729242U);
|
||||
ASSERT (rotl32 (2309737967U, 13) == 2042491189U);
|
||||
ASSERT (rotl32 (2309737967U, 14) == 4084982378U);
|
||||
ASSERT (rotl32 (2309737967U, 15) == 3874997461U);
|
||||
ASSERT (rotl32 (2309737967U, 16) == 3455027627U);
|
||||
ASSERT (rotl32 (2309737967U, 17) == 2615087959U);
|
||||
ASSERT (rotl32 (2309737967U, 18) == 935208623U);
|
||||
ASSERT (rotl32 (2309737967U, 19) == 1870417246U);
|
||||
ASSERT (rotl32 (2309737967U, 20) == 3740834492U);
|
||||
ASSERT (rotl32 (2309737967U, 21) == 3186701689U);
|
||||
ASSERT (rotl32 (2309737967U, 22) == 2078436083U);
|
||||
ASSERT (rotl32 (2309737967U, 23) == 4156872166U);
|
||||
ASSERT (rotl32 (2309737967U, 24) == 4018777037U);
|
||||
ASSERT (rotl32 (2309737967U, 25) == 3742586779U);
|
||||
ASSERT (rotl32 (2309737967U, 26) == 3190206263U);
|
||||
ASSERT (rotl32 (2309737967U, 27) == 2085445231U);
|
||||
ASSERT (rotl32 (2309737967U, 28) == 4170890462U);
|
||||
ASSERT (rotl32 (2309737967U, 29) == 4046813629U);
|
||||
ASSERT (rotl32 (2309737967U, 30) == 3798659963U);
|
||||
ASSERT (rotl32 (2309737967U, 31) == 3302352631U);
|
||||
|
||||
ASSERT (rotr32 (2309737967U, 1) == 3302352631lU);
|
||||
ASSERT (rotr32 (2309737967U, 2) == 3798659963lU);
|
||||
ASSERT (rotr32 (2309737967U, 3) == 4046813629lU);
|
||||
ASSERT (rotr32 (2309737967U, 4) == 4170890462lU);
|
||||
ASSERT (rotr32 (2309737967U, 5) == 2085445231lU);
|
||||
ASSERT (rotr32 (2309737967U, 6) == 3190206263lU);
|
||||
ASSERT (rotr32 (2309737967U, 7) == 3742586779lU);
|
||||
ASSERT (rotr32 (2309737967U, 8) == 4018777037lU);
|
||||
ASSERT (rotr32 (2309737967U, 9) == 4156872166lU);
|
||||
ASSERT (rotr32 (2309737967U, 10) == 2078436083lU);
|
||||
ASSERT (rotr32 (2309737967U, 11) == 3186701689lU);
|
||||
ASSERT (rotr32 (2309737967U, 12) == 3740834492lU);
|
||||
ASSERT (rotr32 (2309737967U, 13) == 1870417246lU);
|
||||
ASSERT (rotr32 (2309737967U, 14) == 935208623lU);
|
||||
ASSERT (rotr32 (2309737967U, 15) == 2615087959lU);
|
||||
ASSERT (rotr32 (2309737967U, 16) == 3455027627lU);
|
||||
ASSERT (rotr32 (2309737967U, 17) == 3874997461lU);
|
||||
ASSERT (rotr32 (2309737967U, 18) == 4084982378lU);
|
||||
ASSERT (rotr32 (2309737967U, 19) == 2042491189lU);
|
||||
ASSERT (rotr32 (2309737967U, 20) == 3168729242lU);
|
||||
ASSERT (rotr32 (2309737967U, 21) == 1584364621lU);
|
||||
ASSERT (rotr32 (2309737967U, 22) == 2939665958lU);
|
||||
ASSERT (rotr32 (2309737967U, 23) == 1469832979lU);
|
||||
ASSERT (rotr32 (2309737967U, 24) == 2882400137lU);
|
||||
ASSERT (rotr32 (2309737967U, 25) == 3588683716lU);
|
||||
ASSERT (rotr32 (2309737967U, 26) == 1794341858lU);
|
||||
ASSERT (rotr32 (2309737967U, 27) == 897170929lU);
|
||||
ASSERT (rotr32 (2309737967U, 28) == 2596069112lU);
|
||||
ASSERT (rotr32 (2309737967U, 29) == 1298034556lU);
|
||||
ASSERT (rotr32 (2309737967U, 30) == 649017278lU);
|
||||
ASSERT (rotr32 (2309737967U, 31) == 324508639lU);
|
||||
|
||||
#ifdef UINT64_MAX
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 1) == 13644637895296644477ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 2) == 8842531716883737339ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 3) == 17685063433767474678ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 4) == 16923382793825397741ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 5) == 15400021513941243867ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 6) == 12353298954172936119ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 7) == 6259853834636320623ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 8) == 12519707669272641246ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 9) == 6592671264835730877ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 10) == 13185342529671461754ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 11) == 7923940985633371893ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 12) == 15847881971266743786ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 13) == 13249019868823935957ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 14) == 8051295663938320299ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 15) == 16102591327876640598ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 16) == 13758438582043729581ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 17) == 9070133090377907547ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 18) == 18140266180755815094ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 19) == 17833788287802078573ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 20) == 17220832501894605531ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 21) == 15994920930079659447ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 22) == 13543097786449767279ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 23) == 8639451499189982943ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 24) == 17278902998379965886ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 25) == 16111061923050380157ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 26) == 13775379772391208699ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 27) == 9104015471072865783ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 28) == 18208030942145731566ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 29) == 17969317810581911517ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 30) == 17491891547454271419ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 31) == 16537039021198991223ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 32) == 14627333968688430831ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 33) == 10807923863667310047ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 34) == 3169103653625068479ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 35) == 6338207307250136958ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 36) == 12676414614500273916ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 37) == 6906085155290996217ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 38) == 13812170310581992434ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 39) == 9177596547454433253ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 40) == 18355193094908866506ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 41) == 18263642116108181397ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 42) == 18080540158506811179ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 43) == 17714336243304070743ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 44) == 16981928412898589871ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 45) == 15517112752087628127ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 46) == 12587481430465704639ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 47) == 6728218787221857663ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 48) == 13456437574443715326ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 49) == 8466131075177879037ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 50) == 16932262150355758074ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 51) == 15417780227001964533ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 52) == 12388816380294377451ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 53) == 6330888686879203287ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 54) == 12661777373758406574ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 55) == 6876810673807261533ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 56) == 13753621347614523066ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 57) == 9060498621519494517ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 58) == 18120997243038989034ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 59) == 17795250412368426453ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 60) == 17143756751027301291ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 61) == 15840769428345050967ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 62) == 13234794782980550319ULL);
|
||||
ASSERT (rotl64 (16045690984503098046ULL, 63) == 8022845492251549023ULL);
|
||||
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 1) == 8022845492251549023ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 2) == 13234794782980550319ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 3) == 15840769428345050967ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 4) == 17143756751027301291ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 5) == 17795250412368426453ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 6) == 18120997243038989034ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 7) == 9060498621519494517ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 8) == 13753621347614523066ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 9) == 6876810673807261533ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 10) == 12661777373758406574ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 11) == 6330888686879203287ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 12) == 12388816380294377451ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 13) == 15417780227001964533ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 14) == 16932262150355758074ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 15) == 8466131075177879037ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 16) == 13456437574443715326ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 17) == 6728218787221857663ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 18) == 12587481430465704639ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 19) == 15517112752087628127ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 20) == 16981928412898589871ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 21) == 17714336243304070743ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 22) == 18080540158506811179ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 23) == 18263642116108181397ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 24) == 18355193094908866506ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 25) == 9177596547454433253ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 26) == 13812170310581992434ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 27) == 6906085155290996217ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 28) == 12676414614500273916ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 29) == 6338207307250136958ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 30) == 3169103653625068479ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 31) == 10807923863667310047ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 32) == 14627333968688430831ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 33) == 16537039021198991223ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 34) == 17491891547454271419ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 35) == 17969317810581911517ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 36) == 18208030942145731566ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 37) == 9104015471072865783ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 38) == 13775379772391208699ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 39) == 16111061923050380157ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 40) == 17278902998379965886ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 41) == 8639451499189982943ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 42) == 13543097786449767279ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 43) == 15994920930079659447ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 44) == 17220832501894605531ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 45) == 17833788287802078573ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 46) == 18140266180755815094ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 47) == 9070133090377907547ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 48) == 13758438582043729581ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 49) == 16102591327876640598ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 50) == 8051295663938320299ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 51) == 13249019868823935957ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 52) == 15847881971266743786ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 53) == 7923940985633371893ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 54) == 13185342529671461754ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 55) == 6592671264835730877ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 56) == 12519707669272641246ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 57) == 6259853834636320623ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 58) == 12353298954172936119ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 59) == 15400021513941243867ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 60) == 16923382793825397741ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 61) == 17685063433767474678ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 62) == 8842531716883737339ULL);
|
||||
ASSERT (rotr64 (16045690984503098046ULL, 63) == 13644637895296644477ULL);
|
||||
#endif /* UINT64_MAX */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Test of conversion of unibyte character to wide character.
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (btowc, wint_t, (int));
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
|
||||
/* configure should already have checked that the locale is supported. */
|
||||
if (setlocale (LC_ALL, "") == NULL)
|
||||
return 1;
|
||||
|
||||
ASSERT (btowc (EOF) == WEOF);
|
||||
|
||||
if (argc > 1)
|
||||
switch (argv[1][0])
|
||||
{
|
||||
case '1':
|
||||
/* Locale encoding is ISO-8859-1 or ISO-8859-15. */
|
||||
for (c = 0; c < 0x80; c++)
|
||||
ASSERT (btowc (c) == c);
|
||||
for (c = 0xA0; c < 0x100; c++)
|
||||
ASSERT (btowc (c) != WEOF);
|
||||
return 0;
|
||||
|
||||
case '2':
|
||||
/* Locale encoding is UTF-8. */
|
||||
for (c = 0; c < 0x80; c++)
|
||||
ASSERT (btowc (c) == c);
|
||||
for (c = 0x80; c < 0x100; c++)
|
||||
ASSERT (btowc (c) == WEOF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Test in an ISO-8859-1 or ISO-8859-15 locale.
|
||||
: ${LOCALE_FR=fr_FR}
|
||||
if test $LOCALE_FR = none; then
|
||||
if test -f /usr/bin/localedef; then
|
||||
echo "Skipping test: no traditional french locale is installed"
|
||||
else
|
||||
echo "Skipping test: no traditional french locale is supported"
|
||||
fi
|
||||
exit 77
|
||||
fi
|
||||
|
||||
LC_ALL=$LOCALE_FR \
|
||||
./test-btowc${EXEEXT} 1
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Test whether a specific UTF-8 locale is installed.
|
||||
: ${LOCALE_FR_UTF8=fr_FR.UTF-8}
|
||||
if test $LOCALE_FR_UTF8 = none; then
|
||||
if test -f /usr/bin/localedef; then
|
||||
echo "Skipping test: no french Unicode locale is installed"
|
||||
else
|
||||
echo "Skipping test: no french Unicode locale is supported"
|
||||
fi
|
||||
exit 77
|
||||
fi
|
||||
|
||||
LC_ALL=$LOCALE_FR_UTF8 \
|
||||
./test-btowc${EXEEXT} 2
|
||||
@@ -0,0 +1,228 @@
|
||||
/* Test of character handling in C locale.
|
||||
Copyright (C) 2005, 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2005. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
static void
|
||||
test_agree_with_C_locale (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c <= UCHAR_MAX; c++)
|
||||
{
|
||||
ASSERT (c_isascii (c) == (isascii (c) != 0));
|
||||
if (c_isascii (c))
|
||||
{
|
||||
ASSERT (c_isalnum (c) == (isalnum (c) != 0));
|
||||
ASSERT (c_isalpha (c) == (isalpha (c) != 0));
|
||||
ASSERT (c_isblank (c) == (isblank (c) != 0));
|
||||
ASSERT (c_iscntrl (c) == (iscntrl (c) != 0));
|
||||
ASSERT (c_isdigit (c) == (isdigit (c) != 0));
|
||||
ASSERT (c_islower (c) == (islower (c) != 0));
|
||||
ASSERT (c_isgraph (c) == (isgraph (c) != 0));
|
||||
ASSERT (c_isprint (c) == (isprint (c) != 0));
|
||||
ASSERT (c_ispunct (c) == (ispunct (c) != 0));
|
||||
ASSERT (c_isspace (c) == (isspace (c) != 0));
|
||||
ASSERT (c_isupper (c) == (isupper (c) != 0));
|
||||
ASSERT (c_isxdigit (c) == (isxdigit (c) != 0));
|
||||
ASSERT (c_tolower (c) == tolower (c));
|
||||
ASSERT (c_toupper (c) == toupper (c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_all (void)
|
||||
{
|
||||
int c;
|
||||
int n_isascii = 0;
|
||||
|
||||
for (c = CHAR_MIN; c <= UCHAR_MAX; c++)
|
||||
{
|
||||
if (! (0 <= c && c <= CHAR_MAX))
|
||||
{
|
||||
ASSERT (! c_isascii (c));
|
||||
ASSERT (! c_isalnum (c));
|
||||
ASSERT (! c_isalpha (c));
|
||||
ASSERT (! c_isblank (c));
|
||||
ASSERT (! c_iscntrl (c));
|
||||
ASSERT (! c_isdigit (c));
|
||||
ASSERT (! c_islower (c));
|
||||
ASSERT (! c_isgraph (c));
|
||||
ASSERT (! c_isprint (c));
|
||||
ASSERT (! c_ispunct (c));
|
||||
ASSERT (! c_isspace (c));
|
||||
ASSERT (! c_isupper (c));
|
||||
ASSERT (! c_isxdigit (c));
|
||||
ASSERT (c_tolower (c) == c);
|
||||
ASSERT (c_toupper (c) == c);
|
||||
}
|
||||
|
||||
n_isascii += c_isascii (c);
|
||||
|
||||
#ifdef C_CTYPE_ASCII
|
||||
ASSERT (c_isascii (c) == (0 <= c && c <= 0x7f));
|
||||
#endif
|
||||
|
||||
ASSERT (c_isascii (c) == (c_isprint (c) || c_iscntrl (c)));
|
||||
|
||||
ASSERT (c_isalnum (c) == (c_isalpha (c) || c_isdigit (c)));
|
||||
|
||||
ASSERT (c_isalpha (c) == (c_islower (c) || c_isupper (c)));
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\t': case ' ':
|
||||
ASSERT (c_isblank (c) == 1);
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_isblank (c) == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef C_CTYPE_ASCII
|
||||
ASSERT (c_iscntrl (c) == ((c >= 0 && c < 0x20) || c == 0x7f));
|
||||
#endif
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\a': case '\b': case '\f': case '\n':
|
||||
case '\r': case '\t': case '\v':
|
||||
ASSERT (c_iscntrl (c));
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT (! (c_iscntrl (c) && c_isprint (c)));
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
ASSERT (c_isdigit (c) == 1);
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_isdigit (c) == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
||||
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
|
||||
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
|
||||
case 'y': case 'z':
|
||||
ASSERT (c_islower (c) == 1);
|
||||
ASSERT (c_toupper (c) == c - 'a' + 'A');
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_islower (c) == 0);
|
||||
ASSERT (c_toupper (c) == c);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef C_CTYPE_ASCII
|
||||
ASSERT (c_isgraph (c) == ((c >= 0x20 && c < 0x7f) && c != ' '));
|
||||
|
||||
ASSERT (c_isprint (c) == (c >= 0x20 && c < 0x7f));
|
||||
#endif
|
||||
|
||||
ASSERT (c_isgraph (c) == (c_isalnum (c) || c_ispunct (c)));
|
||||
|
||||
ASSERT (c_isprint (c) == (c_isgraph (c) || c == ' '));
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '!': case '"': case '#': case '$': case '%': case '&': case '\'':
|
||||
case '(': case ')': case '*': case '+': case ',': case '-': case '.':
|
||||
case '/': case ':': case ';': case '<': case '=': case '>': case '?':
|
||||
case '@': case '[': case'\\': case ']': case '^': case '_': case '`':
|
||||
case '{': case '|': case '}': case '~':
|
||||
ASSERT (c_ispunct (c) == 1);
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_ispunct (c) == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
|
||||
ASSERT (c_isspace (c) == 1);
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_isspace (c) == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
|
||||
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
ASSERT (c_isupper (c) == 1);
|
||||
ASSERT (c_tolower (c) == c - 'A' + 'a');
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_isupper (c) == 0);
|
||||
ASSERT (c_tolower (c) == c);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
ASSERT (c_isxdigit (c) == 1);
|
||||
break;
|
||||
default:
|
||||
ASSERT (c_isxdigit (c) == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT (n_isascii == 128);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
test_agree_with_C_locale ();
|
||||
|
||||
test_all ();
|
||||
|
||||
setlocale (LC_ALL, "de_DE");
|
||||
test_all ();
|
||||
|
||||
setlocale (LC_ALL, "ja_JP.EUC-JP");
|
||||
test_all ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/* Test of c-stack module.
|
||||
Copyright (C) 2002, 2004, 2006, 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "c-stack.h"
|
||||
|
||||
#include "exitfail.h"
|
||||
#include <stdio.h>
|
||||
#if HAVE_SETRLIMIT
|
||||
/* At least FreeBSD 5.0 needs extra headers before <sys/resource.h>
|
||||
will compile. */
|
||||
# include <sys/types.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
static volatile int *
|
||||
recurse_1 (volatile int n, volatile int *p)
|
||||
{
|
||||
if (n >= 0)
|
||||
*recurse_1 (n + 1, p) += n;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
recurse (volatile int n)
|
||||
{
|
||||
int sum = 0;
|
||||
return *recurse_1 (n, &sum);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
#if HAVE_SETRLIMIT && defined RLIMIT_STACK
|
||||
/* Before starting the endless recursion, try to be friendly to the
|
||||
user's machine. On some Linux 2.2.x systems, there is no stack
|
||||
limit for user processes at all. We don't want to kill such
|
||||
systems. */
|
||||
struct rlimit rl;
|
||||
rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
|
||||
setrlimit (RLIMIT_STACK, &rl);
|
||||
#endif
|
||||
|
||||
if (c_stack_action (NULL) == 0)
|
||||
{
|
||||
if (1 < argc)
|
||||
{
|
||||
exit_failure = 77;
|
||||
++*argv[argc]; /* Intentionally dereference NULL. */
|
||||
}
|
||||
return recurse (0);
|
||||
}
|
||||
fputs ("skipping test: ", stderr);
|
||||
perror ("c_stack_action");
|
||||
return 77;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
tmpfiles=""
|
||||
trap 'rm -fr $tmpfiles' 1 2 3 15
|
||||
|
||||
tmpfiles="t-c-stack.tmp"
|
||||
./test-c-stack${EXEEXT} 2> t-c-stack.tmp
|
||||
case $? in
|
||||
77) cat t-c-stack.tmp >&2; (exit 77); exit 77 ;;
|
||||
1) ;;
|
||||
*) (exit 1); exit 1 ;;
|
||||
esac
|
||||
if grep 'stack overflow' t-c-stack.tmp >/dev/null ; then
|
||||
:
|
||||
else
|
||||
(exit 1); exit 1
|
||||
fi
|
||||
|
||||
rm -fr $tmpfiles
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
|
||||
tmpfiles=""
|
||||
trap 'rm -fr $tmpfiles' 1 2 3 15
|
||||
|
||||
tmpfiles="t-c-stack2.tmp"
|
||||
|
||||
# Sanitize exit status within a subshell, since some shells fail to
|
||||
# redirect stderr on their message about death due to signal.
|
||||
(./test-c-stack${EXEEXT} 1; exit $?) 2> t-c-stack2.tmp
|
||||
|
||||
case $? in
|
||||
77) if grep 'stack overflow' t-c-stack2.tmp >/dev/null ; then
|
||||
if test -z "$LIBSIGSEGV"; then
|
||||
echo 'cannot tell stack overflow from crash; consider installing libsigsegv' >&2
|
||||
exit 77
|
||||
else
|
||||
echo 'cannot tell stack overflow from crash, in spite of libsigsegv' >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
cat t-c-stack2.tmp >&2
|
||||
exit 77
|
||||
fi
|
||||
;;
|
||||
0) (exit 1); exit 1 ;;
|
||||
esac
|
||||
if grep 'program error' t-c-stack2.tmp >/dev/null ; then
|
||||
:
|
||||
else
|
||||
(exit 1); exit 1
|
||||
fi
|
||||
|
||||
rm -fr $tmpfiles
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Test in the C locale.
|
||||
./test-c-strcasecmp${EXEEXT} || exit 1
|
||||
./test-c-strncasecmp${EXEEXT} || exit 1
|
||||
|
||||
# Test in an ISO-8859-1 or ISO-8859-15 locale.
|
||||
: ${LOCALE_FR=fr_FR}
|
||||
if test $LOCALE_FR != none; then
|
||||
LC_ALL=$LOCALE_FR ./test-c-strcasecmp${EXEEXT} locale || exit 1
|
||||
LC_ALL=$LOCALE_FR ./test-c-strncasecmp${EXEEXT} locale || exit 1
|
||||
fi
|
||||
|
||||
# Test in a Turkish UTF-8 locale.
|
||||
: ${LOCALE_TR_UTF8=tr_TR.UTF-8}
|
||||
if test $LOCALE_TR_UTF8 != none; then
|
||||
LC_ALL=$LOCALE_TR_UTF8 ./test-c-strcasecmp${EXEEXT} locale || exit 1
|
||||
LC_ALL=$LOCALE_TR_UTF8 ./test-c-strncasecmp${EXEEXT} locale || exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,68 @@
|
||||
/* Test of case-insensitive string comparison function.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "c-strcase.h"
|
||||
#include "c-ctype.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
/* configure should already have checked that the locale is supported. */
|
||||
if (setlocale (LC_ALL, "") == NULL)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASSERT (c_strcasecmp ("paragraph", "Paragraph") == 0);
|
||||
|
||||
ASSERT (c_strcasecmp ("paragrapH", "parAgRaph") == 0);
|
||||
|
||||
ASSERT (c_strcasecmp ("paragraph", "paraLyzed") < 0);
|
||||
ASSERT (c_strcasecmp ("paraLyzed", "paragraph") > 0);
|
||||
|
||||
ASSERT (c_strcasecmp ("para", "paragraph") < 0);
|
||||
ASSERT (c_strcasecmp ("paragraph", "para") > 0);
|
||||
|
||||
/* The following tests shows how c_strcasecmp() is different from
|
||||
strcasecmp(). */
|
||||
|
||||
ASSERT (c_strcasecmp ("\311mile", "\351mile") < 0);
|
||||
ASSERT (c_strcasecmp ("\351mile", "\311mile") > 0);
|
||||
|
||||
/* The following tests shows how c_strcasecmp() is different from
|
||||
mbscasecmp(). */
|
||||
|
||||
ASSERT (c_strcasecmp ("\303\266zg\303\274r", "\303\226ZG\303\234R") > 0); /* özgür */
|
||||
ASSERT (c_strcasecmp ("\303\226ZG\303\234R", "\303\266zg\303\274r") < 0); /* özgür */
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
/* This test shows how strings of different size cannot compare equal. */
|
||||
ASSERT (c_strcasecmp ("turkish", "TURK\304\260SH") < 0);
|
||||
ASSERT (c_strcasecmp ("TURK\304\260SH", "turkish") > 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/* Test of case-insensitive string comparison function.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "c-strcase.h"
|
||||
#include "c-ctype.h"
|
||||
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
if (argc > 1)
|
||||
{
|
||||
/* configure should already have checked that the locale is supported. */
|
||||
if (setlocale (LC_ALL, "") == NULL)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASSERT (c_strncasecmp ("paragraph", "Paragraph", 1000000) == 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "Paragraph", 9) == 0);
|
||||
|
||||
ASSERT (c_strncasecmp ("paragrapH", "parAgRaph", 1000000) == 0);
|
||||
ASSERT (c_strncasecmp ("paragrapH", "parAgRaph", 9) == 0);
|
||||
|
||||
ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 10) < 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 9) < 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 5) < 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "paraLyzed", 4) == 0);
|
||||
ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 10) > 0);
|
||||
ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 9) > 0);
|
||||
ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 5) > 0);
|
||||
ASSERT (c_strncasecmp ("paraLyzed", "paragraph", 4) == 0);
|
||||
|
||||
ASSERT (c_strncasecmp ("para", "paragraph", 10) < 0);
|
||||
ASSERT (c_strncasecmp ("para", "paragraph", 9) < 0);
|
||||
ASSERT (c_strncasecmp ("para", "paragraph", 5) < 0);
|
||||
ASSERT (c_strncasecmp ("para", "paragraph", 4) == 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "para", 10) > 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "para", 9) > 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "para", 5) > 0);
|
||||
ASSERT (c_strncasecmp ("paragraph", "para", 4) == 0);
|
||||
|
||||
/* The following tests shows how c_strncasecmp() is different from
|
||||
strncasecmp(). */
|
||||
|
||||
ASSERT (c_strncasecmp ("\311mily", "\351mile", 4) < 0);
|
||||
ASSERT (c_strncasecmp ("\351mile", "\311mily", 4) > 0);
|
||||
|
||||
/* The following tests shows how c_strncasecmp() is different from
|
||||
mbsncasecmp(). */
|
||||
|
||||
ASSERT (c_strncasecmp ("\303\266zg\303\274r", "\303\226ZG\303\234R", 99) > 0); /* özgür */
|
||||
ASSERT (c_strncasecmp ("\303\226ZG\303\234R", "\303\266zg\303\274r", 99) < 0); /* özgür */
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
/* This test shows how strings of different size cannot compare equal. */
|
||||
ASSERT (c_strncasecmp ("turkish", "TURK\304\260SH", 7) < 0);
|
||||
ASSERT (c_strncasecmp ("TURK\304\260SH", "turkish", 7) > 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Test closing a file or socket.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (close, int, (int));
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Test behaviour for invalid file descriptors. */
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (close (-1) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
{
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (close (99) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Test connecting a client socket.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (connect, int, (int, const struct sockaddr *, socklen_t));
|
||||
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sockets.h"
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
(void) gl_sockets_startup (SOCKETS_1_1);
|
||||
|
||||
/* Test behaviour for invalid file descriptors. */
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
inet_pton (AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||
addr.sin_port = htons (80);
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (connect (-1, (const struct sockaddr *) &addr, sizeof (addr))
|
||||
== -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
{
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (connect (99, (const struct sockaddr *) &addr, sizeof (addr))
|
||||
== -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Test of <ctype.h> substitute.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/* Test the gnulib dirname module.
|
||||
Copyright (C) 2005-2007, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct test {
|
||||
const char *name; /* Name under test. */
|
||||
const char *dir; /* dir_name (name). */
|
||||
const char *last; /* last_component (name). */
|
||||
const char *base; /* base_name (name). */
|
||||
const char *stripped; /* name after strip_trailing_slashes (name). */
|
||||
bool modified; /* result of strip_trailing_slashes (name). */
|
||||
bool absolute; /* IS_ABSOLUTE_FILE_NAME (name). */
|
||||
};
|
||||
|
||||
static struct test tests[] = {
|
||||
{"d/f", "d", "f", "f", "d/f", false, false},
|
||||
{"/d/f", "/d", "f", "f", "/d/f", false, true},
|
||||
{"d/f/", "d", "f/", "f/", "d/f", true, false},
|
||||
{"d/f//", "d", "f//", "f/", "d/f", true, false},
|
||||
{"f", ".", "f", "f", "f", false, false},
|
||||
{"/", "/", "", "/", "/", false, true},
|
||||
#if DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
{"//", "//", "", "//", "//", false, true},
|
||||
{"//d", "//", "d", "d", "//d", false, true},
|
||||
#else
|
||||
{"//", "/", "", "/", "/", true, true},
|
||||
{"//d", "/", "d", "d", "//d", false, true},
|
||||
#endif
|
||||
{"///", "/", "", "/", "/", true, true},
|
||||
{"///a///", "/", "a///", "a/", "///a", true, true},
|
||||
/* POSIX requires dirname("") and basename("") to both return ".",
|
||||
but dir_name and base_name are defined differently. */
|
||||
{"", ".", "", "", "", false, false},
|
||||
{".", ".", ".", ".", ".", false, false},
|
||||
{"..", ".", "..", "..", "..", false, false},
|
||||
#if ISSLASH ('\\')
|
||||
{"a\\", ".", "a\\", "a\\", "a", true, false},
|
||||
{"a\\b", "a", "b", "b", "a\\b", false, false},
|
||||
{"\\", "\\", "", "\\", "\\", false, true},
|
||||
{"\\/\\", "\\", "", "\\", "\\", true, true},
|
||||
{"\\\\/", "\\", "", "\\", "\\", true, true},
|
||||
{"\\//", "\\", "", "\\", "\\", true, true},
|
||||
{"//\\", "/", "", "/", "/", true, true},
|
||||
#else
|
||||
{"a\\", ".", "a\\", "a\\", "a\\", false, false},
|
||||
{"a\\b", ".", "a\\b", "a\\b", "a\\b", false, false},
|
||||
{"\\", ".", "\\", "\\", "\\", false, false},
|
||||
{"\\/\\", "\\", "\\", "\\", "\\/\\",false, false},
|
||||
{"\\\\/", ".", "\\\\/","\\\\/","\\\\", true, false},
|
||||
{"\\//", ".", "\\//", "\\/", "\\", true, false},
|
||||
# if DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
{"//\\", "//", "\\", "\\", "//\\", false, true},
|
||||
# else
|
||||
{"//\\", "/", "\\", "\\", "//\\", false, true},
|
||||
# endif
|
||||
#endif
|
||||
#if ISSLASH ('\\')
|
||||
# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
{"c:", "c:", "", "c:", "c:", false, false},
|
||||
{"c:/", "c:/", "", "c:/", "c:/", false, true},
|
||||
{"c://", "c:/", "", "c:/", "c:/", true, true},
|
||||
{"c:/d", "c:/", "d", "d", "c:/d", false, true},
|
||||
{"c://d", "c:/", "d", "d", "c://d",false, true},
|
||||
{"c:/d/", "c:/", "d/", "d/", "c:/d", true, true},
|
||||
{"c:/d/f", "c:/d", "f", "f", "c:/d/f",false, true},
|
||||
{"c:d", "c:.", "d", "d", "c:d", false, false},
|
||||
{"c:d/", "c:.", "d/", "d/", "c:d", true, false},
|
||||
{"c:d/f", "c:d", "f", "f", "c:d/f",false, false},
|
||||
{"a:b:c", "a:.", "b:c", "./b:c","a:b:c",false, false},
|
||||
{"a/b:c", "a", "b:c", "./b:c","a/b:c",false, false},
|
||||
{"a/b:c/", "a", "b:c/", "./b:c/","a/b:c",true, false},
|
||||
# else /* ! FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE */
|
||||
{"c:", "c:", "", "c:", "c:", false, true},
|
||||
{"c:/", "c:", "", "c:", "c:", true, true},
|
||||
{"c://", "c:", "", "c:", "c:", true, true},
|
||||
{"c:/d", "c:", "d", "d", "c:/d", false, true},
|
||||
{"c://d", "c:", "d", "d", "c://d",false, true},
|
||||
{"c:/d/", "c:", "d/", "d/", "c:/d", true, true},
|
||||
{"c:/d/f", "c:/d", "f", "f", "c:/d/f",false, true},
|
||||
{"c:d", "c:", "d", "d", "c:d", false, true},
|
||||
{"c:d/", "c:", "d/", "d/", "c:d", true, true},
|
||||
{"c:d/f", "c:d", "f", "f", "c:d/f",false, true},
|
||||
{"a:b:c", "a:", "b:c", "./b:c","a:b:c",false, true},
|
||||
{"a/b:c", "a", "b:c", "./b:c","a/b:c",false, false},
|
||||
{"a/b:c/", "a", "b:c/", "./b:c/","a/b:c",true, false},
|
||||
# endif
|
||||
#else /* ! ISSLASH ('\\') */
|
||||
{"c:", ".", "c:", "c:", "c:", false, false},
|
||||
{"c:/", ".", "c:/", "c:/", "c:", true, false},
|
||||
{"c://", ".", "c://", "c:/", "c:", true, false},
|
||||
{"c:/d", "c:", "d", "d", "c:/d", false, false},
|
||||
{"c://d", "c:", "d", "d", "c://d",false, false},
|
||||
{"c:/d/", "c:", "d/", "d/", "c:/d", true, false},
|
||||
{"c:/d/f", "c:/d", "f", "f", "c:/d/f",false, false},
|
||||
{"c:d", ".", "c:d", "c:d", "c:d", false, false},
|
||||
{"c:d/", ".", "c:d/", "c:d/", "c:d", true, false},
|
||||
{"c:d/f", "c:d", "f", "f", "c:d/f",false, false},
|
||||
{"a:b:c", ".", "a:b:c","a:b:c","a:b:c",false, false},
|
||||
{"a/b:c", "a", "b:c", "b:c", "a/b:c",false, false},
|
||||
{"a/b:c/", "a", "b:c/", "b:c/", "a/b:c",true, false},
|
||||
#endif
|
||||
{"1:", ".", "1:", "1:", "1:", false, false},
|
||||
{"1:/", ".", "1:/", "1:/", "1:", true, false},
|
||||
{"/:", "/", ":", ":", "/:", false, true},
|
||||
{"/:/", "/", ":/", ":/", "/:", true, true},
|
||||
/* End sentinel. */
|
||||
{NULL, NULL, NULL, NULL, NULL, false, false}
|
||||
};
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
struct test *t;
|
||||
bool ok = true;
|
||||
|
||||
for (t = tests; t->name; t++)
|
||||
{
|
||||
char *dir = dir_name (t->name);
|
||||
int dirlen = dir_len (t->name);
|
||||
char *last = last_component (t->name);
|
||||
char *base = base_name (t->name);
|
||||
int baselen = base_len (base);
|
||||
char *stripped = strdup (t->name);
|
||||
bool modified = strip_trailing_slashes (stripped);
|
||||
bool absolute = IS_ABSOLUTE_FILE_NAME (t->name);
|
||||
if (! (strcmp (dir, t->dir) == 0
|
||||
&& (dirlen == strlen (dir)
|
||||
|| (dirlen + 1 == strlen (dir) && dir[dirlen] == '.'))))
|
||||
{
|
||||
ok = false;
|
||||
printf ("dir_name '%s': got '%s' len %d,"
|
||||
" expected '%s' len %lu\n",
|
||||
t->name, dir, dirlen,
|
||||
t->dir, (unsigned long) strlen (t->dir));
|
||||
}
|
||||
if (strcmp (last, t->last))
|
||||
{
|
||||
ok = false;
|
||||
printf ("last_component '%s': got '%s', expected '%s'\n",
|
||||
t->name, last, t->last);
|
||||
}
|
||||
if (! (strcmp (base, t->base) == 0
|
||||
&& (baselen == strlen (base)
|
||||
|| (baselen + 1 == strlen (base)
|
||||
&& ISSLASH (base[baselen])))))
|
||||
{
|
||||
ok = false;
|
||||
printf ("base_name '%s': got '%s' len %d,"
|
||||
" expected '%s' len %lu\n",
|
||||
t->name, base, baselen,
|
||||
t->base, (unsigned long) strlen (t->base));
|
||||
}
|
||||
if (strcmp (stripped, t->stripped) || modified != t->modified)
|
||||
{
|
||||
ok = false;
|
||||
printf ("strip_trailing_slashes '%s': got %s %s, expected %s %s\n",
|
||||
t->name, stripped, modified ? "changed" : "unchanged",
|
||||
t->stripped, t->modified ? "changed" : "unchanged");
|
||||
}
|
||||
if (t->absolute != absolute)
|
||||
{
|
||||
ok = false;
|
||||
printf ("'%s': got %s, expected %s\n", t->name,
|
||||
absolute ? "absolute" : "relative",
|
||||
t->absolute ? "absolute" : "relative");
|
||||
}
|
||||
free (dir);
|
||||
free (base);
|
||||
free (stripped);
|
||||
}
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/* Test duplicating file descriptors.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (dup2, int, (int, int));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if HAVE_SYS_RESOURCE_H
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#include "binary-io.h"
|
||||
|
||||
#if GNULIB_TEST_CLOEXEC
|
||||
# include "cloexec.h"
|
||||
#endif
|
||||
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Get declarations of the native Windows API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
/* Return non-zero if FD is open. */
|
||||
static int
|
||||
is_open (int fd)
|
||||
{
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On native Windows, the initial state of unassigned standard file
|
||||
descriptors is that they are open but point to an
|
||||
INVALID_HANDLE_VALUE, and there is no fcntl. */
|
||||
return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
# ifndef F_GETFL
|
||||
# error Please port fcntl to your platform
|
||||
# endif
|
||||
return 0 <= fcntl (fd, F_GETFL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GNULIB_TEST_CLOEXEC
|
||||
/* Return non-zero if FD is open and inheritable across exec/spawn. */
|
||||
static int
|
||||
is_inheritable (int fd)
|
||||
{
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On native Windows, the initial state of unassigned standard file
|
||||
descriptors is that they are open but point to an
|
||||
INVALID_HANDLE_VALUE, and there is no fcntl. */
|
||||
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
||||
DWORD flags;
|
||||
if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
|
||||
return 0;
|
||||
return (flags & HANDLE_FLAG_INHERIT) != 0;
|
||||
# else
|
||||
# ifndef F_GETFD
|
||||
# error Please port fcntl to your platform
|
||||
# endif
|
||||
int i = fcntl (fd, F_GETFD);
|
||||
return 0 <= i && (i & FD_CLOEXEC) == 0;
|
||||
# endif
|
||||
}
|
||||
#endif /* GNULIB_TEST_CLOEXEC */
|
||||
|
||||
#if !O_BINARY
|
||||
# define setmode(f,m) zero ()
|
||||
static int zero (void) { return 0; }
|
||||
#endif
|
||||
|
||||
/* Return non-zero if FD is open in the given MODE, which is either
|
||||
O_TEXT or O_BINARY. */
|
||||
static int
|
||||
is_mode (int fd, int mode)
|
||||
{
|
||||
int value = setmode (fd, O_BINARY);
|
||||
setmode (fd, value);
|
||||
return mode == value;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
const char *file = "test-dup2.tmp";
|
||||
char buffer[1];
|
||||
int bad_fd = getdtablesize ();
|
||||
int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);
|
||||
|
||||
/* Assume std descriptors were provided by invoker. */
|
||||
ASSERT (STDERR_FILENO < fd);
|
||||
ASSERT (is_open (fd));
|
||||
/* Ignore any other fd's leaked into this process. */
|
||||
close (fd + 1);
|
||||
close (fd + 2);
|
||||
ASSERT (!is_open (fd + 1));
|
||||
ASSERT (!is_open (fd + 2));
|
||||
|
||||
/* Assigning to self must be a no-op. */
|
||||
ASSERT (dup2 (fd, fd) == fd);
|
||||
ASSERT (is_open (fd));
|
||||
|
||||
/* The source must be valid. */
|
||||
errno = 0;
|
||||
ASSERT (dup2 (-1, fd) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (dup2 (99, fd) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (dup2 (AT_FDCWD, fd) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (is_open (fd));
|
||||
|
||||
/* If the source is not open, then the destination is unaffected. */
|
||||
errno = 0;
|
||||
ASSERT (dup2 (fd + 1, fd + 1) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (!is_open (fd + 1));
|
||||
errno = 0;
|
||||
ASSERT (dup2 (fd + 1, fd) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (is_open (fd));
|
||||
|
||||
/* The destination must be valid. */
|
||||
errno = 0;
|
||||
ASSERT (dup2 (fd, -2) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
if (bad_fd > 256)
|
||||
{
|
||||
ASSERT (dup2 (fd, 255) == 255);
|
||||
ASSERT (dup2 (fd, 256) == 256);
|
||||
ASSERT (close (255) == 0);
|
||||
ASSERT (close (256) == 0);
|
||||
}
|
||||
ASSERT (dup2 (fd, bad_fd - 1) == bad_fd - 1);
|
||||
ASSERT (close (bad_fd - 1) == 0);
|
||||
errno = 0;
|
||||
ASSERT (dup2 (fd, bad_fd) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
|
||||
/* Using dup2 can skip fds. */
|
||||
ASSERT (dup2 (fd, fd + 2) == fd + 2);
|
||||
ASSERT (is_open (fd));
|
||||
ASSERT (!is_open (fd + 1));
|
||||
ASSERT (is_open (fd + 2));
|
||||
|
||||
/* Verify that dup2 closes the previous occupant of a fd. */
|
||||
ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1);
|
||||
ASSERT (dup2 (fd + 1, fd) == fd);
|
||||
ASSERT (close (fd + 1) == 0);
|
||||
ASSERT (write (fd, "1", 1) == 1);
|
||||
ASSERT (dup2 (fd + 2, fd) == fd);
|
||||
ASSERT (lseek (fd, 0, SEEK_END) == 0);
|
||||
ASSERT (write (fd + 2, "2", 1) == 1);
|
||||
ASSERT (lseek (fd, 0, SEEK_SET) == 0);
|
||||
ASSERT (read (fd, buffer, 1) == 1);
|
||||
ASSERT (*buffer == '2');
|
||||
|
||||
#if GNULIB_TEST_CLOEXEC
|
||||
/* Any new fd created by dup2 must not be cloexec. */
|
||||
ASSERT (close (fd + 2) == 0);
|
||||
ASSERT (dup_cloexec (fd) == fd + 1);
|
||||
ASSERT (!is_inheritable (fd + 1));
|
||||
ASSERT (dup2 (fd + 1, fd + 1) == fd + 1);
|
||||
ASSERT (!is_inheritable (fd + 1));
|
||||
ASSERT (dup2 (fd + 1, fd + 2) == fd + 2);
|
||||
ASSERT (!is_inheritable (fd + 1));
|
||||
ASSERT (is_inheritable (fd + 2));
|
||||
errno = 0;
|
||||
ASSERT (dup2 (fd + 1, -1) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (!is_inheritable (fd + 1));
|
||||
#endif
|
||||
|
||||
/* On systems that distinguish between text and binary mode, dup2
|
||||
reuses the mode of the source. */
|
||||
setmode (fd, O_BINARY);
|
||||
ASSERT (is_mode (fd, O_BINARY));
|
||||
ASSERT (dup2 (fd, fd + 1) == fd + 1);
|
||||
ASSERT (is_mode (fd + 1, O_BINARY));
|
||||
setmode (fd, O_TEXT);
|
||||
ASSERT (is_mode (fd, O_TEXT));
|
||||
ASSERT (dup2 (fd, fd + 1) == fd + 1);
|
||||
ASSERT (is_mode (fd + 1, O_TEXT));
|
||||
|
||||
/* Clean up. */
|
||||
ASSERT (close (fd + 2) == 0);
|
||||
ASSERT (close (fd + 1) == 0);
|
||||
ASSERT (close (fd) == 0);
|
||||
ASSERT (unlink (file) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/* Test of environ variable.
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* The environment variables that are set even in the weirdest situations
|
||||
are HOME and PATH.
|
||||
POSIX says that HOME is initialized by the system, and that PATH may be
|
||||
unset. But in practice it's more frequent to see HOME unset and PATH
|
||||
set. So we test the presence of PATH. */
|
||||
char **remaining_variables = environ;
|
||||
char *string;
|
||||
|
||||
for (; (string = *remaining_variables) != NULL; remaining_variables++)
|
||||
{
|
||||
if (strncmp (string, "PATH=", 5) == 0)
|
||||
/* Found the PATH environment variable. */
|
||||
return 0;
|
||||
}
|
||||
/* Failed to find the PATH environment variable. */
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/* Test of <errno.h> substitute.
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* Verify that the POSIX mandated errno values exist and can be used as
|
||||
initializers outside of a function.
|
||||
The variable names happen to match the Linux/x86 error numbers. */
|
||||
int e1 = EPERM;
|
||||
int e2 = ENOENT;
|
||||
int e3 = ESRCH;
|
||||
int e4 = EINTR;
|
||||
int e5 = EIO;
|
||||
int e6 = ENXIO;
|
||||
int e7 = E2BIG;
|
||||
int e8 = ENOEXEC;
|
||||
int e9 = EBADF;
|
||||
int e10 = ECHILD;
|
||||
int e11 = EAGAIN;
|
||||
int e11a = EWOULDBLOCK;
|
||||
int e12 = ENOMEM;
|
||||
int e13 = EACCES;
|
||||
int e14 = EFAULT;
|
||||
int e16 = EBUSY;
|
||||
int e17 = EEXIST;
|
||||
int e18 = EXDEV;
|
||||
int e19 = ENODEV;
|
||||
int e20 = ENOTDIR;
|
||||
int e21 = EISDIR;
|
||||
int e22 = EINVAL;
|
||||
int e23 = ENFILE;
|
||||
int e24 = EMFILE;
|
||||
int e25 = ENOTTY;
|
||||
int e26 = ETXTBSY;
|
||||
int e27 = EFBIG;
|
||||
int e28 = ENOSPC;
|
||||
int e29 = ESPIPE;
|
||||
int e30 = EROFS;
|
||||
int e31 = EMLINK;
|
||||
int e32 = EPIPE;
|
||||
int e33 = EDOM;
|
||||
int e34 = ERANGE;
|
||||
int e35 = EDEADLK;
|
||||
int e36 = ENAMETOOLONG;
|
||||
int e37 = ENOLCK;
|
||||
int e38 = ENOSYS;
|
||||
int e39 = ENOTEMPTY;
|
||||
int e40 = ELOOP;
|
||||
int e42 = ENOMSG;
|
||||
int e43 = EIDRM;
|
||||
int e67 = ENOLINK;
|
||||
int e71 = EPROTO;
|
||||
int e72 = EMULTIHOP;
|
||||
int e74 = EBADMSG;
|
||||
int e75 = EOVERFLOW;
|
||||
int e84 = EILSEQ;
|
||||
int e88 = ENOTSOCK;
|
||||
int e89 = EDESTADDRREQ;
|
||||
int e90 = EMSGSIZE;
|
||||
int e91 = EPROTOTYPE;
|
||||
int e92 = ENOPROTOOPT;
|
||||
int e93 = EPROTONOSUPPORT;
|
||||
int e95 = EOPNOTSUPP;
|
||||
int e95a = ENOTSUP;
|
||||
int e97 = EAFNOSUPPORT;
|
||||
int e98 = EADDRINUSE;
|
||||
int e99 = EADDRNOTAVAIL;
|
||||
int e100 = ENETDOWN;
|
||||
int e101 = ENETUNREACH;
|
||||
int e102 = ENETRESET;
|
||||
int e103 = ECONNABORTED;
|
||||
int e104 = ECONNRESET;
|
||||
int e105 = ENOBUFS;
|
||||
int e106 = EISCONN;
|
||||
int e107 = ENOTCONN;
|
||||
int e110 = ETIMEDOUT;
|
||||
int e111 = ECONNREFUSED;
|
||||
int e113 = EHOSTUNREACH;
|
||||
int e114 = EALREADY;
|
||||
int e115 = EINPROGRESS;
|
||||
int e116 = ESTALE;
|
||||
int e122 = EDQUOT;
|
||||
int e125 = ECANCELED;
|
||||
int e130 = EOWNERDEAD;
|
||||
int e131 = ENOTRECOVERABLE;
|
||||
|
||||
/* Don't verify that these errno values are all different, except for possibly
|
||||
EWOULDBLOCK == EAGAIN. Even Linux/x86 does not pass this check: it has
|
||||
ENOTSUP == EOPNOTSUPP. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
/* Verify that errno can be assigned. */
|
||||
errno = EOVERFLOW;
|
||||
|
||||
/* snprintf() callers want to distinguish EINVAL and EOVERFLOW. */
|
||||
if (errno == EINVAL)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/* Test suite for exclude.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
This file is part of the GNUlib Library.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include "exclude.h"
|
||||
#include "error.h"
|
||||
#include "argmatch.h"
|
||||
|
||||
#ifndef FNM_CASEFOLD
|
||||
# define FNM_CASEFOLD 0
|
||||
#endif
|
||||
#ifndef FNM_LEADING_DIR
|
||||
# define FNM_LEADING_DIR 0
|
||||
#endif
|
||||
|
||||
char const * const exclude_keywords[] = {
|
||||
"noescape",
|
||||
"pathname",
|
||||
"period",
|
||||
"leading_dir",
|
||||
"casefold",
|
||||
"anchored",
|
||||
"include",
|
||||
"wildcards",
|
||||
NULL
|
||||
};
|
||||
|
||||
int exclude_flags[] = {
|
||||
FNM_NOESCAPE,
|
||||
FNM_PATHNAME,
|
||||
FNM_PERIOD,
|
||||
FNM_LEADING_DIR,
|
||||
FNM_CASEFOLD,
|
||||
EXCLUDE_ANCHORED,
|
||||
EXCLUDE_INCLUDE,
|
||||
EXCLUDE_WILDCARDS
|
||||
};
|
||||
|
||||
ARGMATCH_VERIFY (exclude_keywords, exclude_flags);
|
||||
|
||||
/* Some packages define ARGMATCH_DIE and ARGMATCH_DIE_DECL in <config.h>, and
|
||||
thus must link with a definition of that function. Provide it here. */
|
||||
#ifdef ARGMATCH_DIE_DECL
|
||||
|
||||
_Noreturn ARGMATCH_DIE_DECL;
|
||||
ARGMATCH_DIE_DECL { exit (1); }
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int exclude_options = 0;
|
||||
struct exclude *exclude = new_exclude ();
|
||||
|
||||
if (argc == 1)
|
||||
error (1, 0, "usage: %s file -- words...", argv[0]);
|
||||
|
||||
while (--argc)
|
||||
{
|
||||
char *opt = *++argv;
|
||||
if (opt[0] == '-')
|
||||
{
|
||||
int neg = 0;
|
||||
int flag;
|
||||
char *s = opt + 1;
|
||||
|
||||
if (opt[1] == '-' && opt[2] == 0)
|
||||
{
|
||||
argc--;
|
||||
break;
|
||||
}
|
||||
if (strlen (s) > 3 && memcmp (s, "no-", 3) == 0)
|
||||
{
|
||||
neg = 1;
|
||||
s += 3;
|
||||
}
|
||||
flag = XARGMATCH (opt, s, exclude_keywords, exclude_flags);
|
||||
if (neg)
|
||||
exclude_options &= ~flag;
|
||||
else
|
||||
exclude_options |= flag;
|
||||
|
||||
/* Skip this test if invoked with -leading-dir on a system that
|
||||
lacks support for FNM_LEADING_DIR. */
|
||||
if (strcmp (s, "leading_dir") == 0 && FNM_LEADING_DIR == 0)
|
||||
exit (77);
|
||||
|
||||
/* Likewise for -casefold and FNM_CASEFOLD. */
|
||||
if (strcmp (s, "casefold") == 0 && FNM_CASEFOLD == 0)
|
||||
exit (77);
|
||||
}
|
||||
else if (add_exclude_file (add_exclude, exclude, opt,
|
||||
exclude_options, '\n') != 0)
|
||||
error (1, errno, "error loading %s", opt);
|
||||
}
|
||||
|
||||
for (; argc; --argc)
|
||||
{
|
||||
char *word = *++argv;
|
||||
|
||||
printf ("%s: %d\n", word, excluded_file_name (exclude, word));
|
||||
}
|
||||
|
||||
free_exclude (exclude);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test literal matches
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
cat > expected <<EOT
|
||||
foo: 0
|
||||
foo*: 1
|
||||
bar: 1
|
||||
foobar: 0
|
||||
baz: 0
|
||||
bar/qux: 0
|
||||
EOT
|
||||
|
||||
test-exclude in -- foo 'foo*' bar foobar baz bar/qux > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,50 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
# Test case-insensitive literal matches
|
||||
|
||||
cat > expected <<EOT
|
||||
foo: 0
|
||||
foo*: 1
|
||||
bar: 1
|
||||
foobar: 0
|
||||
baz: 1
|
||||
bar/qux: 0
|
||||
EOT
|
||||
|
||||
test-exclude -casefold in -- foo 'foo*' bar foobar baz bar/qux > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,50 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test include
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
cat > expected <<EOT
|
||||
foo: 1
|
||||
foo*: 0
|
||||
bar: 0
|
||||
foobar: 1
|
||||
baz: 1
|
||||
bar/qux: 1
|
||||
EOT
|
||||
|
||||
test-exclude -include in -- foo 'foo*' bar foobar baz bar/qux > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,45 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test wildcard matching
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
cat > expected <<EOT
|
||||
foobar: 1
|
||||
EOT
|
||||
|
||||
test-exclude -wildcards in -- foobar > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,48 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test FNM_LEADING_DIR
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
cat > expected <<EOT
|
||||
bar: 1
|
||||
bar/qux: 1
|
||||
barz: 0
|
||||
foo/bar: 1
|
||||
EOT
|
||||
|
||||
test-exclude -leading_dir in -- bar bar/qux barz foo/bar > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,46 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test anchored
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
cat > expected <<EOT
|
||||
bar: 1
|
||||
foo/bar: 0
|
||||
EOT
|
||||
|
||||
test-exclude -anchored in -- bar foo/bar > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,47 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test exclude precedence
|
||||
|
||||
cat > in <<EOT
|
||||
foo*
|
||||
bar
|
||||
Baz
|
||||
EOT
|
||||
|
||||
cat > expected <<EOT
|
||||
bar: 0
|
||||
bar: 1
|
||||
EOT
|
||||
|
||||
test-exclude in -include in -- bar > out || exit $?
|
||||
test-exclude -include in -no-include in -- bar >> out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,46 @@
|
||||
#! /bin/sh
|
||||
# Test suite for exclude.
|
||||
# Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
# This file is part of the GNUlib Library.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
. "${srcdir=.}/init.sh"; path_prepend_ .
|
||||
fail=0
|
||||
|
||||
# Test escaped metacharacters.
|
||||
|
||||
cat > in <<'EOT'
|
||||
f\*e
|
||||
b[a\*]r
|
||||
EOT
|
||||
|
||||
cat > expected <<'EOT'
|
||||
f*e: 1
|
||||
file: 0
|
||||
bar: 1
|
||||
EOT
|
||||
|
||||
test-exclude -wildcards in -- 'f*e' 'file' 'bar' > out || exit $?
|
||||
|
||||
# Find out how to remove carriage returns from output. Solaris /usr/ucb/tr
|
||||
# does not understand '\r'.
|
||||
case $(echo r | tr -d '\r') in '') cr='\015';; *) cr='\r';; esac
|
||||
|
||||
# normalize output
|
||||
LC_ALL=C tr -d "$cr" < out > k && mv k out
|
||||
|
||||
compare expected out || fail=1
|
||||
|
||||
Exit $fail
|
||||
@@ -0,0 +1,130 @@
|
||||
/* Test of <fcntl.h> substitute.
|
||||
Copyright (C) 2007, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
/* Check that the various O_* macros are defined. */
|
||||
int o = (O_DIRECT | O_DIRECTORY | O_DSYNC | O_IGNORE_CTTY | O_NDELAY | O_NOATIME
|
||||
| O_NONBLOCK | O_NOCTTY | O_NOFOLLOW | O_NOLINK | O_NOLINKS | O_NOTRANS
|
||||
| O_RSYNC | O_SYNC | O_TTY_INIT | O_BINARY | O_TEXT);
|
||||
|
||||
/* Check that the various SEEK_* macros are defined. */
|
||||
int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET };
|
||||
|
||||
/* Check that the FD_* macros are defined. */
|
||||
int i = FD_CLOEXEC;
|
||||
|
||||
/* Check that the types are all defined. */
|
||||
pid_t t1;
|
||||
off_t t2;
|
||||
mode_t t3;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Ensure no overlap in SEEK_*. */
|
||||
switch (0)
|
||||
{
|
||||
case SEEK_CUR:
|
||||
case SEEK_END:
|
||||
case SEEK_SET:
|
||||
;
|
||||
}
|
||||
|
||||
/* Ensure no dangerous overlap in non-zero gnulib-defined replacements. */
|
||||
switch (O_RDONLY)
|
||||
{
|
||||
/* Access modes */
|
||||
case O_RDONLY:
|
||||
case O_WRONLY:
|
||||
case O_RDWR:
|
||||
#if O_EXEC && O_EXEC != O_RDONLY
|
||||
case O_EXEC:
|
||||
#endif
|
||||
#if O_SEARCH && O_EXEC != O_SEARCH && O_SEARCH != O_RDONLY
|
||||
case O_SEARCH:
|
||||
#endif
|
||||
i = ! (~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH));
|
||||
break;
|
||||
|
||||
/* Everyone should have these */
|
||||
case O_CREAT:
|
||||
case O_EXCL:
|
||||
case O_TRUNC:
|
||||
case O_APPEND:
|
||||
break;
|
||||
|
||||
/* These might be 0 or O_RDONLY, only test non-zero versions. */
|
||||
#if O_CLOEXEC
|
||||
case O_CLOEXEC:
|
||||
#endif
|
||||
#if O_DIRECT
|
||||
case O_DIRECT:
|
||||
#endif
|
||||
#if O_DIRECTORY
|
||||
case O_DIRECTORY:
|
||||
#endif
|
||||
#if O_DSYNC
|
||||
case O_DSYNC:
|
||||
#endif
|
||||
#if O_IGNORE_CTTY
|
||||
case O_IGNORE_CTTY:
|
||||
#endif
|
||||
#if O_NOATIME
|
||||
case O_NOATIME:
|
||||
#endif
|
||||
#if O_NONBLOCK
|
||||
case O_NONBLOCK:
|
||||
#endif
|
||||
#if O_NOCTTY
|
||||
case O_NOCTTY:
|
||||
#endif
|
||||
#if O_NOFOLLOW
|
||||
case O_NOFOLLOW:
|
||||
#endif
|
||||
#if O_NOLINK
|
||||
case O_NOLINK:
|
||||
#endif
|
||||
#if O_NOLINKS
|
||||
case O_NOLINKS:
|
||||
#endif
|
||||
#if O_NOTRANS
|
||||
case O_NOTRANS:
|
||||
#endif
|
||||
#if O_RSYNC && O_RSYNC != O_DSYNC
|
||||
case O_RSYNC:
|
||||
#endif
|
||||
#if O_SYNC && O_SYNC != O_DSYNC && O_SYNC != O_RSYNC
|
||||
case O_SYNC:
|
||||
#endif
|
||||
#if O_TTY_INIT
|
||||
case O_TTY_INIT:
|
||||
#endif
|
||||
#if O_BINARY
|
||||
case O_BINARY:
|
||||
#endif
|
||||
#if O_TEXT
|
||||
case O_TEXT:
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
return !i;
|
||||
}
|
||||
@@ -0,0 +1,413 @@
|
||||
/* Test of fcntl(2).
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fcntl, int, (int, int, ...));
|
||||
|
||||
/* Helpers. */
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Get declarations of the native Windows API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# include <io.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "binary-io.h"
|
||||
#include "macros.h"
|
||||
|
||||
#if !O_BINARY
|
||||
# define setmode(f,m) zero ()
|
||||
static int zero (void) { return 0; }
|
||||
#endif
|
||||
|
||||
/* Return true if FD is open. */
|
||||
static bool
|
||||
is_open (int fd)
|
||||
{
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On native Windows, the initial state of unassigned standard file
|
||||
descriptors is that they are open but point to an
|
||||
INVALID_HANDLE_VALUE, and there is no fcntl. */
|
||||
return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
# ifndef F_GETFL
|
||||
# error Please port fcntl to your platform
|
||||
# endif
|
||||
return 0 <= fcntl (fd, F_GETFL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return true if FD is open and inheritable across exec/spawn. */
|
||||
static bool
|
||||
is_inheritable (int fd)
|
||||
{
|
||||
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On native Windows, the initial state of unassigned standard file
|
||||
descriptors is that they are open but point to an
|
||||
INVALID_HANDLE_VALUE, and there is no fcntl. */
|
||||
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
||||
DWORD flags;
|
||||
if (h == INVALID_HANDLE_VALUE || GetHandleInformation (h, &flags) == 0)
|
||||
return false;
|
||||
return (flags & HANDLE_FLAG_INHERIT) != 0;
|
||||
#else
|
||||
# ifndef F_GETFD
|
||||
# error Please port fcntl to your platform
|
||||
# endif
|
||||
int i = fcntl (fd, F_GETFD);
|
||||
return 0 <= i && (i & FD_CLOEXEC) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return non-zero if FD is open in the given MODE, which is either
|
||||
O_TEXT or O_BINARY. */
|
||||
static bool
|
||||
is_mode (int fd, int mode)
|
||||
{
|
||||
int value = setmode (fd, O_BINARY);
|
||||
setmode (fd, value);
|
||||
return mode == value;
|
||||
}
|
||||
|
||||
/* Since native fcntl can have more supported operations than our
|
||||
replacement is aware of, and since various operations assign
|
||||
different types to the vararg argument, a wrapper around fcntl must
|
||||
be able to pass a vararg of unknown type on through to the original
|
||||
fcntl. Make sure that this works properly: func1 behaves like the
|
||||
original fcntl interpreting the vararg as an int or a pointer to a
|
||||
struct, and func2 behaves like rpl_fcntl that doesn't know what
|
||||
type to forward. */
|
||||
struct dummy_struct
|
||||
{
|
||||
long filler;
|
||||
int value;
|
||||
};
|
||||
static int
|
||||
func1 (int a, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int i;
|
||||
va_start (arg, a);
|
||||
if (a < 4)
|
||||
i = va_arg (arg, int);
|
||||
else
|
||||
{
|
||||
struct dummy_struct *s = va_arg (arg, struct dummy_struct *);
|
||||
i = s->value;
|
||||
}
|
||||
va_end (arg);
|
||||
return i;
|
||||
}
|
||||
static int
|
||||
func2 (int a, ...)
|
||||
{
|
||||
va_list arg;
|
||||
void *p;
|
||||
va_start (arg, a);
|
||||
p = va_arg (arg, void *);
|
||||
va_end (arg);
|
||||
return func1 (a, p);
|
||||
}
|
||||
|
||||
/* Ensure that all supported fcntl actions are distinct, and
|
||||
usable in preprocessor expressions. */
|
||||
static void
|
||||
check_flags (void)
|
||||
{
|
||||
switch (0)
|
||||
{
|
||||
case F_DUPFD:
|
||||
#if F_DUPFD
|
||||
#endif
|
||||
|
||||
case F_DUPFD_CLOEXEC:
|
||||
#if F_DUPFD_CLOEXEC
|
||||
#endif
|
||||
|
||||
case F_GETFD:
|
||||
#if F_GETFD
|
||||
#endif
|
||||
|
||||
#ifdef F_SETFD
|
||||
case F_SETFD:
|
||||
# if F_SETFD
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_GETFL
|
||||
case F_GETFL:
|
||||
# if F_GETFL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_SETFL
|
||||
case F_SETFL:
|
||||
# if F_SETFL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_GETOWN
|
||||
case F_GETOWN:
|
||||
# if F_GETOWN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_SETOWN
|
||||
case F_SETOWN:
|
||||
# if F_SETOWN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_GETLK
|
||||
case F_GETLK:
|
||||
# if F_GETLK
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_SETLK
|
||||
case F_SETLK:
|
||||
# if F_SETLK
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F_SETLKW
|
||||
case F_SETLKW:
|
||||
# if F_SETLKW
|
||||
# endif
|
||||
#endif
|
||||
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
const char *file = "test-fcntl.tmp";
|
||||
int fd;
|
||||
int bad_fd = getdtablesize ();
|
||||
|
||||
/* Sanity check that rpl_fcntl is likely to work. */
|
||||
ASSERT (func2 (1, 2) == 2);
|
||||
ASSERT (func2 (2, -2) == -2);
|
||||
ASSERT (func2 (3, 0x80000000) == 0x80000000);
|
||||
{
|
||||
struct dummy_struct s = { 0L, 4 };
|
||||
ASSERT (func2 (4, &s) == 4);
|
||||
}
|
||||
check_flags ();
|
||||
|
||||
/* Assume std descriptors were provided by invoker, and ignore fds
|
||||
that might have been inherited. */
|
||||
fd = creat (file, 0600);
|
||||
ASSERT (STDERR_FILENO < fd);
|
||||
close (fd + 1);
|
||||
close (fd + 2);
|
||||
|
||||
/* For F_DUPFD*, the source must be valid. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_DUPFD, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_DUPFD, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_DUPFD, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_DUPFD_CLOEXEC, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_DUPFD_CLOEXEC, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_DUPFD_CLOEXEC, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
|
||||
/* For F_DUPFD*, the destination must be valid. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd, F_DUPFD, -1) == -1);
|
||||
ASSERT (errno == EINVAL);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd, F_DUPFD, bad_fd) == -1);
|
||||
ASSERT (errno == EINVAL);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, -1) == -1);
|
||||
ASSERT (errno == EINVAL);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, bad_fd) == -1);
|
||||
ASSERT (errno == EINVAL);
|
||||
|
||||
/* For F_DUPFD*, check for correct inheritance, as well as
|
||||
preservation of text vs. binary. */
|
||||
setmode (fd, O_BINARY);
|
||||
ASSERT (is_open (fd));
|
||||
ASSERT (!is_open (fd + 1));
|
||||
ASSERT (!is_open (fd + 2));
|
||||
ASSERT (is_inheritable (fd));
|
||||
ASSERT (is_mode (fd, O_BINARY));
|
||||
|
||||
ASSERT (fcntl (fd, F_DUPFD, fd) == fd + 1);
|
||||
ASSERT (is_open (fd));
|
||||
ASSERT (is_open (fd + 1));
|
||||
ASSERT (!is_open (fd + 2));
|
||||
ASSERT (is_inheritable (fd + 1));
|
||||
ASSERT (is_mode (fd, O_BINARY));
|
||||
ASSERT (is_mode (fd + 1, O_BINARY));
|
||||
ASSERT (close (fd + 1) == 0);
|
||||
|
||||
ASSERT (fcntl (fd, F_DUPFD_CLOEXEC, fd + 2) == fd + 2);
|
||||
ASSERT (is_open (fd));
|
||||
ASSERT (!is_open (fd + 1));
|
||||
ASSERT (is_open (fd + 2));
|
||||
ASSERT (is_inheritable (fd));
|
||||
ASSERT (!is_inheritable (fd + 2));
|
||||
ASSERT (is_mode (fd, O_BINARY));
|
||||
ASSERT (is_mode (fd + 2, O_BINARY));
|
||||
ASSERT (close (fd) == 0);
|
||||
|
||||
setmode (fd + 2, O_TEXT);
|
||||
ASSERT (fcntl (fd + 2, F_DUPFD, fd + 1) == fd + 1);
|
||||
ASSERT (!is_open (fd));
|
||||
ASSERT (is_open (fd + 1));
|
||||
ASSERT (is_open (fd + 2));
|
||||
ASSERT (is_inheritable (fd + 1));
|
||||
ASSERT (!is_inheritable (fd + 2));
|
||||
ASSERT (is_mode (fd + 1, O_TEXT));
|
||||
ASSERT (is_mode (fd + 2, O_TEXT));
|
||||
ASSERT (close (fd + 1) == 0);
|
||||
|
||||
ASSERT (fcntl (fd + 2, F_DUPFD_CLOEXEC, 0) == fd);
|
||||
ASSERT (is_open (fd));
|
||||
ASSERT (!is_open (fd + 1));
|
||||
ASSERT (is_open (fd + 2));
|
||||
ASSERT (!is_inheritable (fd));
|
||||
ASSERT (!is_inheritable (fd + 2));
|
||||
ASSERT (is_mode (fd, O_TEXT));
|
||||
ASSERT (is_mode (fd + 2, O_TEXT));
|
||||
ASSERT (close (fd + 2) == 0);
|
||||
|
||||
/* Test F_GETFD on invalid file descriptors. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_GETFD) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_GETFD) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_GETFD) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
|
||||
/* Test F_GETFD, the FD_CLOEXEC bit. */
|
||||
{
|
||||
int result = fcntl (fd, F_GETFD);
|
||||
ASSERT (0 <= result);
|
||||
ASSERT ((result & FD_CLOEXEC) == FD_CLOEXEC);
|
||||
ASSERT (dup (fd) == fd + 1);
|
||||
result = fcntl (fd + 1, F_GETFD);
|
||||
ASSERT (0 <= result);
|
||||
ASSERT ((result & FD_CLOEXEC) == 0);
|
||||
ASSERT (close (fd + 1) == 0);
|
||||
}
|
||||
|
||||
#ifdef F_SETFD
|
||||
/* Test F_SETFD on invalid file descriptors. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_SETFD, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_SETFD, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_SETFD, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
#endif
|
||||
|
||||
#ifdef F_GETFL
|
||||
/* Test F_GETFL on invalid file descriptors. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_GETFL) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_GETFL) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_GETFL) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
#endif
|
||||
|
||||
#ifdef F_SETFL
|
||||
/* Test F_SETFL on invalid file descriptors. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_SETFL, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_SETFL, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_SETFL, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
#endif
|
||||
|
||||
#ifdef F_GETOWN
|
||||
/* Test F_GETOWN on invalid file descriptors. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_GETOWN) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_GETOWN) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_GETOWN) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
#endif
|
||||
|
||||
#ifdef F_SETOWN
|
||||
/* Test F_SETFL on invalid file descriptors. */
|
||||
errno = 0;
|
||||
ASSERT (fcntl (-1, F_SETOWN, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (fd + 1, F_SETOWN, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
errno = 0;
|
||||
ASSERT (fcntl (bad_fd, F_SETOWN, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
#endif
|
||||
|
||||
/* Cleanup. */
|
||||
ASSERT (close (fd) == 0);
|
||||
ASSERT (unlink (file) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/* Test opening a stream with a file descriptor.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fdopen, FILE *, (int, const char *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Test behavior on failure. POSIX makes it hard to check for
|
||||
failure, since the behavior is not well-defined on invalid file
|
||||
descriptors, so try fdopen 1000 times and if that's not enough to
|
||||
fail due to EMFILE, so be it. */
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
errno = 0;
|
||||
if (! fdopen (STDOUT_FILENO, "w"))
|
||||
{
|
||||
ASSERT (errno != 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/* Test of fgetc() function.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fgetc, int, (FILE *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const char *filename = "test-fgetc.txt";
|
||||
|
||||
/* We don't have an fgetc() function that installs an invalid parameter
|
||||
handler so far. So install that handler here, explicitly. */
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \
|
||||
&& MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING
|
||||
gl_msvc_inval_ensure_handler ();
|
||||
#endif
|
||||
|
||||
/* Prepare a file. */
|
||||
{
|
||||
const char text[] = "hello world";
|
||||
int fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
ASSERT (fd >= 0);
|
||||
ASSERT (write (fd, text, sizeof (text)) == sizeof (text));
|
||||
ASSERT (close (fd) == 0);
|
||||
}
|
||||
|
||||
/* Test that fgetc() sets errno if someone else closes the stream
|
||||
fd behind the back of stdio. */
|
||||
{
|
||||
FILE *fp = fopen (filename, "r");
|
||||
ASSERT (fp != NULL);
|
||||
ASSERT (close (fileno (fp)) == 0);
|
||||
errno = 0;
|
||||
ASSERT (fgetc (fp) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
/* Test that fgetc() sets errno if the stream was constructed with
|
||||
an invalid file descriptor. */
|
||||
{
|
||||
FILE *fp = fdopen (-1, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (fgetc (fp) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
{
|
||||
FILE *fp;
|
||||
close (99);
|
||||
fp = fdopen (99, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (fgetc (fp) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
unlink (filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Test of concatenation of two arbitrary file names.
|
||||
|
||||
Copyright (C) 1996-2007, 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Jim Meyering. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "filenamecat.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int
|
||||
main (int argc _GL_UNUSED, char *argv[])
|
||||
{
|
||||
static char const *const tests[][3] =
|
||||
{
|
||||
{"a", "b", "a/b"},
|
||||
{"a/", "b", "a/b"},
|
||||
{"a/", "/b", "a/b"},
|
||||
{"a", "/b", "a/b"},
|
||||
|
||||
{"/", "b", "/b"},
|
||||
{"/", "/b", "/b"},
|
||||
{"/", "/", "/"},
|
||||
{"a", "/", "a/"}, /* this might deserve a diagnostic */
|
||||
{"/a", "/", "/a/"}, /* this might deserve a diagnostic */
|
||||
{"a", "//b", "a/b"},
|
||||
{"", "a", "a"}, /* this might deserve a diagnostic */
|
||||
};
|
||||
unsigned int i;
|
||||
bool fail = false;
|
||||
|
||||
for (i = 0; i < sizeof tests / sizeof tests[0]; i++)
|
||||
{
|
||||
char *base_in_result;
|
||||
char const *const *t = tests[i];
|
||||
char *res = file_name_concat (t[0], t[1], &base_in_result);
|
||||
if (strcmp (res, t[2]) != 0)
|
||||
{
|
||||
fprintf (stderr, "test #%u: got %s, expected %s\n", i, res, t[2]);
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
exit (fail ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
@@ -0,0 +1,384 @@
|
||||
/* Test of <float.h> substitute.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2011. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#include "fpucw.h"
|
||||
#include "macros.h"
|
||||
|
||||
/* Check that FLT_RADIX is a constant expression. */
|
||||
int a[] = { FLT_RADIX };
|
||||
|
||||
#if FLT_RADIX == 2
|
||||
|
||||
/* Return 2^n. */
|
||||
static float
|
||||
pow2f (int n)
|
||||
{
|
||||
int k = n;
|
||||
volatile float x = 1;
|
||||
volatile float y = 2;
|
||||
/* Invariant: 2^n == x * y^k. */
|
||||
if (k < 0)
|
||||
{
|
||||
y = 0.5f;
|
||||
k = - k;
|
||||
}
|
||||
while (k > 0)
|
||||
{
|
||||
if (k != 2 * (k / 2))
|
||||
{
|
||||
x = x * y;
|
||||
k = k - 1;
|
||||
}
|
||||
if (k == 0)
|
||||
break;
|
||||
y = y * y;
|
||||
k = k / 2;
|
||||
}
|
||||
/* Now k == 0, hence x == 2^n. */
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return 2^n. */
|
||||
static double
|
||||
pow2d (int n)
|
||||
{
|
||||
int k = n;
|
||||
volatile double x = 1;
|
||||
volatile double y = 2;
|
||||
/* Invariant: 2^n == x * y^k. */
|
||||
if (k < 0)
|
||||
{
|
||||
y = 0.5;
|
||||
k = - k;
|
||||
}
|
||||
while (k > 0)
|
||||
{
|
||||
if (k != 2 * (k / 2))
|
||||
{
|
||||
x = x * y;
|
||||
k = k - 1;
|
||||
}
|
||||
if (k == 0)
|
||||
break;
|
||||
y = y * y;
|
||||
k = k / 2;
|
||||
}
|
||||
/* Now k == 0, hence x == 2^n. */
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Return 2^n. */
|
||||
static long double
|
||||
pow2l (int n)
|
||||
{
|
||||
int k = n;
|
||||
volatile long double x = 1;
|
||||
volatile long double y = 2;
|
||||
/* Invariant: 2^n == x * y^k. */
|
||||
if (k < 0)
|
||||
{
|
||||
y = 0.5L;
|
||||
k = - k;
|
||||
}
|
||||
while (k > 0)
|
||||
{
|
||||
if (k != 2 * (k / 2))
|
||||
{
|
||||
x = x * y;
|
||||
k = k - 1;
|
||||
}
|
||||
if (k == 0)
|
||||
break;
|
||||
y = y * y;
|
||||
k = k / 2;
|
||||
}
|
||||
/* Now k == 0, hence x == 2^n. */
|
||||
return x;
|
||||
}
|
||||
|
||||
/* ----------------------- Check macros for 'float' ----------------------- */
|
||||
|
||||
/* Check that the FLT_* macros expand to constant expressions. */
|
||||
int fb[] =
|
||||
{
|
||||
FLT_MANT_DIG, FLT_MIN_EXP, FLT_MAX_EXP,
|
||||
FLT_DIG, FLT_MIN_10_EXP, FLT_MAX_10_EXP
|
||||
};
|
||||
float fc[] = { FLT_EPSILON, FLT_MIN, FLT_MAX };
|
||||
|
||||
static void
|
||||
test_float (void)
|
||||
{
|
||||
/* Check that the value of FLT_MIN_EXP is well parenthesized. */
|
||||
ASSERT ((FLT_MIN_EXP % 101111) == (FLT_MIN_EXP) % 101111);
|
||||
|
||||
/* Check that the value of DBL_MIN_10_EXP is well parenthesized. */
|
||||
ASSERT ((FLT_MIN_10_EXP % 101111) == (FLT_MIN_10_EXP) % 101111);
|
||||
|
||||
/* Check that 'float' is as specified in IEEE 754. */
|
||||
ASSERT (FLT_MANT_DIG == 24);
|
||||
ASSERT (FLT_MIN_EXP == -125);
|
||||
ASSERT (FLT_MAX_EXP == 128);
|
||||
|
||||
/* Check the value of FLT_MIN_10_EXP. */
|
||||
ASSERT (FLT_MIN_10_EXP == - (int) (- (FLT_MIN_EXP - 1) * 0.30103));
|
||||
|
||||
/* Check the value of FLT_DIG. */
|
||||
ASSERT (FLT_DIG == (int) ((FLT_MANT_DIG - 1) * 0.30103));
|
||||
|
||||
/* Check the value of FLT_MIN_10_EXP. */
|
||||
ASSERT (FLT_MIN_10_EXP == - (int) (- (FLT_MIN_EXP - 1) * 0.30103));
|
||||
|
||||
/* Check the value of FLT_MAX_10_EXP. */
|
||||
ASSERT (FLT_MAX_10_EXP == (int) (FLT_MAX_EXP * 0.30103));
|
||||
|
||||
/* Check the value of FLT_MAX. */
|
||||
{
|
||||
volatile float m = FLT_MAX;
|
||||
int n;
|
||||
|
||||
ASSERT (m + m > m);
|
||||
for (n = 0; n <= 2 * FLT_MANT_DIG; n++)
|
||||
{
|
||||
volatile float pow2_n = pow2f (n); /* 2^n */
|
||||
volatile float x = m + (m / pow2_n);
|
||||
if (x > m)
|
||||
ASSERT (x + x == x);
|
||||
else
|
||||
ASSERT (!(x + x == x));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the value of FLT_MIN. */
|
||||
{
|
||||
volatile float m = FLT_MIN;
|
||||
volatile float x = pow2f (FLT_MIN_EXP - 1);
|
||||
ASSERT (m == x);
|
||||
}
|
||||
|
||||
/* Check the value of FLT_EPSILON. */
|
||||
{
|
||||
volatile float e = FLT_EPSILON;
|
||||
volatile float me;
|
||||
int n;
|
||||
|
||||
me = 1.0f + e;
|
||||
ASSERT (me > 1.0f);
|
||||
ASSERT (me - 1.0f == e);
|
||||
for (n = 0; n <= 2 * FLT_MANT_DIG; n++)
|
||||
{
|
||||
volatile float half_n = pow2f (- n); /* 2^-n */
|
||||
volatile float x = me - half_n;
|
||||
if (x < me)
|
||||
ASSERT (x <= 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------- Check macros for 'double' ----------------------- */
|
||||
|
||||
/* Check that the DBL_* macros expand to constant expressions. */
|
||||
int db[] =
|
||||
{
|
||||
DBL_MANT_DIG, DBL_MIN_EXP, DBL_MAX_EXP,
|
||||
DBL_DIG, DBL_MIN_10_EXP, DBL_MAX_10_EXP
|
||||
};
|
||||
double dc[] = { DBL_EPSILON, DBL_MIN, DBL_MAX };
|
||||
|
||||
static void
|
||||
test_double (void)
|
||||
{
|
||||
/* Check that the value of DBL_MIN_EXP is well parenthesized. */
|
||||
ASSERT ((DBL_MIN_EXP % 101111) == (DBL_MIN_EXP) % 101111);
|
||||
|
||||
/* Check that the value of DBL_MIN_10_EXP is well parenthesized. */
|
||||
ASSERT ((DBL_MIN_10_EXP % 101111) == (DBL_MIN_10_EXP) % 101111);
|
||||
|
||||
/* Check that 'double' is as specified in IEEE 754. */
|
||||
ASSERT (DBL_MANT_DIG == 53);
|
||||
ASSERT (DBL_MIN_EXP == -1021);
|
||||
ASSERT (DBL_MAX_EXP == 1024);
|
||||
|
||||
/* Check the value of DBL_MIN_10_EXP. */
|
||||
ASSERT (DBL_MIN_10_EXP == - (int) (- (DBL_MIN_EXP - 1) * 0.30103));
|
||||
|
||||
/* Check the value of DBL_DIG. */
|
||||
ASSERT (DBL_DIG == (int) ((DBL_MANT_DIG - 1) * 0.30103));
|
||||
|
||||
/* Check the value of DBL_MIN_10_EXP. */
|
||||
ASSERT (DBL_MIN_10_EXP == - (int) (- (DBL_MIN_EXP - 1) * 0.30103));
|
||||
|
||||
/* Check the value of DBL_MAX_10_EXP. */
|
||||
ASSERT (DBL_MAX_10_EXP == (int) (DBL_MAX_EXP * 0.30103));
|
||||
|
||||
/* Check the value of DBL_MAX. */
|
||||
{
|
||||
volatile double m = DBL_MAX;
|
||||
int n;
|
||||
|
||||
ASSERT (m + m > m);
|
||||
for (n = 0; n <= 2 * DBL_MANT_DIG; n++)
|
||||
{
|
||||
volatile double pow2_n = pow2d (n); /* 2^n */
|
||||
volatile double x = m + (m / pow2_n);
|
||||
if (x > m)
|
||||
ASSERT (x + x == x);
|
||||
else
|
||||
ASSERT (!(x + x == x));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the value of DBL_MIN. */
|
||||
{
|
||||
volatile double m = DBL_MIN;
|
||||
volatile double x = pow2d (DBL_MIN_EXP - 1);
|
||||
ASSERT (m == x);
|
||||
}
|
||||
|
||||
/* Check the value of DBL_EPSILON. */
|
||||
{
|
||||
volatile double e = DBL_EPSILON;
|
||||
volatile double me;
|
||||
int n;
|
||||
|
||||
me = 1.0 + e;
|
||||
ASSERT (me > 1.0);
|
||||
ASSERT (me - 1.0 == e);
|
||||
for (n = 0; n <= 2 * DBL_MANT_DIG; n++)
|
||||
{
|
||||
volatile double half_n = pow2d (- n); /* 2^-n */
|
||||
volatile double x = me - half_n;
|
||||
if (x < me)
|
||||
ASSERT (x <= 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------- Check macros for 'long double' -------------------- */
|
||||
|
||||
/* Check that the LDBL_* macros expand to constant expressions. */
|
||||
int lb[] =
|
||||
{
|
||||
LDBL_MANT_DIG, LDBL_MIN_EXP, LDBL_MAX_EXP,
|
||||
LDBL_DIG, LDBL_MIN_10_EXP, LDBL_MAX_10_EXP
|
||||
};
|
||||
long double lc1 = LDBL_EPSILON;
|
||||
long double lc2 = LDBL_MIN;
|
||||
#if 0 /* LDBL_MAX is not a constant expression on some platforms. */
|
||||
long double lc3 = LDBL_MAX;
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_long_double (void)
|
||||
{
|
||||
/* Check that the value of LDBL_MIN_EXP is well parenthesized. */
|
||||
ASSERT ((LDBL_MIN_EXP % 101111) == (LDBL_MIN_EXP) % 101111);
|
||||
|
||||
/* Check that the value of LDBL_MIN_10_EXP is well parenthesized. */
|
||||
ASSERT ((LDBL_MIN_10_EXP % 101111) == (LDBL_MIN_10_EXP) % 101111);
|
||||
|
||||
/* Check that 'long double' is at least as wide as 'double'. */
|
||||
ASSERT (LDBL_MANT_DIG >= DBL_MANT_DIG);
|
||||
ASSERT (LDBL_MIN_EXP - LDBL_MANT_DIG <= DBL_MIN_EXP - DBL_MANT_DIG);
|
||||
ASSERT (LDBL_MAX_EXP >= DBL_MAX_EXP);
|
||||
|
||||
/* Check the value of LDBL_DIG. */
|
||||
ASSERT (LDBL_DIG == (int)((LDBL_MANT_DIG - 1) * 0.30103));
|
||||
|
||||
/* Check the value of LDBL_MIN_10_EXP. */
|
||||
ASSERT (LDBL_MIN_10_EXP == - (int) (- (LDBL_MIN_EXP - 1) * 0.30103));
|
||||
|
||||
/* Check the value of LDBL_MAX_10_EXP. */
|
||||
ASSERT (LDBL_MAX_10_EXP == (int) (LDBL_MAX_EXP * 0.30103));
|
||||
|
||||
/* Check the value of LDBL_MAX. */
|
||||
{
|
||||
volatile long double m = LDBL_MAX;
|
||||
int n;
|
||||
|
||||
ASSERT (m + m > m);
|
||||
for (n = 0; n <= 2 * LDBL_MANT_DIG; n++)
|
||||
{
|
||||
volatile long double pow2_n = pow2l (n); /* 2^n */
|
||||
volatile long double x = m + (m / pow2_n);
|
||||
if (x > m)
|
||||
ASSERT (x + x == x);
|
||||
else
|
||||
ASSERT (!(x + x == x));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the value of LDBL_MIN. */
|
||||
{
|
||||
volatile long double m = LDBL_MIN;
|
||||
volatile long double x = pow2l (LDBL_MIN_EXP - 1);
|
||||
ASSERT (m == x);
|
||||
}
|
||||
|
||||
/* Check the value of LDBL_EPSILON. */
|
||||
{
|
||||
volatile long double e = LDBL_EPSILON;
|
||||
volatile long double me;
|
||||
int n;
|
||||
|
||||
me = 1.0L + e;
|
||||
ASSERT (me > 1.0L);
|
||||
ASSERT (me - 1.0L == e);
|
||||
for (n = 0; n <= 2 * LDBL_MANT_DIG; n++)
|
||||
{
|
||||
volatile long double half_n = pow2l (- n); /* 2^-n */
|
||||
volatile long double x = me - half_n;
|
||||
if (x < me)
|
||||
ASSERT (x <= 1.0L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
test_float ();
|
||||
test_double ();
|
||||
|
||||
{
|
||||
DECL_LONG_DOUBLE_ROUNDING
|
||||
|
||||
BEGIN_LONG_DOUBLE_ROUNDING ();
|
||||
|
||||
test_long_double ();
|
||||
|
||||
END_LONG_DOUBLE_ROUNDING ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
fprintf (stderr, "Skipping test: FLT_RADIX is not 2.\n");
|
||||
return 77;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Test of fnmatch string matching function.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Simon Josefsson <simon@josefsson.org>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fnmatch, int, (char const *, char const *, int));
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int res;
|
||||
|
||||
ASSERT (res = fnmatch ("", "", 0) == 0);
|
||||
|
||||
ASSERT (res = fnmatch ("*", "", 0) == 0);
|
||||
ASSERT (res = fnmatch ("*", "foo", 0) == 0);
|
||||
ASSERT (res = fnmatch ("*", "bar", 0) == 0);
|
||||
ASSERT (res = fnmatch ("*", "*", 0) == 0);
|
||||
ASSERT (res = fnmatch ("**", "f", 0) == 0);
|
||||
ASSERT (res = fnmatch ("**", "foo.txt", 0) == 0);
|
||||
ASSERT (res = fnmatch ("*.*", "foo.txt", 0) == 0);
|
||||
|
||||
ASSERT (res = fnmatch ("foo*.txt", "foobar.txt", 0) == 0);
|
||||
|
||||
ASSERT (res = fnmatch ("foo.txt", "foo.txt", 0) == 0);
|
||||
ASSERT (res = fnmatch ("foo\\.txt", "foo.txt", 0) == 0);
|
||||
ASSERT (res = fnmatch ("foo\\.txt", "foo.txt", FNM_NOESCAPE) == FNM_NOMATCH);
|
||||
|
||||
/* Verify that an unmatched [ is treated as a literal, as POSIX
|
||||
requires. This test ensures that glibc Bugzilla bug #12378 stays
|
||||
fixed.
|
||||
*/
|
||||
ASSERT (res = fnmatch ("[/b", "[/b", 0) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/* Test of fputc() function.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fputc, int, (int, FILE *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const char *filename = "test-fputc.txt";
|
||||
|
||||
/* We don't have an fputc() function that installs an invalid parameter
|
||||
handler so far. So install that handler here, explicitly. */
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \
|
||||
&& MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING
|
||||
gl_msvc_inval_ensure_handler ();
|
||||
#endif
|
||||
|
||||
/* Test that fputc() on an unbuffered stream sets errno if someone else
|
||||
closes the stream fd behind the back of stdio. */
|
||||
{
|
||||
FILE *fp = fopen (filename, "w");
|
||||
ASSERT (fp != NULL);
|
||||
setvbuf (fp, NULL, _IONBF, 0);
|
||||
ASSERT (close (fileno (fp)) == 0);
|
||||
errno = 0;
|
||||
ASSERT (fputc ('x', fp) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
/* Test that fputc() on an unbuffered stream sets errno if the stream
|
||||
was constructed with an invalid file descriptor. */
|
||||
{
|
||||
FILE *fp = fdopen (-1, "w");
|
||||
if (fp != NULL)
|
||||
{
|
||||
setvbuf (fp, NULL, _IONBF, 0);
|
||||
errno = 0;
|
||||
ASSERT (fputc ('x', fp) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
{
|
||||
FILE *fp;
|
||||
close (99);
|
||||
fp = fdopen (99, "w");
|
||||
if (fp != NULL)
|
||||
{
|
||||
setvbuf (fp, NULL, _IONBF, 0);
|
||||
errno = 0;
|
||||
ASSERT (fputc ('x', fp) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
unlink (filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/* Test of fread() function.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fread, size_t, (void *, size_t, size_t, FILE *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const char *filename = "test-fread.txt";
|
||||
|
||||
/* We don't have an fread() function that installs an invalid parameter
|
||||
handler so far. So install that handler here, explicitly. */
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \
|
||||
&& MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING
|
||||
gl_msvc_inval_ensure_handler ();
|
||||
#endif
|
||||
|
||||
/* Prepare a file. */
|
||||
{
|
||||
const char text[] = "hello world";
|
||||
int fd = open (filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
ASSERT (fd >= 0);
|
||||
ASSERT (write (fd, text, sizeof (text)) == sizeof (text));
|
||||
ASSERT (close (fd) == 0);
|
||||
}
|
||||
|
||||
/* Test that fread() sets errno if someone else closes the stream
|
||||
fd behind the back of stdio. */
|
||||
{
|
||||
FILE *fp = fopen (filename, "r");
|
||||
char buf[5];
|
||||
ASSERT (fp != NULL);
|
||||
ASSERT (close (fileno (fp)) == 0);
|
||||
errno = 0;
|
||||
ASSERT (fread (buf, 1, sizeof (buf), fp) == 0);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
/* Test that fread() sets errno if the stream was constructed with
|
||||
an invalid file descriptor. */
|
||||
{
|
||||
FILE *fp = fdopen (-1, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
char buf[1];
|
||||
errno = 0;
|
||||
ASSERT (fread (buf, 1, 1, fp) == 0);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
{
|
||||
FILE *fp;
|
||||
close (99);
|
||||
fp = fdopen (99, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
char buf[1];
|
||||
errno = 0;
|
||||
ASSERT (fread (buf, 1, 1, fp) == 0);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
unlink (filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/* Test of reopening a stream.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Eric Blake <ebb9@byu.net>, 2009. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "stdio--.h"
|
||||
|
||||
/* Helpers. */
|
||||
#include <unistd.h>
|
||||
|
||||
/* This test intentionally closes stderr. So, we arrange to have fd 10
|
||||
(outside the range of interesting fd's during the test) set up to
|
||||
duplicate the original stderr. */
|
||||
|
||||
#define BACKUP_STDERR_FILENO 10
|
||||
#define ASSERT_STREAM myerr
|
||||
#include "macros.h"
|
||||
|
||||
static FILE *myerr;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
/* We close fd 2 later, so save it in fd 10. */
|
||||
if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
|
||||
|| (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
|
||||
return 2;
|
||||
|
||||
{
|
||||
FILE *tmp;
|
||||
ASSERT (tmp = fopen ("/dev/null", "r"));
|
||||
ASSERT (STDERR_FILENO < fileno (tmp));
|
||||
ASSERT (fp = fopen ("/dev/null", "w"));
|
||||
ASSERT (fileno (tmp) < fileno (fp));
|
||||
ASSERT (fclose (tmp) == 0);
|
||||
}
|
||||
|
||||
/* Gap in fds. */
|
||||
ASSERT (freopen ("/dev/null", "r+", fp) == fp);
|
||||
ASSERT (STDERR_FILENO < fileno (fp));
|
||||
|
||||
ASSERT (freopen ("/dev/null", "r", stdin) == stdin);
|
||||
ASSERT (STDIN_FILENO == fileno (stdin));
|
||||
|
||||
ASSERT (freopen ("/dev/null", "w", stdout) == stdout);
|
||||
ASSERT (STDOUT_FILENO == fileno (stdout));
|
||||
|
||||
ASSERT (freopen ("/dev/null", "w", stderr) == stderr);
|
||||
ASSERT (STDERR_FILENO == fileno (stderr));
|
||||
|
||||
/* fd 0 closed. */
|
||||
ASSERT (close (STDIN_FILENO) == 0);
|
||||
|
||||
ASSERT (freopen ("/dev/null", "w", stdout) == stdout);
|
||||
ASSERT (STDOUT_FILENO == fileno (stdout));
|
||||
|
||||
ASSERT (freopen ("/dev/null", "w", stderr) == stderr);
|
||||
ASSERT (STDERR_FILENO == fileno (stderr));
|
||||
|
||||
ASSERT (freopen ("/dev/null", "a", fp) == fp);
|
||||
ASSERT (STDERR_FILENO < fileno (fp));
|
||||
|
||||
/* fd 1 closed. */
|
||||
ASSERT (close (STDOUT_FILENO) == 0);
|
||||
|
||||
ASSERT (freopen ("/dev/null", "w", stderr) == stderr);
|
||||
ASSERT (STDERR_FILENO == fileno (stderr));
|
||||
|
||||
ASSERT (freopen ("/dev/null", "a+", fp) == fp);
|
||||
ASSERT (STDERR_FILENO < fileno (fp));
|
||||
|
||||
/* fd 2 closed. */
|
||||
ASSERT (close (STDERR_FILENO) == 0);
|
||||
|
||||
ASSERT (freopen ("/dev/null", "w+", fp) == fp);
|
||||
ASSERT (STDERR_FILENO < fileno (fp));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Test of opening a file stream.
|
||||
Copyright (C) 2007-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (freopen, FILE *, (char const *, char const *, FILE *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
const char *filename = "test-freopen.txt";
|
||||
|
||||
close (STDIN_FILENO);
|
||||
ASSERT (freopen ("/dev/null", "r", stdin) != NULL);
|
||||
ASSERT (getchar () == EOF);
|
||||
ASSERT (!ferror (stdin));
|
||||
ASSERT (feof (stdin));
|
||||
|
||||
#if 0 /* freopen (NULL, ...) is unsupported on most platforms. */
|
||||
/* Test that freopen() sets errno if someone else closes the stream
|
||||
fd behind the back of stdio. */
|
||||
{
|
||||
FILE *fp = fopen (filename, "w+");
|
||||
ASSERT (fp != NULL);
|
||||
ASSERT (close (fileno (fp)) == 0);
|
||||
errno = 0;
|
||||
ASSERT (freopen (NULL, "r", fp) == NULL);
|
||||
perror("freopen");
|
||||
ASSERT (errno == EBADF);
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
/* Test that freopen() sets errno if the stream was constructed with
|
||||
an invalid file descriptor. */
|
||||
{
|
||||
FILE *fp = fdopen (-1, "w+");
|
||||
if (fp != NULL)
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (freopen (NULL, "r", fp) == NULL);
|
||||
ASSERT (errno == EBADF);
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
{
|
||||
FILE *fp;
|
||||
close (99);
|
||||
fp = fdopen (99, "w+");
|
||||
if (fp != NULL)
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (freopen (NULL, "r", fp) == NULL);
|
||||
ASSERT (errno == EBADF);
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clean up. */
|
||||
unlink (filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/* Tests of fstat() function.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fstat, int, (int, struct stat *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
/* Test behaviour for invalid file descriptors. */
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
errno = 0;
|
||||
ASSERT (fstat (-1, &statbuf) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (fstat (99, &statbuf) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Test truncating a file.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (ftruncate, int, (int, off_t));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const char *filename = argv[1];
|
||||
|
||||
/* Test behaviour for invalid file descriptors. */
|
||||
{
|
||||
errno = 0;
|
||||
ASSERT (ftruncate (-1, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
{
|
||||
close (99);
|
||||
errno = 0;
|
||||
ASSERT (ftruncate (99, 0) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
}
|
||||
|
||||
/* Test behaviour for read-only file descriptors. */
|
||||
{
|
||||
int fd = open (filename, O_RDONLY);
|
||||
ASSERT (fd >= 0);
|
||||
errno = 0;
|
||||
ASSERT (ftruncate (fd, 0) == -1);
|
||||
ASSERT (errno == EBADF || errno == EINVAL
|
||||
|| errno == EACCES /* seen on mingw */
|
||||
);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec ./test-ftruncate${EXEEXT} "$srcdir/test-ftruncate.sh"
|
||||
@@ -0,0 +1,96 @@
|
||||
/* Test of fwrite() function.
|
||||
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fwrite, size_t, (const void *, size_t, size_t, FILE *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
#endif
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const char *filename = "test-fwrite.txt";
|
||||
|
||||
/* We don't have an fwrite() function that installs an invalid parameter
|
||||
handler so far. So install that handler here, explicitly. */
|
||||
#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \
|
||||
&& MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING
|
||||
gl_msvc_inval_ensure_handler ();
|
||||
#endif
|
||||
|
||||
/* Test that fwrite() on an unbuffered stream sets errno if someone else
|
||||
closes the stream fd behind the back of stdio. */
|
||||
{
|
||||
FILE *fp = fopen (filename, "w");
|
||||
char buf[5] = "world";
|
||||
ASSERT (fp != NULL);
|
||||
setvbuf (fp, NULL, _IONBF, 0);
|
||||
ASSERT (close (fileno (fp)) == 0);
|
||||
errno = 0;
|
||||
ASSERT (fwrite (buf, 1, sizeof (buf), fp) == 0);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
/* Test that fwrite() on an unbuffered stream sets errno if the stream
|
||||
was constructed with an invalid file descriptor. */
|
||||
{
|
||||
FILE *fp = fdopen (-1, "w");
|
||||
if (fp != NULL)
|
||||
{
|
||||
char buf[5] = "world";
|
||||
setvbuf (fp, NULL, _IONBF, 0);
|
||||
errno = 0;
|
||||
ASSERT (fwrite (buf, 1, sizeof (buf), fp) == 0);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
{
|
||||
FILE *fp;
|
||||
close (99);
|
||||
fp = fdopen (99, "w");
|
||||
if (fp != NULL)
|
||||
{
|
||||
char buf[5] = "world";
|
||||
setvbuf (fp, NULL, _IONBF, 0);
|
||||
errno = 0;
|
||||
ASSERT (fwrite (buf, 1, sizeof (buf), fp) == 0);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (ferror (fp));
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
unlink (filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/* Test of getcwd() function.
|
||||
Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (getcwd, char *, (char *, size_t));
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *pwd1;
|
||||
char *pwd2;
|
||||
/* If the user provides an argument, attempt to chdir there first. */
|
||||
if (1 < argc)
|
||||
{
|
||||
if (chdir (argv[1]) == 0)
|
||||
printf ("changed to directory %s\n", argv[1]);
|
||||
}
|
||||
|
||||
pwd1 = getcwd (NULL, 0);
|
||||
ASSERT (pwd1 && *pwd1);
|
||||
if (1 < argc)
|
||||
printf ("cwd=%s\n", pwd1);
|
||||
|
||||
/* Make sure the result is usable. */
|
||||
ASSERT (chdir (pwd1) == 0);
|
||||
ASSERT (chdir (".//./.") == 0);
|
||||
|
||||
/* Make sure that result is normalized. */
|
||||
pwd2 = getcwd (NULL, 0);
|
||||
ASSERT (pwd2);
|
||||
ASSERT (strcmp (pwd1, pwd2) == 0);
|
||||
free (pwd2);
|
||||
{
|
||||
size_t len = strlen (pwd1);
|
||||
ssize_t i = len - 10;
|
||||
if (i < 1)
|
||||
i = 1;
|
||||
pwd2 = getcwd (NULL, len + 1);
|
||||
ASSERT (pwd2);
|
||||
free (pwd2);
|
||||
pwd2 = malloc (len + 2);
|
||||
for ( ; i <= len; i++)
|
||||
{
|
||||
char *tmp;
|
||||
errno = 0;
|
||||
ASSERT (getcwd (pwd2, i) == NULL);
|
||||
ASSERT (errno == ERANGE);
|
||||
/* Allow either glibc or BSD behavior, since POSIX allows both. */
|
||||
errno = 0;
|
||||
tmp = getcwd (NULL, i);
|
||||
if (tmp)
|
||||
{
|
||||
ASSERT (strcmp (pwd1, tmp) == 0);
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT (errno == ERANGE);
|
||||
}
|
||||
}
|
||||
ASSERT (getcwd (pwd2, len + 1) == pwd2);
|
||||
pwd2[len] = '/';
|
||||
pwd2[len + 1] = '\0';
|
||||
}
|
||||
ASSERT (strstr (pwd2, "/./") == NULL);
|
||||
ASSERT (strstr (pwd2, "/../") == NULL);
|
||||
ASSERT (strstr (pwd2 + 1 + (pwd2[1] == '/'), "//") == NULL);
|
||||
|
||||
/* Validate a POSIX requirement on size. */
|
||||
errno = 0;
|
||||
ASSERT (getcwd(pwd2, 0) == NULL);
|
||||
ASSERT (errno == EINVAL);
|
||||
|
||||
free (pwd1);
|
||||
free (pwd2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Test of getdtablesize() function.
|
||||
Copyright (C) 2008-2017 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (getdtablesize, int, (void));
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
ASSERT (getdtablesize () >= 3);
|
||||
ASSERT (dup2 (0, getdtablesize() - 1) == getdtablesize () - 1);
|
||||
ASSERT (dup2 (0, getdtablesize()) == -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user