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:
2026-07-05 22:29:19 +03:00
parent 7a2b0d5160
commit b8aac3c9bc
2226 changed files with 876572 additions and 2382 deletions
@@ -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