build: Remove gnulib.

As part of our efforts to clean up and simplify libguestfs, removing
gnulib deletes a large dependency that we mostly no longer use and
causes problems for new users trying to build the library from source.

A few modules from gnulib are still used (under a compatible license)
and these are copied into gnulib/lib/
This commit is contained in:
Richard W.M. Jones
2021-04-06 11:30:42 +01:00
parent 48e7520ec5
commit 0f54df53d2
50 changed files with 3964 additions and 798 deletions

3
.gitignore vendored
View File

@@ -205,8 +205,6 @@ Makefile.in
/generator/stamp-generator
/.gitattributes
/.git-module-status
/gnulib
/GNUmakefile
/gobject/bindtests.js
/gobject/Guestfs-1.0.gir
/gobject/Guestfs-1.0.typelib
@@ -266,7 +264,6 @@ Makefile.in
/lua/guestfs.so
/lua/lua-guestfs.c
/m4/ChangeLog
/m4/gnulib-cache.m4
/m4/intmax.m4
/m4/libtool.m4
/m4/lt~obsolete.m4

3
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "gnulib"]
path = .gnulib
url = https://git.savannah.gnu.org/git/gnulib.git
[submodule "common"]
path = common
url = https://github.com/libguestfs/libguestfs-common

Submodule .gnulib deleted from 25a7d014d6

View File

@@ -26,13 +26,8 @@ SUBDIRS = common/mlstdutils generator
# tests run.
SUBDIRS += test-data
# Gnulib - must be built and tested before the library.
SUBDIRS += gnulib/lib
if ENABLE_GNULIB_TESTS
SUBDIRS += gnulib/tests
endif
# Basic source for the library.
SUBDIRS += gnulib/lib
SUBDIRS += common/errnostring common/protocol common/qemuopts
SUBDIRS += common/utils
SUBDIRS += common/structs
@@ -126,12 +121,9 @@ EXTRA_DIST = \
.gitignore \
.lvimrc \
.mailmap \
bootstrap \
bugs-in-changelog.sh \
autogen.sh \
bindtests \
build-aux/config.rpath \
cfg.mk \
check-mli.sh \
common/.gitignore \
common/README \
@@ -234,7 +226,7 @@ BUGS: configure.ac
docs/C_SOURCE_FILES: configure.ac
rm -f $@ $@-t
find $(DIST_SUBDIRS) -name '*.[ch]' | \
grep -v -E '^(builder/index-parse\.|builder/index-scan\.|examples/|gnulib/|gobject/|java/com_redhat_et_libguestfs|perl/|php/extension/config\.h|ruby/ext/guestfs/extconf\.h|tests/|test-data/|bundled/)' | \
grep -v -E '^(builder/index-parse\.|builder/index-scan\.|examples/|gobject/|java/com_redhat_et_libguestfs|perl/|php/extension/config\.h|ruby/ext/guestfs/extconf\.h|tests/|test-data/|bundled/)' | \
grep -v -E '/(guestfs|rc)_protocol\.' | \
grep -v -E '.*/errnostring\.' | \
grep -v -E '.*-gperf\.' | \
@@ -247,7 +239,7 @@ po/POTFILES: configure.ac
rm -f $@ $@-t
cd $(srcdir); \
find $(DIST_SUBDIRS) -name '*.c' | \
grep -v -E '^(examples|gnulib|perl/(blib|examples)|po-docs|tests|test-data|bundled)/' | \
grep -v -E '^(examples|perl/(blib|examples)|po-docs|tests|test-data|bundled)/' | \
grep -v -E '/((guestfs|rc)_protocol\.c|dummy\.c)$$' | \
grep -v -E '^python/utils\.c$$' | \
grep -v -E '^perl/lib/Sys/Guestfs\.c$$' | \
@@ -490,7 +482,6 @@ maintainer-check-extra-dist:
grep -v '^common/mlxml/' | \
grep -v '^intltool-.*\.in' | \
grep -v '^\.gitmodules' | \
grep -v '^\.gnulib' | \
sort > tmp/gitfiles
comm -13 tmp/tarfiles tmp/gitfiles > tmp/comm-out
@echo Checking for differences between EXTRA_DIST and git ...

View File

@@ -1,51 +0,0 @@
#!/bin/bash -
# libguestfs
# Copyright (C) 2009 Red Hat 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Rebuild the autotools environment.
set -e
set -v
# Ensure that whenever we pull in a gnulib update or otherwise change to a
# different version (i.e., when switching branches), we also rerun ./bootstrap.
curr_status=.git-module-status
t=$(git submodule status | grep gnulib | sed 's/^[ +-]//;s/ .*//')
if test "$t" = "$(cat $curr_status 2>/dev/null)"; then
: # good, it's up to date
else
echo running bootstrap...
./bootstrap && echo "$t" > $curr_status
fi
CONFIGUREDIR=.
# Run configure in BUILDDIR if it's set
if [ ! -z "$BUILDDIR" ]; then
mkdir -p $BUILDDIR
cd $BUILDDIR
CONFIGUREDIR=..
fi
# If no arguments were specified and configure has run before, use the previous
# arguments
if test $# -eq 0 && test -x ./config.status; then
./config.status --recheck
else
$CONFIGUREDIR/configure "$@"
fi

174
bootstrap
View File

@@ -1,174 +0,0 @@
#!/bin/sh
usage() {
echo >&2 "\
Usage: $0 [OPTION]...
Bootstrap this package from the checked-out sources.
Options:
--gnulib-srcdir=DIRNAME specify the local directory where gnulib
sources reside. Use this if you already
have gnulib sources on your machine, and
do not want to waste your bandwidth downloading
them again. Defaults to \$GNULIB_SRCDIR
"
}
for option
do
case $option in
--help)
usage
exit;;
--gnulib-srcdir=*)
GNULIB_SRCDIR=${option#--gnulib-srcdir=};;
*)
echo >&2 "$0: $option: unknown option"
exit 1;;
esac
done
cleanup_gnulib() {
status=$?
rm -fr "$gnulib_path"
exit $status
}
git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@"
}
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
# submodule, for use in the rest of the script.
case ${GNULIB_SRCDIR--} in
-)
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init -- "$gnulib_path" || exit $?
git submodule update -- "$gnulib_path" || exit $?
elif [ ! -d "$gnulib_path" ]; then
echo "$0: getting gnulib files..."
trap cleanup_gnulib 1 2 13 15
shallow=
git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" ||
cleanup_gnulib
trap - 1 2 13 15
fi
GNULIB_SRCDIR=$gnulib_path
;;
*)
# Use GNULIB_SRCDIR directly or as a reference.
if test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
# Prefer the one-liner available in git 1.6.4 or newer.
git submodule update --init --reference "$GNULIB_SRCDIR" \
"$gnulib_path" || exit $?
else
# This fallback allows at least git 1.5.5.
if test -f "$gnulib_path"/gnulib-tool; then
# Since file already exists, assume submodule init already complete.
git submodule update -- "$gnulib_path" || exit $?
else
# Older git can't clone into an empty directory.
rmdir "$gnulib_path" 2>/dev/null
git clone --reference "$GNULIB_SRCDIR" \
"$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
&& git submodule init -- "$gnulib_path" \
&& git submodule update -- "$gnulib_path" \
|| exit $?
fi
fi
GNULIB_SRCDIR=$gnulib_path
fi
;;
esac
# Autoreconf runs aclocal before libtoolize, which causes spurious
# warnings if the initial aclocal is confused by the libtoolized
# (or worse out-of-date) macro directory.
libtoolize --copy --install
gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
<$gnulib_tool || exit
modules='
accept4
areadlinkat
base64
byteswap
c-ctype
cloexec
closeout
connect
error
fstatat
full-read
full-write
futimens
getline
getprogname
gitlog-to-changelog
glob
gnumakefile
hash
hash-pjw
human
ignore-value
intprops
lock
maintainer-makefile
manywarnings
memmem
mkdtemp
mkstemps
netdb
nonblocking
perror
pipe2
pread
readlink
select
setenv
sleep
socket
strchrnul
strerror
strndup
sys_select
sys_types
sys_wait
tls
vasprintf
vc-list-files
warnings
xstrtol
xstrtoll
xvasprintf
'
# If any tests fail, avoid including them by adding them to
# this list.
avoid="--avoid=dummy --avoid=getlogin_r-tests"
$gnulib_tool \
$avoid \
--with-tests \
--m4-base=m4 \
--source-base=gnulib/lib \
--tests-base=gnulib/tests \
--libtool \
--import $modules
# Disable autopoint and libtoolize, since they were already done above.
AUTOPOINT=true LIBTOOLIZE=true autoreconf --verbose --install

141
cfg.mk
View File

@@ -1,141 +0,0 @@
# Customize Makefile.maint. -*- makefile -*-
# Copyright (C) 2003-2012 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/>.
# Use alpha.gnu.org for alpha and beta releases.
# Use ftp.gnu.org for major releases.
gnu_ftp_host-alpha = alpha.gnu.org
gnu_ftp_host-beta = alpha.gnu.org
gnu_ftp_host-major = ftp.gnu.org
gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
url_dir_list = \
ftp://$(gnu_rel_host)/gnu/coreutils
# Exclude some filenames.
exclude_file_name_regexp--sc_bindtextdomain = ^(daemon|erlang|examples|tests)/|/test-
exclude_file_name_regexp--sc_error_message_period = ^(generator|php|po-docs)/
exclude_file_name_regexp--sc_prohibit_always-defined_macros = ^examples/|^tests/xml/fake-libvirt-xml\.c|^daemon/guestfsd\.c
exclude_file_name_regexp--sc_prohibit_doubled_word = ^po/
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = ^test-data/|\.patch$|\.png$
exclude_file_name_regexp--sc_prohibit_magic_number_exit = ^(po|po-docs)/|\.pod$|^fuse/guestunmount\.c
exclude_file_name_regexp--sc_prohibit_strcmp = ^(examples|po-docs)/|\.pod$
exclude_file_name_regexp--sc_prohibit_strcmp_and_strncmp = ^(examples|po-docs)/|\.pod$
exclude_file_name_regexp--sc_prohibit_strncpy = ^lib/launch-.*\.c$
exclude_file_name_regexp--sc_require_config_h = ^examples/|^tests/c-api/test-just-header\.c$
exclude_file_name_regexp--sc_require_config_h_first = ^examples/|^tests/c-api/test-just-header\.c$|^python/guestfs-py-byhand\.c$
# Tests not to run as part of "make distcheck".
local-checks-to-skip = \
sc_po_check \
sc_GPL_version \
sc_error_exit_success \
sc_file_system \
sc_makefile_path_separator_check \
sc_obsolete_symbols \
sc_prohibit_atoi_atof \
sc_prohibit_quote_without_use \
sc_prohibit_quotearg_without_use \
sc_prohibit_stat_st_blocks \
sc_space_tab \
sc_two_space_separator_in_usage \
sc_error_message_uppercase \
sc_program_name \
$(disable_temporarily) \
sc_useless_cpp_parens \
sc_cast_of_argument_to_free
disable_temporarily = \
sc_makefile_check \
sc_unmarked_diagnostics \
sc_prohibit_ctype_h \
sc_prohibit_asprintf \
sc_avoid_write
# Avoid uses of write(2). Either switch to streams (fwrite), or use
# the safewrite wrapper.
sc_avoid_write:
@if $(VC_LIST_EXCEPT) | grep '\.c$$' > /dev/null; then \
grep '\<write *(' $$($(VC_LIST_EXCEPT) | grep '\.c$$') && \
{ echo "$(ME): the above files use write;" \
" consider using the safewrite wrapper instead" \
1>&2; exit 1; } || :; \
else :; \
fi
# Use STREQ rather than comparing strcmp == 0, or != 0.
# Similarly, use STREQLEN or STRPREFIX rather than strncmp.
sc_prohibit_strcmp_and_strncmp:
@grep -nE '! *strn?cmp *\(|\<strn?cmp *\([^)]+\) *==' \
$$($(VC_LIST_EXCEPT)) \
| grep -vE ':# *define STREQ(LEN)?\(' && \
{ echo '$(ME): use STREQ(LEN) in place of the above uses of strcmp(strncmp)' \
1>&2; exit 1; } || :
# Use virAsprintf rather than a'sprintf since *strp is undefined on error.
sc_prohibit_asprintf:
@re='\<[a]sprintf\>' \
msg='use virAsprintf, not a'sprintf \
$(_prohibit_regexp)
# Prohibit the inclusion of <ctype.h>.
sc_prohibit_ctype_h:
@grep -E '^# *include *<ctype\.h>' $$($(VC_LIST_EXCEPT)) && \
{ echo "$(ME): don't use ctype.h; instead, use c-ctype.h" \
1>&2; exit 1; } || :
ctype_re = isalnum|isalpha|isascii|isblank|iscntrl|isdigit|isgraph|islower\
|isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper
sc_avoid_ctype_macros:
@grep -E '\b($(ctype_re)) *\(' /dev/null \
$$($(VC_LIST_EXCEPT)) && \
{ echo "$(ME): don't use ctype macros (use c-ctype.h)" \
1>&2; exit 1; } || :
sc_prohibit_virBufferAdd_with_string_literal:
@prohibit='\<virBufferAdd *\([^,]+, *"[^"]' \
halt='use virBufferAddLit, not virBufferAdd, with a string literal' \
$(_sc_search_regexp)
# Not only do they fail to deal well with ipv6, but the gethostby*
# functions are also not thread-safe.
sc_prohibit_gethostby:
@prohibit='\<gethostby(addr|name2?) *\(' \
halt='use getaddrinfo, not gethostby*' \
$(_sc_search_regexp)
# We don't use this feature of maint.mk.
prev_version_file = /dev/null
ifeq (0,$(MAKELEVEL))
_curr_status = .git-module-status
# The sed filter accommodates those who check out on a commit from which
# no tag is reachable. In that case, git submodule status prints a "-"
# in column 1 and does not print a "git describe"-style string after the
# submodule name. Contrast these:
# -b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib
# b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib (v0.0-2286-gb653eda)
# $ cat .git-module-status
# b653eda3ac4864de205419d9f41eec267cb89eeb
_submodule_hash = sed 's/^[ +-]//;s/ .*//'
_update_required := $(shell \
actual=$$(git submodule status | grep gnulib | $(_submodule_hash)); \
stamp="$$($(_submodule_hash) $(_curr_status) 2>/dev/null)"; \
test "$$stamp" = "$$actual"; echo $$?)
ifeq (1,$(_update_required))
$(error gnulib update required; run ./autogen.sh first)
endif
endif

View File

@@ -85,11 +85,6 @@ PACKAGE_VERSION_FULL="libguestfs_major.libguestfs_minor.libguestfs_release${libg
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_FULL],["$PACKAGE_VERSION_FULL"],[Full version string.])
AC_SUBST([PACKAGE_VERSION_FULL])
dnl Early gnulib initialization.
HEADING([Configuring Gnulib])
gl_EARLY
gl_INIT
dnl Check for external programs required to either build or run
dnl libguestfs.
HEADING([Checking for external programs])
@@ -242,7 +237,6 @@ AC_CONFIG_FILES([Makefile
fuse/Makefile
generator/Makefile
gnulib/lib/Makefile
gnulib/tests/Makefile
gobject/libguestfs-gobject-1.0.pc
gobject/Makefile
golang/Makefile

View File

@@ -25,14 +25,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <error.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <error.h>
#include <errno.h>
#include "ignore-value.h"

View File

@@ -49,7 +49,6 @@
#include "c-ctype.h"
#include "ignore-value.h"
#include "sockets.h"
#include "daemon.h"

View File

@@ -24,8 +24,8 @@
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include "areadlink.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "daemon.h"
#include "actions.h"
@@ -47,20 +47,36 @@ do_internal_readlinklist (const char *path, char *const *names)
}
for (i = 0; names[i] != NULL; ++i) {
CLEANUP_FREE char *link = NULL;
struct stat statbuf;
size_t n;
ssize_t r;
/* Because of the way this function is intended to be used,
* we actually expect to see errors here, and they are not fatal.
*/
CLEANUP_FREE char *link = areadlinkat (fd_cwd, names[i]);
if (link != NULL) {
if (add_string (&ret, link) == -1) {
add_string_failed:
if (fstatat (fd_cwd, names[i], &statbuf, AT_SYMLINK_NOFOLLOW) == -1) {
add_empty_string:
if (add_string (&ret, "") == -1) {
close (fd_cwd);
return NULL;
}
} else {
if (add_string (&ret, "") == -1)
goto add_string_failed;
}
if (!S_ISLNK (statbuf.st_mode))
goto add_empty_string;
n = statbuf.st_size;
link = malloc (n+1);
if (link == NULL)
goto add_empty_string;
r = readlinkat (fd_cwd, names[i], link, n);
if (r == -1 || r != n)
goto add_empty_string;
link[n] = '\0';
if (add_string (&ret, link) == -1) {
close (fd_cwd);
return NULL;
}
}

View File

@@ -402,7 +402,8 @@ git.
git clone https://github.com/libguestfs/libguestfs
cd libguestfs
git submodule update --init
CFLAGS=-fPIC ./autogen.sh
autoreconf -i
./configure CFLAGS=-fPIC
make
=head1 BUILDING FROM TARBALLS
@@ -497,11 +498,11 @@ are ignored by git. These files can contain local configuration or
scripts that you need to build libguestfs.
I have a file called F<localconfigure> which is a simple wrapper
around F<autogen.sh> containing local configure customizations that I
around F<configure> containing local configure customizations that I
need. It looks like this:
. localenv
./autogen.sh \
./configure.sh \
-C \
--enable-werror \
"$@"
@@ -570,11 +571,6 @@ OCaml tools.
Disable FUSE support in the API and the L<guestmount(1)> tool.
=item B<--disable-gnulib-tests>
On some platforms the GNUlib test suite can be flaky. This disables
it, since errors in the GNUlib test suite are often not important.
=item B<--disable-static>
Dont build a static linked version of the libguestfs library.

View File

@@ -403,7 +403,7 @@ should contain:
source localenv
#export PATH=/tmp/qemu/x86_64-softmmu:$PATH
./autogen.sh --prefix /usr "$@"
./configure --prefix /usr "$@"
Make C<localconfigure> executable.
@@ -431,7 +431,7 @@ enough supermin installed, then see the previous question.
If supermin 5 doesn't support your distro at all, you will need to use
the "fixed appliance method" where you use a pre-compiled binary
appliance. To build libguestfs without supermin, you need to pass
C<--disable-appliance --disable-daemon> to either F<./autogen.sh> or
C<--disable-appliance --disable-daemon> to either F<./configure> or
F<./configure> (depending whether you are building respectively from
git or from tarballs). Then, when using libguestfs, you B<must> set
the C<LIBGUESTFS_PATH> environment variable to the directory of a

View File

@@ -14,7 +14,7 @@ L<https://github.com/libguestfs/libguestfs>
Large amounts of boilerplate code in libguestfs (RPC, bindings,
documentation) are generated. This means that many source files will
appear to be missing from a straightforward git checkout. You have to
run the generator (C<./autogen.sh && make -C generator>) in order to
run the generator (C<./configure && make -C generator>) in order to
create those files.
Libguestfs uses an autotools-based build system, with the main files
@@ -250,11 +250,6 @@ large amounts of boilerplate C code for things like RPC and bindings.
L<virt-get-kernel(1)> command and documentation.
=item F<gnulib>
Gnulib is used as a portability library. A copy of gnulib is included
under here.
=item F<inspector>
L<virt-inspector(1)>, the virtual machine image inspector.
@@ -799,7 +794,7 @@ the libguestfs source tree must be the same.
Do:
./autogen.sh
./configure
make clean ||:
make
make installcheck
@@ -921,7 +916,7 @@ command, the list of objects and the C<-cclib> libraries in the
correct order otherwise.
virt_customize_LINK = \
$(top_builddir)/ocaml-link.sh -cclib '-lutils -lgnu' -- ...
$(top_builddir)/ocaml-link.sh -cclib '-lutils' -- ...
The actual rules, which you can examine in F<customize/Makefile.am>, are a
little bit more complicated than this because they have to handle:
@@ -1029,10 +1024,6 @@ Finalize F<guestfs-release-notes.pod>
=item *
Consider updating gnulib to latest upstream version.
=item *
Create new stable and development directories under
L<http://libguestfs.org/download>.

View File

@@ -33,6 +33,7 @@
#include <signal.h>
#include <errno.h>
#include <error.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <locale.h>
@@ -52,7 +53,6 @@
#include "progress.h"
#include "c-ctype.h"
#include "closeout.h"
#include "ignore-value.h"
#include "getprogname.h"
@@ -178,9 +178,6 @@ usage (int status)
int
main (int argc, char *argv[])
{
/* Initialize gnulib closeout module. */
atexit (close_stdout);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEBASEDIR);
textdomain (PACKAGE);

View File

@@ -30,6 +30,7 @@
#include <error.h>
#include <getopt.h>
#include <signal.h>
#include <limits.h>
#include <locale.h>
#include <libintl.h>

View File

@@ -31,6 +31,7 @@
#include <locale.h>
#include <libintl.h>
#include <poll.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>

57
gnulib/lib/Makefile.am Normal file
View File

@@ -0,0 +1,57 @@
# libguestfs
# Copyright (C) 2017-2021 Red Hat 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 2 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# This directory contains some dependencies originally from gnulib.
# The aim is for everything in this directory to eventually go away,
# probably being moved to common/utils.
include $(top_srcdir)/subdir-rules.mk
noinst_LTLIBRARIES = libgnu.la
libgnu_la_SOURCES = \
base64.c \
base64.h \
bitrotate.h \
c-ctype.h \
cloexec.c \
cloexec.h \
full-read.c \
full-read.h \
full-write.c \
full-write.h \
getprogname.h \
hash.c \
hash.h \
hash-pjw.c \
hash-pjw.h \
ignore-value.h \
nonblocking.c \
nonblocking.h \
safe-read.c \
safe-read.h \
safe-write.c \
safe-write.h \
xalloc-oversized.h \
xstrtol.c \
xstrtol.h \
xstrtoll.c \
xstrtoul.c \
xstrtoull.c \
xstrtoumax.c
libutils_la_CFLAGS = \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(GCC_VISIBILITY_HIDDEN)

612
gnulib/lib/base64.c Normal file
View File

@@ -0,0 +1,612 @@
/* base64.c -- Encode binary data using printable characters.
Copyright (C) 1999-2001, 2004-2006, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Written by Simon Josefsson. Partially adapted from GNU MailUtils
* (mailbox/filter_trans.c, as of 2004-11-28). Improved by review
* from Paul Eggert, Bruno Haible, and Stepan Kasal.
*
* See also RFC 4648 <https://www.ietf.org/rfc/rfc4648.txt>.
*
* Be careful with error checking. Here is how you would typically
* use these functions:
*
* bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
* if (!ok)
* FAIL: input was not valid base64
* if (out == NULL)
* FAIL: memory allocation error
* OK: data in OUT/OUTLEN
*
* size_t outlen = base64_encode_alloc (in, inlen, &out);
* if (out == NULL && outlen == 0 && inlen != 0)
* FAIL: input too long
* if (out == NULL)
* FAIL: memory allocation error
* OK: data in OUT/OUTLEN.
*
*/
#include <config.h>
/* Get prototype. */
#include "base64.h"
/* Get malloc. */
#include <stdlib.h>
/* Get UCHAR_MAX. */
#include <limits.h>
#include <string.h>
/* C89 compliant way to cast 'char' to 'unsigned char'. */
static unsigned char
to_uchar (char ch)
{
return ch;
}
static const char b64c[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* Base64 encode IN array of size INLEN into OUT array. OUT needs
to be of length >= BASE64_LENGTH(INLEN), and INLEN needs to be
a multiple of 3. */
static void
base64_encode_fast (const char *restrict in, size_t inlen, char *restrict out)
{
while (inlen)
{
*out++ = b64c[(to_uchar (in[0]) >> 2) & 0x3f];
*out++ = b64c[((to_uchar (in[0]) << 4) + (to_uchar (in[1]) >> 4)) & 0x3f];
*out++ = b64c[((to_uchar (in[1]) << 2) + (to_uchar (in[2]) >> 6)) & 0x3f];
*out++ = b64c[to_uchar (in[2]) & 0x3f];
inlen -= 3;
in += 3;
}
}
/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
terminate the output buffer. */
void
base64_encode (const char *restrict in, size_t inlen,
char *restrict out, size_t outlen)
{
/* Note this outlen constraint can be enforced at compile time.
I.E. that the output buffer is exactly large enough to hold
the encoded inlen bytes. The inlen constraints (of corresponding
to outlen, and being a multiple of 3) can change at runtime
at the end of input. However the common case when reading
large inputs is to have both constraints satisfied, so we depend
on both in base_encode_fast(). */
if (outlen % 4 == 0 && inlen == outlen / 4 * 3)
{
base64_encode_fast (in, inlen, out);
return;
}
while (inlen && outlen)
{
*out++ = b64c[(to_uchar (in[0]) >> 2) & 0x3f];
if (!--outlen)
break;
*out++ = b64c[((to_uchar (in[0]) << 4)
+ (--inlen ? to_uchar (in[1]) >> 4 : 0))
& 0x3f];
if (!--outlen)
break;
*out++ =
(inlen
? b64c[((to_uchar (in[1]) << 2)
+ (--inlen ? to_uchar (in[2]) >> 6 : 0))
& 0x3f]
: '=');
if (!--outlen)
break;
*out++ = inlen ? b64c[to_uchar (in[2]) & 0x3f] : '=';
if (!--outlen)
break;
if (inlen)
inlen--;
if (inlen)
in += 3;
}
if (outlen)
*out = '\0';
}
/* Allocate a buffer and store zero terminated base64 encoded data
from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
the length of the encoded data, excluding the terminating zero. On
return, the OUT variable will hold a pointer to newly allocated
memory that must be deallocated by the caller. If output string
length would overflow, 0 is returned and OUT is set to NULL. If
memory allocation failed, OUT is set to NULL, and the return value
indicates length of the requested memory block, i.e.,
BASE64_LENGTH(inlen) + 1. */
size_t
base64_encode_alloc (const char *in, size_t inlen, char **out)
{
size_t outlen = 1 + BASE64_LENGTH (inlen);
/* Check for overflow in outlen computation.
*
* If there is no overflow, outlen >= inlen.
*
* If the operation (inlen + 2) overflows then it yields at most +1, so
* outlen is 0.
*
* If the multiplication overflows, we lose at least half of the
* correct value, so the result is < ((inlen + 2) / 3) * 2, which is
* less than (inlen + 2) * 0.66667, which is less than inlen as soon as
* (inlen > 4).
*/
if (inlen > outlen)
{
*out = NULL;
return 0;
}
*out = malloc (outlen);
if (!*out)
return outlen;
base64_encode (in, inlen, *out, outlen);
return outlen - 1;
}
/* With this approach this file works independent of the charset used
(think EBCDIC). However, it does assume that the characters in the
Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX
1003.1-2001 require that char and unsigned char are 8-bit
quantities, though, taking care of that problem. But this may be a
potential problem on non-POSIX C99 platforms.
IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
as the formal parameter rather than "x". */
#define B64(_) \
((_) == 'A' ? 0 \
: (_) == 'B' ? 1 \
: (_) == 'C' ? 2 \
: (_) == 'D' ? 3 \
: (_) == 'E' ? 4 \
: (_) == 'F' ? 5 \
: (_) == 'G' ? 6 \
: (_) == 'H' ? 7 \
: (_) == 'I' ? 8 \
: (_) == 'J' ? 9 \
: (_) == 'K' ? 10 \
: (_) == 'L' ? 11 \
: (_) == 'M' ? 12 \
: (_) == 'N' ? 13 \
: (_) == 'O' ? 14 \
: (_) == 'P' ? 15 \
: (_) == 'Q' ? 16 \
: (_) == 'R' ? 17 \
: (_) == 'S' ? 18 \
: (_) == 'T' ? 19 \
: (_) == 'U' ? 20 \
: (_) == 'V' ? 21 \
: (_) == 'W' ? 22 \
: (_) == 'X' ? 23 \
: (_) == 'Y' ? 24 \
: (_) == 'Z' ? 25 \
: (_) == 'a' ? 26 \
: (_) == 'b' ? 27 \
: (_) == 'c' ? 28 \
: (_) == 'd' ? 29 \
: (_) == 'e' ? 30 \
: (_) == 'f' ? 31 \
: (_) == 'g' ? 32 \
: (_) == 'h' ? 33 \
: (_) == 'i' ? 34 \
: (_) == 'j' ? 35 \
: (_) == 'k' ? 36 \
: (_) == 'l' ? 37 \
: (_) == 'm' ? 38 \
: (_) == 'n' ? 39 \
: (_) == 'o' ? 40 \
: (_) == 'p' ? 41 \
: (_) == 'q' ? 42 \
: (_) == 'r' ? 43 \
: (_) == 's' ? 44 \
: (_) == 't' ? 45 \
: (_) == 'u' ? 46 \
: (_) == 'v' ? 47 \
: (_) == 'w' ? 48 \
: (_) == 'x' ? 49 \
: (_) == 'y' ? 50 \
: (_) == 'z' ? 51 \
: (_) == '0' ? 52 \
: (_) == '1' ? 53 \
: (_) == '2' ? 54 \
: (_) == '3' ? 55 \
: (_) == '4' ? 56 \
: (_) == '5' ? 57 \
: (_) == '6' ? 58 \
: (_) == '7' ? 59 \
: (_) == '8' ? 60 \
: (_) == '9' ? 61 \
: (_) == '+' ? 62 \
: (_) == '/' ? 63 \
: -1)
static const signed char b64[0x100] = {
B64 (0), B64 (1), B64 (2), B64 (3),
B64 (4), B64 (5), B64 (6), B64 (7),
B64 (8), B64 (9), B64 (10), B64 (11),
B64 (12), B64 (13), B64 (14), B64 (15),
B64 (16), B64 (17), B64 (18), B64 (19),
B64 (20), B64 (21), B64 (22), B64 (23),
B64 (24), B64 (25), B64 (26), B64 (27),
B64 (28), B64 (29), B64 (30), B64 (31),
B64 (32), B64 (33), B64 (34), B64 (35),
B64 (36), B64 (37), B64 (38), B64 (39),
B64 (40), B64 (41), B64 (42), B64 (43),
B64 (44), B64 (45), B64 (46), B64 (47),
B64 (48), B64 (49), B64 (50), B64 (51),
B64 (52), B64 (53), B64 (54), B64 (55),
B64 (56), B64 (57), B64 (58), B64 (59),
B64 (60), B64 (61), B64 (62), B64 (63),
B64 (64), B64 (65), B64 (66), B64 (67),
B64 (68), B64 (69), B64 (70), B64 (71),
B64 (72), B64 (73), B64 (74), B64 (75),
B64 (76), B64 (77), B64 (78), B64 (79),
B64 (80), B64 (81), B64 (82), B64 (83),
B64 (84), B64 (85), B64 (86), B64 (87),
B64 (88), B64 (89), B64 (90), B64 (91),
B64 (92), B64 (93), B64 (94), B64 (95),
B64 (96), B64 (97), B64 (98), B64 (99),
B64 (100), B64 (101), B64 (102), B64 (103),
B64 (104), B64 (105), B64 (106), B64 (107),
B64 (108), B64 (109), B64 (110), B64 (111),
B64 (112), B64 (113), B64 (114), B64 (115),
B64 (116), B64 (117), B64 (118), B64 (119),
B64 (120), B64 (121), B64 (122), B64 (123),
B64 (124), B64 (125), B64 (126), B64 (127),
B64 (128), B64 (129), B64 (130), B64 (131),
B64 (132), B64 (133), B64 (134), B64 (135),
B64 (136), B64 (137), B64 (138), B64 (139),
B64 (140), B64 (141), B64 (142), B64 (143),
B64 (144), B64 (145), B64 (146), B64 (147),
B64 (148), B64 (149), B64 (150), B64 (151),
B64 (152), B64 (153), B64 (154), B64 (155),
B64 (156), B64 (157), B64 (158), B64 (159),
B64 (160), B64 (161), B64 (162), B64 (163),
B64 (164), B64 (165), B64 (166), B64 (167),
B64 (168), B64 (169), B64 (170), B64 (171),
B64 (172), B64 (173), B64 (174), B64 (175),
B64 (176), B64 (177), B64 (178), B64 (179),
B64 (180), B64 (181), B64 (182), B64 (183),
B64 (184), B64 (185), B64 (186), B64 (187),
B64 (188), B64 (189), B64 (190), B64 (191),
B64 (192), B64 (193), B64 (194), B64 (195),
B64 (196), B64 (197), B64 (198), B64 (199),
B64 (200), B64 (201), B64 (202), B64 (203),
B64 (204), B64 (205), B64 (206), B64 (207),
B64 (208), B64 (209), B64 (210), B64 (211),
B64 (212), B64 (213), B64 (214), B64 (215),
B64 (216), B64 (217), B64 (218), B64 (219),
B64 (220), B64 (221), B64 (222), B64 (223),
B64 (224), B64 (225), B64 (226), B64 (227),
B64 (228), B64 (229), B64 (230), B64 (231),
B64 (232), B64 (233), B64 (234), B64 (235),
B64 (236), B64 (237), B64 (238), B64 (239),
B64 (240), B64 (241), B64 (242), B64 (243),
B64 (244), B64 (245), B64 (246), B64 (247),
B64 (248), B64 (249), B64 (250), B64 (251),
B64 (252), B64 (253), B64 (254), B64 (255)
};
#if UCHAR_MAX == 255
# define uchar_in_range(c) true
#else
# define uchar_in_range(c) ((c) <= 255)
#endif
/* Return true if CH is a character from the Base64 alphabet, and
false otherwise. Note that '=' is padding and not considered to be
part of the alphabet. */
bool
isbase64 (char ch)
{
return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
}
/* Initialize decode-context buffer, CTX. */
void
base64_decode_ctx_init (struct base64_decode_context *ctx)
{
ctx->i = 0;
}
/* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
none of those four is a newline, then return *IN. Otherwise, copy up to
4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
index CTX->i and setting CTX->i to reflect the number of bytes copied,
and return CTX->buf. In either case, advance *IN to point to the byte
after the last one processed, and set *N_NON_NEWLINE to the number of
verified non-newline bytes accessible through the returned pointer. */
static char *
get_4 (struct base64_decode_context *ctx,
char const *restrict *in, char const *restrict in_end,
size_t *n_non_newline)
{
if (ctx->i == 4)
ctx->i = 0;
if (ctx->i == 0)
{
char const *t = *in;
if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
{
/* This is the common case: no newline. */
*in += 4;
*n_non_newline = 4;
return (char *) t;
}
}
{
/* Copy non-newline bytes into BUF. */
char const *p = *in;
while (p < in_end)
{
char c = *p++;
if (c != '\n')
{
ctx->buf[ctx->i++] = c;
if (ctx->i == 4)
break;
}
}
*in = p;
*n_non_newline = ctx->i;
return ctx->buf;
}
}
#define return_false \
do \
{ \
*outp = out; \
return false; \
} \
while (false)
/* Decode up to four bytes of base64-encoded data, IN, of length INLEN
into the output buffer, *OUT, of size *OUTLEN bytes. Return true if
decoding is successful, false otherwise. If *OUTLEN is too small,
as many bytes as possible are written to *OUT. On return, advance
*OUT to point to the byte after the last one written, and decrement
*OUTLEN to reflect the number of bytes remaining in *OUT. */
static bool
decode_4 (char const *restrict in, size_t inlen,
char *restrict *outp, size_t *outleft)
{
char *out = *outp;
if (inlen < 2)
return false;
if (!isbase64 (in[0]) || !isbase64 (in[1]))
return false;
if (*outleft)
{
*out++ = ((b64[to_uchar (in[0])] << 2)
| (b64[to_uchar (in[1])] >> 4));
--*outleft;
}
if (inlen == 2)
return_false;
if (in[2] == '=')
{
if (inlen != 4)
return_false;
if (in[3] != '=')
return_false;
}
else
{
if (!isbase64 (in[2]))
return_false;
if (*outleft)
{
*out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
| (b64[to_uchar (in[2])] >> 2));
--*outleft;
}
if (inlen == 3)
return_false;
if (in[3] == '=')
{
if (inlen != 4)
return_false;
}
else
{
if (!isbase64 (in[3]))
return_false;
if (*outleft)
{
*out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
| b64[to_uchar (in[3])]);
--*outleft;
}
}
}
*outp = out;
return true;
}
/* Decode base64-encoded input array IN of length INLEN to output array
OUT that can hold *OUTLEN bytes. The input data may be interspersed
with newlines. Return true if decoding was successful, i.e. if the
input was valid base64 data, false otherwise. If *OUTLEN is too
small, as many bytes as possible will be written to OUT. On return,
*OUTLEN holds the length of decoded bytes in OUT. Note that as soon
as any non-alphabet, non-newline character is encountered, decoding
is stopped and false is returned. If INLEN is zero, then process
only whatever data is stored in CTX.
Initially, CTX must have been initialized via base64_decode_ctx_init.
Subsequent calls to this function must reuse whatever state is recorded
in that buffer. It is necessary for when a quadruple of base64 input
bytes spans two input buffers.
If CTX is NULL then newlines are treated as garbage and the input
buffer is processed as a unit. */
bool
base64_decode_ctx (struct base64_decode_context *ctx,
const char *restrict in, size_t inlen,
char *restrict out, size_t *outlen)
{
size_t outleft = *outlen;
bool ignore_newlines = ctx != NULL;
bool flush_ctx = false;
unsigned int ctx_i = 0;
if (ignore_newlines)
{
ctx_i = ctx->i;
flush_ctx = inlen == 0;
}
while (true)
{
size_t outleft_save = outleft;
if (ctx_i == 0 && !flush_ctx)
{
while (true)
{
/* Save a copy of outleft, in case we need to re-parse this
block of four bytes. */
outleft_save = outleft;
if (!decode_4 (in, inlen, &out, &outleft))
break;
in += 4;
inlen -= 4;
}
}
if (inlen == 0 && !flush_ctx)
break;
/* Handle the common case of 72-byte wrapped lines.
This also handles any other multiple-of-4-byte wrapping. */
if (inlen && *in == '\n' && ignore_newlines)
{
++in;
--inlen;
continue;
}
/* Restore OUT and OUTLEFT. */
out -= outleft_save - outleft;
outleft = outleft_save;
{
char const *in_end = in + inlen;
char const *non_nl;
if (ignore_newlines)
non_nl = get_4 (ctx, &in, in_end, &inlen);
else
non_nl = in; /* Might have nl in this case. */
/* If the input is empty or consists solely of newlines (0 non-newlines),
then we're done. Likewise if there are fewer than 4 bytes when not
flushing context and not treating newlines as garbage. */
if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
{
inlen = 0;
break;
}
if (!decode_4 (non_nl, inlen, &out, &outleft))
break;
inlen = in_end - in;
}
}
*outlen -= outleft;
return inlen == 0;
}
/* Allocate an output buffer in *OUT, and decode the base64 encoded
data stored in IN of size INLEN to the *OUT buffer. On return, the
size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL,
if the caller is not interested in the decoded length. *OUT may be
NULL to indicate an out of memory error, in which case *OUTLEN
contains the size of the memory block needed. The function returns
true on successful decoding and memory allocation errors. (Use the
*OUT and *OUTLEN parameters to differentiate between successful
decoding and memory error.) The function returns false if the
input was invalid, in which case *OUT is NULL and *OUTLEN is
undefined. */
bool
base64_decode_alloc_ctx (struct base64_decode_context *ctx,
const char *in, size_t inlen, char **out,
size_t *outlen)
{
/* This may allocate a few bytes too many, depending on input,
but it's not worth the extra CPU time to compute the exact size.
The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
input ends with "=" and minus another 1 if the input ends with "==".
Dividing before multiplying avoids the possibility of overflow. */
size_t needlen = 3 * (inlen / 4) + 3;
*out = malloc (needlen);
if (!*out)
return true;
if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
{
free (*out);
*out = NULL;
return false;
}
if (outlen)
*outlen = needlen;
return true;
}

75
gnulib/lib/base64.h Normal file
View File

@@ -0,0 +1,75 @@
/* base64.h -- Encode binary data using printable characters.
Copyright (C) 2004-2006, 2009-2021 Free Software Foundation, Inc.
Written by Simon Josefsson.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BASE64_H
# define BASE64_H
/* Get size_t. */
# include <stddef.h>
/* Get bool. */
# include <stdbool.h>
# ifdef __cplusplus
extern "C" {
# endif
/* This uses that the expression (n+(k-1))/k means the smallest
integer >= n/k, i.e., the ceiling of n/k. */
# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
struct base64_decode_context
{
unsigned int i;
char buf[4];
};
extern bool isbase64 (char ch);
extern void base64_encode (const char *restrict in, size_t inlen,
char *restrict out, size_t outlen);
extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
extern void base64_decode_ctx_init (struct base64_decode_context *ctx);
extern bool base64_decode_ctx (struct base64_decode_context *ctx,
const char *restrict in, size_t inlen,
char *restrict out, size_t *outlen);
extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx,
const char *in, size_t inlen,
char **out, size_t *outlen);
#define base64_decode(in, inlen, out, outlen) \
base64_decode_ctx (NULL, in, inlen, out, outlen)
#define base64_decode_alloc(in, inlen, out, outlen) \
base64_decode_alloc_ctx (NULL, in, inlen, out, outlen)
# ifdef __cplusplus
}
# endif
#endif /* BASE64_H */

135
gnulib/lib/bitrotate.h Executable file
View File

@@ -0,0 +1,135 @@
/* bitrotate.h - Rotate bits in integers
Copyright (C) 2008-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Written by Simon Josefsson <simon@josefsson.org>, 2008. */
#ifndef _GL_BITROTATE_H
#define _GL_BITROTATE_H
#include <limits.h>
#include <stdint.h>
#include <sys/types.h>
#ifdef UINT64_MAX
/* Given an unsigned 64-bit argument X, return the value corresponding
to rotating the bits N steps to the left. N must be between 1 and
63 inclusive. */
static inline uint64_t
rotl64 (uint64_t x, int n)
{
return ((x << n) | (x >> (64 - n))) & UINT64_MAX;
}
/* Given an unsigned 64-bit argument X, return the value corresponding
to rotating the bits N steps to the right. N must be between 1 to
63 inclusive.*/
static inline uint64_t
rotr64 (uint64_t x, int n)
{
return ((x >> n) | (x << (64 - n))) & UINT64_MAX;
}
#endif
/* Given an unsigned 32-bit argument X, return the value corresponding
to rotating the bits N steps to the left. N must be between 1 and
31 inclusive. */
static inline uint32_t
rotl32 (uint32_t x, int n)
{
return ((x << n) | (x >> (32 - n))) & UINT32_MAX;
}
/* Given an unsigned 32-bit argument X, return the value corresponding
to rotating the bits N steps to the right. N must be between 1 to
31 inclusive.*/
static inline uint32_t
rotr32 (uint32_t x, int n)
{
return ((x >> n) | (x << (32 - n))) & UINT32_MAX;
}
/* Given a size_t argument X, return the value corresponding
to rotating the bits N steps to the left. N must be between 1 and
(CHAR_BIT * sizeof (size_t) - 1) inclusive. */
static inline size_t
rotl_sz (size_t x, int n)
{
return ((x << n) | (x >> ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX;
}
/* Given a size_t argument X, return the value corresponding
to rotating the bits N steps to the right. N must be between 1 to
(CHAR_BIT * sizeof (size_t) - 1) inclusive. */
static inline size_t
rotr_sz (size_t x, int n)
{
return ((x >> n) | (x << ((CHAR_BIT * sizeof x) - n))) & SIZE_MAX;
}
/* Given an unsigned 16-bit argument X, return the value corresponding
to rotating the bits N steps to the left. N must be between 1 to
15 inclusive, but on most relevant targets N can also be 0 and 16
because 'int' is at least 32 bits and the arguments must widen
before shifting. */
static inline uint16_t
rotl16 (uint16_t x, int n)
{
return (((unsigned int) x << n) | ((unsigned int) x >> (16 - n)))
& UINT16_MAX;
}
/* Given an unsigned 16-bit argument X, return the value corresponding
to rotating the bits N steps to the right. N must be in 1 to 15
inclusive, but on most relevant targets N can also be 0 and 16
because 'int' is at least 32 bits and the arguments must widen
before shifting. */
static inline uint16_t
rotr16 (uint16_t x, int n)
{
return (((unsigned int) x >> n) | ((unsigned int) x << (16 - n)))
& UINT16_MAX;
}
/* Given an unsigned 8-bit argument X, return the value corresponding
to rotating the bits N steps to the left. N must be between 1 to 7
inclusive, but on most relevant targets N can also be 0 and 8
because 'int' is at least 32 bits and the arguments must widen
before shifting. */
static inline uint8_t
rotl8 (uint8_t x, int n)
{
return (((unsigned int) x << n) | ((unsigned int) x >> (8 - n))) & UINT8_MAX;
}
/* Given an unsigned 8-bit argument X, return the value corresponding
to rotating the bits N steps to the right. N must be in 1 to 7
inclusive, but on most relevant targets N can also be 0 and 8
because 'int' is at least 32 bits and the arguments must widen
before shifting. */
static inline uint8_t
rotr8 (uint8_t x, int n)
{
return (((unsigned int) x >> n) | ((unsigned int) x << (8 - n))) & UINT8_MAX;
}
#endif /* _GL_BITROTATE_H */

363
gnulib/lib/c-ctype.h Executable file
View File

@@ -0,0 +1,363 @@
/* Character handling in C locale.
These functions work like the corresponding functions in <ctype.h>,
except that they have the C (POSIX) locale hardwired, whereas the
<ctype.h> functions' behaviour depends on the current locale set via
setlocale.
Copyright (C) 2000-2003, 2006, 2008-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef C_CTYPE_H
#define C_CTYPE_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The functions defined in this file assume the "C" locale and a character
set without diacritics (ASCII-US or EBCDIC-US or something like that).
Even if the "C" locale on a particular system is an extension of the ASCII
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
is ISO-8859-1), the functions in this file recognize only the ASCII
characters. */
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
Testing the value of '\n' and '\r' is not relevant. */
# define C_CTYPE_ASCII 1
#elif ! (' ' == '\x40' && '0' == '\xf0' \
&& 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
&& 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
# error "Only ASCII and EBCDIC are supported"
#endif
#if 'A' < 0
# error "EBCDIC and char is signed -- not supported"
#endif
/* Cases for control characters. */
#define _C_CTYPE_CNTRL \
case '\a': case '\b': case '\f': case '\n': \
case '\r': case '\t': case '\v': \
_C_CTYPE_OTHER_CNTRL
/* ASCII control characters other than those with \-letter escapes. */
#if C_CTYPE_ASCII
# define _C_CTYPE_OTHER_CNTRL \
case '\x00': case '\x01': case '\x02': case '\x03': \
case '\x04': case '\x05': case '\x06': case '\x0e': \
case '\x0f': case '\x10': case '\x11': case '\x12': \
case '\x13': case '\x14': case '\x15': case '\x16': \
case '\x17': case '\x18': case '\x19': case '\x1a': \
case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
case '\x1f': case '\x7f'
#else
/* Use EBCDIC code page 1047's assignments for ASCII control chars;
assume all EBCDIC code pages agree about these assignments. */
# define _C_CTYPE_OTHER_CNTRL \
case '\x00': case '\x01': case '\x02': case '\x03': \
case '\x07': case '\x0e': case '\x0f': case '\x10': \
case '\x11': case '\x12': case '\x13': case '\x18': \
case '\x19': case '\x1c': case '\x1d': case '\x1e': \
case '\x1f': case '\x26': case '\x27': case '\x2d': \
case '\x2e': case '\x32': case '\x37': case '\x3c': \
case '\x3d': case '\x3f'
#endif
/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */
#define _C_CTYPE_LOWER_A_THRU_F_N(N) \
case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
case 'e' + (N): case 'f' + (N)
#define _C_CTYPE_LOWER_N(N) \
_C_CTYPE_LOWER_A_THRU_F_N(N): \
case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
/* Cases for hex letters, digits, lower, punct, and upper. */
#define _C_CTYPE_A_THRU_F \
_C_CTYPE_LOWER_A_THRU_F_N (0): \
_C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
#define _C_CTYPE_DIGIT \
case '0': case '1': case '2': case '3': \
case '4': case '5': case '6': case '7': \
case '8': case '9'
#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
#define _C_CTYPE_PUNCT \
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 '~'
#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
/* Function definitions. */
/* Unlike the functions in <ctype.h>, which require an argument in the range
of the 'unsigned char' type, the functions here operate on values that are
in the 'unsigned char' range or in the 'char' range. In other words,
when you have a 'char' value, you need to cast it before using it as
argument to a <ctype.h> function:
const char *s = ...;
if (isalpha ((unsigned char) *s)) ...
but you don't need to cast it for the functions defined in this file:
const char *s = ...;
if (c_isalpha (*s)) ...
*/
static inline bool
c_isalnum (int c)
{
switch (c)
{
_C_CTYPE_DIGIT:
_C_CTYPE_LOWER:
_C_CTYPE_UPPER:
return true;
default:
return false;
}
}
static inline bool
c_isalpha (int c)
{
switch (c)
{
_C_CTYPE_LOWER:
_C_CTYPE_UPPER:
return true;
default:
return false;
}
}
/* The function isascii is not locale dependent.
Its use in EBCDIC is questionable. */
static inline bool
c_isascii (int c)
{
switch (c)
{
case ' ':
_C_CTYPE_CNTRL:
_C_CTYPE_DIGIT:
_C_CTYPE_LOWER:
_C_CTYPE_PUNCT:
_C_CTYPE_UPPER:
return true;
default:
return false;
}
}
static inline bool
c_isblank (int c)
{
return c == ' ' || c == '\t';
}
static inline bool
c_iscntrl (int c)
{
switch (c)
{
_C_CTYPE_CNTRL:
return true;
default:
return false;
}
}
static inline bool
c_isdigit (int c)
{
switch (c)
{
_C_CTYPE_DIGIT:
return true;
default:
return false;
}
}
static inline bool
c_isgraph (int c)
{
switch (c)
{
_C_CTYPE_DIGIT:
_C_CTYPE_LOWER:
_C_CTYPE_PUNCT:
_C_CTYPE_UPPER:
return true;
default:
return false;
}
}
static inline bool
c_islower (int c)
{
switch (c)
{
_C_CTYPE_LOWER:
return true;
default:
return false;
}
}
static inline bool
c_isprint (int c)
{
switch (c)
{
case ' ':
_C_CTYPE_DIGIT:
_C_CTYPE_LOWER:
_C_CTYPE_PUNCT:
_C_CTYPE_UPPER:
return true;
default:
return false;
}
}
static inline bool
c_ispunct (int c)
{
switch (c)
{
_C_CTYPE_PUNCT:
return true;
default:
return false;
}
}
static inline bool
c_isspace (int c)
{
switch (c)
{
case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
return true;
default:
return false;
}
}
static inline bool
c_isupper (int c)
{
switch (c)
{
_C_CTYPE_UPPER:
return true;
default:
return false;
}
}
static inline bool
c_isxdigit (int c)
{
switch (c)
{
_C_CTYPE_DIGIT:
_C_CTYPE_A_THRU_F:
return true;
default:
return false;
}
}
static inline int
c_tolower (int c)
{
switch (c)
{
_C_CTYPE_UPPER:
return c - 'A' + 'a';
default:
return c;
}
}
static inline int
c_toupper (int c)
{
switch (c)
{
_C_CTYPE_LOWER:
return c - 'a' + 'A';
default:
return c;
}
}
#ifdef __cplusplus
}
#endif
#endif /* C_CTYPE_H */

88
gnulib/lib/cloexec.c Normal file
View File

@@ -0,0 +1,88 @@
/* cloexec.c - set or clear the close-on-exec descriptor flag
Copyright (C) 1991, 2004-2006, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
#include "cloexec.h"
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true,
or clear the flag if VALUE is false.
Return 0 on success, or -1 on error with 'errno' set.
Note that on MingW, this function does NOT protect DESC from being
inherited into spawned children. Instead, either use dup_cloexec
followed by closing the original DESC, or use interfaces such as
open or pipe2 that accept flags like O_CLOEXEC to create DESC
non-inheritable in the first place. */
int
set_cloexec_flag (int desc, bool value)
{
#ifdef F_SETFD
int flags = fcntl (desc, F_GETFD, 0);
if (0 <= flags)
{
int newflags = (value ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC);
if (flags == newflags
|| fcntl (desc, F_SETFD, newflags) != -1)
return 0;
}
return -1;
#else /* !F_SETFD */
/* Use dup2 to reject invalid file descriptors; the cloexec flag
will be unaffected. */
if (desc < 0)
{
errno = EBADF;
return -1;
}
if (dup2 (desc, desc) < 0)
/* errno is EBADF here. */
return -1;
/* There is nothing we can do on this kind of platform. Punt. */
return 0;
#endif /* !F_SETFD */
}
/* Duplicates a file handle FD, while marking the copy to be closed
prior to exec or spawn. Returns -1 and sets errno if FD could not
be duplicated. */
int
dup_cloexec (int fd)
{
return fcntl (fd, F_DUPFD_CLOEXEC, 0);
}

43
gnulib/lib/cloexec.h Normal file
View File

@@ -0,0 +1,43 @@
/* cloexec.c - set or clear the close-on-exec descriptor flag
Copyright (C) 2004, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdbool.h>
/* Set the 'FD_CLOEXEC' flag of DESC if VALUE is true,
or clear the flag if VALUE is false.
Return 0 on success, or -1 on error with 'errno' set.
Note that on MingW, this function does NOT protect DESC from being
inherited into spawned children. Instead, either use dup_cloexec
followed by closing the original DESC, or use interfaces such as
open or pipe2 that accept flags like O_CLOEXEC to create DESC
non-inheritable in the first place. */
int set_cloexec_flag (int desc, bool value);
/* Duplicates a file handle FD, while marking the copy to be closed
prior to exec or spawn. Returns -1 and sets errno if FD could not
be duplicated. */
int dup_cloexec (int fd);

25
gnulib/lib/full-read.c Normal file
View File

@@ -0,0 +1,25 @@
/* An interface to read that retries after partial reads and interrupts.
Copyright (C) 2002-2003, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define FULL_READ
#include "full-write.c"

30
gnulib/lib/full-read.h Normal file
View File

@@ -0,0 +1,30 @@
/* An interface to read() that reads all it is asked to read.
Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stddef.h>
/* Read COUNT bytes at BUF to descriptor FD, retrying if interrupted
or if partial reads occur. Return the number of bytes successfully
read, setting errno if that is less than COUNT. errno = 0 means EOF. */
extern size_t full_read (int fd, void *buf, size_t count);

86
gnulib/lib/full-write.c Normal file
View File

@@ -0,0 +1,86 @@
/* An interface to read and write that retries (if necessary) until complete.
Copyright (C) 1993-1994, 1997-2006, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
/* Specification. */
#ifdef FULL_READ
# include "full-read.h"
#else
# include "full-write.h"
#endif
#include <errno.h>
#ifdef FULL_READ
# include "safe-read.h"
# define safe_rw safe_read
# define full_rw full_read
# undef const
# define const /* empty */
#else
# include "safe-write.h"
# define safe_rw safe_write
# define full_rw full_write
#endif
#ifdef FULL_READ
/* Set errno to zero upon EOF. */
# define ZERO_BYTE_TRANSFER_ERRNO 0
#else
/* Some buggy drivers return 0 when one tries to write beyond
a device's end. (Example: Linux 1.2.13 on /dev/fd0.)
Set errno to ENOSPC so they get a sensible diagnostic. */
# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC
#endif
/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if
interrupted or if a partial write(read) occurs. Return the number
of bytes transferred.
When writing, set errno if fewer than COUNT bytes are written.
When reading, if fewer than COUNT bytes are read, you must examine
errno to distinguish failure from EOF (errno == 0). */
size_t
full_rw (int fd, const void *buf, size_t count)
{
size_t total = 0;
const char *ptr = (const char *) buf;
while (count > 0)
{
size_t n_rw = safe_rw (fd, ptr, count);
if (n_rw == (size_t) -1)
break;
if (n_rw == 0)
{
errno = ZERO_BYTE_TRANSFER_ERRNO;
break;
}
total += n_rw;
ptr += n_rw;
count -= n_rw;
}
return total;
}

41
gnulib/lib/full-write.h Normal file
View File

@@ -0,0 +1,41 @@
/* An interface to write() that writes all it is asked to write.
Copyright (C) 2002-2003, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted
or if partial writes occur. Return the number of bytes successfully
written, setting errno if that is less than COUNT. */
extern size_t full_write (int fd, const void *buf, size_t count);
#ifdef __cplusplus
}
#endif

30
gnulib/lib/getprogname.h Normal file
View File

@@ -0,0 +1,30 @@
/* libguestfs
* Copyright (C) 2013-2020 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef GUESTFS_GETPROGNAME
#define GUESTFS_GETPROGNAME
#include <errno.h>
static inline char const *
getprogname (void)
{
return program_invocation_short_name;
}
#endif /* GUESTFS_GETPROGNAME */

40
gnulib/lib/hash-pjw.c Normal file
View File

@@ -0,0 +1,40 @@
/* hash-pjw.c -- compute a hash value from a NUL-terminated string.
Copyright (C) 2001, 2003, 2006, 2009-2021 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 <https://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 https://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;
}

23
gnulib/lib/hash-pjw.h Normal file
View File

@@ -0,0 +1,23 @@
/* hash-pjw.h -- declaration for a simple hash function
Copyright (C) 2001, 2003, 2009-2021 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 <https://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);

1113
gnulib/lib/hash.c Executable file

File diff suppressed because it is too large Load Diff

256
gnulib/lib/hash.h Executable file
View File

@@ -0,0 +1,256 @@
/* hash - hashing table processing.
Copyright (C) 1998-1999, 2001, 2003, 2009-2021 Free Software Foundation,
Inc.
Written by Jim Meyering <meyering@ascend.com>, 1998.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* A generic hash table package. */
/* Make sure USE_OBSTACK is defined to 1 if you want the allocator to use
obstacks instead of malloc, and recompile 'hash.c' with same setting. */
#ifndef HASH_H_
# define HASH_H_
# include <stdio.h>
# include <stdbool.h>
# ifdef __cplusplus
extern "C" {
# endif
struct hash_tuning
{
/* This structure is mainly used for 'hash_initialize', see the block
documentation of 'hash_reset_tuning' for more complete comments. */
float shrink_threshold; /* ratio of used buckets to trigger a shrink */
float shrink_factor; /* ratio of new smaller size to original size */
float growth_threshold; /* ratio of used buckets to trigger a growth */
float growth_factor; /* ratio of new bigger size to original size */
bool is_n_buckets; /* if CANDIDATE really means table size */
};
typedef struct hash_tuning Hash_tuning;
struct hash_table;
typedef struct hash_table Hash_table;
/*
* Information and lookup.
*/
/* The following few functions provide information about the overall hash
table organization: the number of entries, number of buckets and maximum
length of buckets. */
/* Return the number of buckets in the hash table. The table size, the total
number of buckets (used plus unused), or the maximum number of slots, are
the same quantity. */
extern size_t hash_get_n_buckets (const Hash_table *table);
/* Return the number of slots in use (non-empty buckets). */
extern size_t hash_get_n_buckets_used (const Hash_table *table);
/* Return the number of active entries. */
extern size_t hash_get_n_entries (const Hash_table *table);
/* Return the length of the longest chain (bucket). */
extern size_t hash_get_max_bucket_length (const Hash_table *table);
/* Do a mild validation of a hash table, by traversing it and checking two
statistics. */
extern bool hash_table_ok (const Hash_table *table);
extern void hash_print_statistics (const Hash_table *table, FILE *stream);
/* If ENTRY matches an entry already in the hash table, return the
entry from the table. Otherwise, return NULL. */
extern void *hash_lookup (const Hash_table *table, const void *entry);
/*
* Walking.
*/
/* The functions in this page traverse the hash table and process the
contained entries. For the traversal to work properly, the hash table
should not be resized nor modified while any particular entry is being
processed. In particular, entries should not be added, and an entry
may be removed only if there is no shrink threshold and the entry being
removed has already been passed to hash_get_next. */
/* Return the first data in the table, or NULL if the table is empty. */
extern void *hash_get_first (const Hash_table *table);
/* Return the user data for the entry following ENTRY, where ENTRY has been
returned by a previous call to either 'hash_get_first' or 'hash_get_next'.
Return NULL if there are no more entries. */
extern void *hash_get_next (const Hash_table *table, const void *entry);
/* Fill BUFFER with pointers to active user entries in the hash table, then
return the number of pointers copied. Do not copy more than BUFFER_SIZE
pointers. */
extern size_t hash_get_entries (const Hash_table *table, void **buffer,
size_t buffer_size);
typedef bool (*Hash_processor) (void *entry, void *processor_data);
/* Call a PROCESSOR function for each entry of a hash table, and return the
number of entries for which the processor function returned success. A
pointer to some PROCESSOR_DATA which will be made available to each call to
the processor function. The PROCESSOR accepts two arguments: the first is
the user entry being walked into, the second is the value of PROCESSOR_DATA
as received. The walking continue for as long as the PROCESSOR function
returns nonzero. When it returns zero, the walking is interrupted. */
extern size_t hash_do_for_each (const Hash_table *table,
Hash_processor processor, void *processor_data);
/*
* Allocation and clean-up.
*/
/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
This is a convenience routine for constructing other hashing functions. */
extern size_t hash_string (const char *string, size_t n_buckets);
extern void hash_reset_tuning (Hash_tuning *tuning);
typedef size_t (*Hash_hasher) (const void *entry, size_t table_size);
typedef bool (*Hash_comparator) (const void *entry1, const void *entry2);
typedef void (*Hash_data_freer) (void *entry);
/* Allocate and return a new hash table, or NULL upon failure. The initial
number of buckets is automatically selected so as to _guarantee_ that you
may insert at least CANDIDATE different user entries before any growth of
the hash table size occurs. So, if have a reasonably tight a-priori upper
bound on the number of entries you intend to insert in the hash table, you
may save some table memory and insertion time, by specifying it here. If
the IS_N_BUCKETS field of the TUNING structure is true, the CANDIDATE
argument has its meaning changed to the wanted number of buckets.
TUNING points to a structure of user-supplied values, in case some fine
tuning is wanted over the default behavior of the hasher. If TUNING is
NULL, the default tuning parameters are used instead. If TUNING is
provided but the values requested are out of bounds or might cause
rounding errors, return NULL.
The user-supplied HASHER function, when not NULL, accepts two
arguments ENTRY and TABLE_SIZE. It computes, by hashing ENTRY contents, a
slot number for that entry which should be in the range 0..TABLE_SIZE-1.
This slot number is then returned.
The user-supplied COMPARATOR function, when not NULL, accepts two
arguments pointing to user data, it then returns true for a pair of entries
that compare equal, or false otherwise. This function is internally called
on entries which are already known to hash to the same bucket index,
but which are distinct pointers.
The user-supplied DATA_FREER function, when not NULL, may be later called
with the user data as an argument, just before the entry containing the
data gets freed. This happens from within 'hash_free' or 'hash_clear'.
You should specify this function only if you want these functions to free
all of your 'data' data. This is typically the case when your data is
simply an auxiliary struct that you have malloc'd to aggregate several
values. */
extern Hash_table *hash_initialize (size_t candidate,
const Hash_tuning *tuning,
Hash_hasher hasher,
Hash_comparator comparator,
Hash_data_freer data_freer);
/* Same as hash_initialize, but invokes xalloc_die on memory exhaustion. */
/* This function is defined by module 'xhash'. */
extern Hash_table *hash_xinitialize (size_t candidate,
const Hash_tuning *tuning,
Hash_hasher hasher,
Hash_comparator comparator,
Hash_data_freer data_freer);
/* Make all buckets empty, placing any chained entries on the free list.
Apply the user-specified function data_freer (if any) to the datas of any
affected entries. */
extern void hash_clear (Hash_table *table);
/* Reclaim all storage associated with a hash table. If a data_freer
function has been supplied by the user when the hash table was created,
this function applies it to the data of each entry before freeing that
entry. */
extern void hash_free (Hash_table *table);
/*
* Insertion and deletion.
*/
/* For an already existing hash table, change the number of buckets through
specifying CANDIDATE. The contents of the hash table are preserved. The
new number of buckets is automatically selected so as to _guarantee_ that
the table may receive at least CANDIDATE different user entries, including
those already in the table, before any other growth of the hash table size
occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the
exact number of buckets desired. Return true iff the rehash succeeded. */
extern bool hash_rehash (Hash_table *table, size_t candidate);
/* If ENTRY matches an entry already in the hash table, return the pointer
to the entry from the table. Otherwise, insert ENTRY and return ENTRY.
Return NULL if the storage required for insertion cannot be allocated.
This implementation does not support duplicate entries or insertion of
NULL. */
extern void *hash_insert (Hash_table *table, const void *entry);
/* Same as hash_insert, but invokes xalloc_die on memory exhaustion. */
/* This function is defined by module 'xhash'. */
extern void *hash_xinsert (Hash_table *table, const void *entry);
/* Insert ENTRY into hash TABLE if there is not already a matching entry.
Return -1 upon memory allocation failure.
Return 1 if insertion succeeded.
Return 0 if there is already a matching entry in the table,
and in that case, if MATCHED_ENT is non-NULL, set *MATCHED_ENT
to that entry.
This interface is easier to use than hash_insert when you must
distinguish between the latter two cases. More importantly,
hash_insert is unusable for some types of ENTRY values. When using
hash_insert, the only way to distinguish those cases is to compare
the return value and ENTRY. That works only when you can have two
different ENTRY values that point to data that compares "equal". Thus,
when the ENTRY value is a simple scalar, you must use
hash_insert_if_absent. ENTRY must not be NULL. */
extern int hash_insert_if_absent (Hash_table *table, const void *entry,
const void **matched_ent);
/* If ENTRY is already in the table, remove it and return the just-deleted
data (the user may want to deallocate its storage). If ENTRY is not in the
table, don't modify the table and return NULL. */
extern void *hash_remove (Hash_table *table, const void *entry);
/* Same as hash_remove. This interface is deprecated.
FIXME: Remove in 2022. */
extern void *hash_delete (Hash_table *table, const void *entry);
# ifdef __cplusplus
}
# endif
#endif

58
gnulib/lib/ignore-value.h Executable file
View File

@@ -0,0 +1,58 @@
/* ignore a function return without a compiler warning. -*- coding: utf-8 -*-
Copyright (C) 2008-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Written by Jim Meyering, Eric Blake and Pádraig Brady. */
/* Use "ignore_value" to avoid a warning when using a function declared with
gcc's warn_unused_result attribute, but for which you really do want to
ignore the result. Traditionally, people have used a "(void)" cast to
indicate that a function's return value is deliberately unused. However,
if the function is declared with __attribute__((warn_unused_result)),
gcc issues a warning even with the cast.
Caution: most of the time, you really should heed gcc's warning, and
check the return value. However, in those exceptional cases in which
you're sure you know what you're doing, use this function.
For the record, here's one of the ignorable warnings:
"copy.c:233: warning: ignoring return value of 'fchown',
declared with attribute warn_unused_result". */
#ifndef _GL_IGNORE_VALUE_H
#define _GL_IGNORE_VALUE_H
/* Normally casting an expression to void discards its value, but GCC
versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
which may cause unwanted diagnostics in that case. Use __typeof__
and __extension__ to work around the problem, if the workaround is
known to be needed.
The workaround is not needed with clang. */
#if (3 < __GNUC__ + (4 <= __GNUC_MINOR__)) && !defined __clang__
# define ignore_value(x) \
(__extension__ ({ __typeof__ (x) __x = (x); (void) __x; }))
#else
# define ignore_value(x) ((void) (x))
#endif
#endif

170
gnulib/lib/nonblocking.c Normal file
View File

@@ -0,0 +1,170 @@
/* Non-blocking I/O for pipe or socket descriptors.
Copyright (C) 2011-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
/* Specification. */
#include "nonblocking.h"
#include <errno.h>
#if defined _WIN32 && ! defined __CYGWIN__
/* Native Windows API. */
# include <sys/ioctl.h>
# include <sys/socket.h>
# include <unistd.h>
/* Get declarations of the native Windows API functions. */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# if GNULIB_MSVC_NOTHROW
# include "msvc-nothrow.h"
# else
# include <io.h>
# endif
/* Don't assume that UNICODE is not defined. */
# undef GetNamedPipeHandleState
# define GetNamedPipeHandleState GetNamedPipeHandleStateA
int
get_nonblocking_flag (int desc)
{
HANDLE h = (HANDLE) _get_osfhandle (desc);
if (h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return -1;
}
if (GetFileType (h) == FILE_TYPE_PIPE)
{
/* h is a pipe or socket. */
DWORD state;
if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0))
/* h is a pipe. */
return (state & PIPE_NOWAIT) != 0;
else
/* h is a socket. */
errno = ENOSYS;
return -1;
}
else
/* The native Windows API does not support non-blocking on regular
files. */
return 0;
}
int
set_nonblocking_flag (int desc, bool value)
{
HANDLE h = (HANDLE) _get_osfhandle (desc);
if (h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return -1;
}
if (GetFileType (h) == FILE_TYPE_PIPE)
{
/* h is a pipe or socket. */
DWORD state;
if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0))
{
/* h is a pipe. */
if ((state & PIPE_NOWAIT) != 0)
{
if (value)
return 0;
state &= ~PIPE_NOWAIT;
}
else
{
if (!value)
return 0;
state |= PIPE_NOWAIT;
}
if (SetNamedPipeHandleState (h, &state, NULL, NULL))
return 0;
errno = EINVAL;
return -1;
}
else
{
/* h is a socket. */
int v = value;
return ioctl (desc, FIONBIO, &v);
}
}
else
{
/* The native Windows API does not support non-blocking on regular
files. */
if (!value)
return 0;
errno = ENOTSUP;
return -1;
}
}
#else
/* Unix API. */
# include <fcntl.h>
# if GNULIB_defined_O_NONBLOCK
# error Please port nonblocking to your platform
# endif
/* We don't need the gnulib replacement of fcntl() here. */
# undef fcntl
int
get_nonblocking_flag (int desc)
{
int fcntl_flags;
fcntl_flags = fcntl (desc, F_GETFL, 0);
if (fcntl_flags < 0)
return -1;
return (fcntl_flags & O_NONBLOCK) != 0;
}
int
set_nonblocking_flag (int desc, bool value)
{
int fcntl_flags;
fcntl_flags = fcntl (desc, F_GETFL, 0);
if (fcntl_flags < 0)
return -1;
if (((fcntl_flags & O_NONBLOCK) != 0) == value)
return 0;
if (value)
fcntl_flags |= O_NONBLOCK;
else
fcntl_flags &= ~O_NONBLOCK;
return fcntl (desc, F_SETFL, fcntl_flags);
}
#endif

69
gnulib/lib/nonblocking.h Normal file
View File

@@ -0,0 +1,69 @@
/* Non-blocking I/O for pipe or socket descriptors.
Copyright (C) 2011-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _NONBLOCKING_H
#define _NONBLOCKING_H
#include <stdbool.h>
/* Non-blocking I/O is an I/O mode by which read(), write() calls avoid
blocking the current thread. When non-blocking is enabled:
- A read() call returns -1 with errno set to EAGAIN when no data or EOF
information is immediately available.
- A write() call returns -1 with errno set to EAGAIN when it cannot
transport the requested amount of data (but at most one pipe buffer)
without blocking.
Non-blocking I/O is most useful for character devices, pipes, and sockets.
Whether it also works on regular files and block devices is platform
dependent.
There are three modern alternatives to non-blocking I/O:
- use select() or poll() followed by read() or write() if the descriptor
is ready,
- call read() or write() in separate threads,
- use <aio.h> interfaces. */
#ifdef __cplusplus
extern "C" {
#endif
/* Return 1 if I/O to the descriptor DESC is currently non-blocking, 0
it is blocking, or -1 with errno set if fd is invalid or blocking
status cannot be determined (such as with sockets on mingw). */
extern int get_nonblocking_flag (int desc);
/* Specify the non-blocking flag for the descriptor DESC.
Return 0 upon success, or -1 with errno set upon failure.
The default depends on the presence of the O_NONBLOCK flag for files
or pipes opened with open() or on the presence of the SOCK_NONBLOCK
flag for sockets. */
extern int set_nonblocking_flag (int desc, bool value);
#ifdef __cplusplus
}
#endif
#endif /* _NONBLOCKING_H */

79
gnulib/lib/safe-read.c Normal file
View File

@@ -0,0 +1,79 @@
/* An interface to read and write that retries after interrupts.
Copyright (C) 1993-1994, 1998, 2002-2006, 2009-2021 Free Software
Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
/* Specification. */
#ifdef SAFE_WRITE
# include "safe-write.h"
#else
# include "safe-read.h"
#endif
/* Get ssize_t. */
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#ifdef EINTR
# define IS_EINTR(x) ((x) == EINTR)
#else
# define IS_EINTR(x) 0
#endif
enum { SYS_BUFSIZE_MAX = INT_MAX >> 20 << 20 };
#ifdef SAFE_WRITE
# define safe_rw safe_write
# define rw write
#else
# define safe_rw safe_read
# define rw read
# undef const
# define const /* empty */
#endif
/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if
interrupted. Return the actual number of bytes read(written), zero for EOF,
or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error. */
size_t
safe_rw (int fd, void const *buf, size_t count)
{
for (;;)
{
ssize_t result = rw (fd, buf, count);
if (0 <= result)
return result;
else if (IS_EINTR (errno))
continue;
else if (errno == EINVAL && SYS_BUFSIZE_MAX < count)
count = SYS_BUFSIZE_MAX;
else
return result;
}
}

54
gnulib/lib/safe-read.h Normal file
View File

@@ -0,0 +1,54 @@
/* An interface to read() that retries after interrupts.
Copyright (C) 2002, 2006, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Some system calls may be interrupted and fail with errno = EINTR in the
following situations:
- The process is stopped and restarted (signal SIGSTOP and SIGCONT, user
types Ctrl-Z) on some platforms: Mac OS X.
- The process receives a signal for which a signal handler was installed
with sigaction() with an sa_flags field that does not contain
SA_RESTART.
- The process receives a signal for which a signal handler was installed
with signal() and for which no call to siginterrupt(sig,0) was done,
on some platforms: AIX, HP-UX, IRIX, OSF/1, Solaris.
This module provides a wrapper around read() that handles EINTR. */
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SAFE_READ_ERROR ((size_t) -1)
/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
upon error. */
extern size_t safe_read (int fd, void *buf, size_t count);
#ifdef __cplusplus
}
#endif

25
gnulib/lib/safe-write.c Normal file
View File

@@ -0,0 +1,25 @@
/* An interface to write that retries after interrupts.
Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define SAFE_WRITE
#include "safe-read.c"

44
gnulib/lib/safe-write.h Normal file
View File

@@ -0,0 +1,44 @@
/* An interface to write() that retries after interrupts.
Copyright (C) 2002, 2009-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Some system calls may be interrupted and fail with errno = EINTR in the
following situations:
- The process is stopped and restarted (signal SIGSTOP and SIGCONT, user
types Ctrl-Z) on some platforms: Mac OS X.
- The process receives a signal for which a signal handler was installed
with sigaction() with an sa_flags field that does not contain
SA_RESTART.
- The process receives a signal for which a signal handler was installed
with signal() and for which no call to siginterrupt(sig,0) was done,
on some platforms: AIX, HP-UX, IRIX, OSF/1, Solaris.
This module provides a wrapper around write() that handles EINTR. */
#include <stddef.h>
#define SAFE_WRITE_ERROR ((size_t) -1)
/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted.
Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR
upon error. */
extern size_t safe_write (int fd, const void *buf, size_t count);

67
gnulib/lib/xalloc-oversized.h Executable file
View File

@@ -0,0 +1,67 @@
/* xalloc-oversized.h -- memory allocation size checking
Copyright (C) 1990-2000, 2003-2004, 2006-2021 Free Software Foundation, Inc.
(NB: I modified the original GPL boilerplate here to LGPLv2+. This
is because of the weird way that gnulib uses licenses, where the
real license is covered in the modules/X file. The real license
for this file is LGPLv2+, not GPL. - RWMJ)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef XALLOC_OVERSIZED_H_
#define XALLOC_OVERSIZED_H_
#include <stddef.h>
#include <stdint.h>
/* True if N * S would overflow in a size_t calculation,
or would generate a value larger than PTRDIFF_MAX.
This expands to a constant expression if N and S are both constants.
By gnulib convention, SIZE_MAX represents overflow in size
calculations, so the conservative size_t-based dividend to use here
is SIZE_MAX - 1. */
#define __xalloc_oversized(n, s) \
((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
#if PTRDIFF_MAX < SIZE_MAX
typedef ptrdiff_t __xalloc_count_type;
#else
typedef size_t __xalloc_count_type;
#endif
/* Return 1 if an array of N objects, each of size S, cannot exist
reliably due to size or ptrdiff_t arithmetic overflow. S must be
positive and N must be nonnegative. This is a macro, not a
function, so that it works correctly even when SIZE_MAX < N. */
#if 7 <= __GNUC__ && !defined __clang__
# define xalloc_oversized(n, s) \
__builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
#elif 5 <= __GNUC__ && !defined __ICC && !__STRICT_ANSI__
# define xalloc_oversized(n, s) \
(__builtin_constant_p (n) && __builtin_constant_p (s) \
? __xalloc_oversized (n, s) \
: ({ __xalloc_count_type __xalloc_count; \
__builtin_mul_overflow (n, s, &__xalloc_count); }))
/* Other compilers use integer division; this may be slower but is
more portable. */
#else
# define xalloc_oversized(n, s) __xalloc_oversized (n, s)
#endif
#endif /* !XALLOC_OVERSIZED_H_ */

236
gnulib/lib/xstrtol.c Normal file
View File

@@ -0,0 +1,236 @@
/* A more useful interface to strtol.
Copyright (C) 1995-1996, 1998-2001, 2003-2007, 2009-2021 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 <https://www.gnu.org/licenses/>. */
/* Written by Jim Meyering. */
#ifndef __strtol
# define __strtol strtol
# define __strtol_t long int
# define __xstrtol xstrtol
# define STRTOL_T_MINIMUM LONG_MIN
# define STRTOL_T_MAXIMUM LONG_MAX
#endif
#include <config.h>
#include "xstrtol.h"
/* Some pre-ANSI implementations (e.g. SunOS 4)
need stderr defined if assertion checking is enabled. */
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
static strtol_error
bkm_scale (__strtol_t *x, int scale_factor)
{
if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor)
{
*x = STRTOL_T_MINIMUM;
return LONGINT_OVERFLOW;
}
if (STRTOL_T_MAXIMUM / scale_factor < *x)
{
*x = STRTOL_T_MAXIMUM;
return LONGINT_OVERFLOW;
}
*x *= scale_factor;
return LONGINT_OK;
}
static strtol_error
bkm_scale_by_power (__strtol_t *x, int base, int power)
{
strtol_error err = LONGINT_OK;
while (power--)
err |= bkm_scale (x, base);
return err;
}
/* FIXME: comment. */
strtol_error
__xstrtol (const char *s, char **ptr, int strtol_base,
__strtol_t *val, const char *valid_suffixes)
{
char *t_ptr;
char **p;
__strtol_t tmp;
strtol_error err = LONGINT_OK;
assert (0 <= strtol_base && strtol_base <= 36);
p = (ptr ? ptr : &t_ptr);
errno = 0;
if (! TYPE_SIGNED (__strtol_t))
{
const char *q = s;
unsigned char ch = *q;
while (isspace (ch))
ch = *++q;
if (ch == '-')
return LONGINT_INVALID;
}
tmp = __strtol (s, p, strtol_base);
if (*p == s)
{
/* If there is no number but there is a valid suffix, assume the
number is 1. The string is invalid otherwise. */
if (valid_suffixes && **p && strchr (valid_suffixes, **p))
tmp = 1;
else
return LONGINT_INVALID;
}
else if (errno != 0)
{
if (errno != ERANGE)
return LONGINT_INVALID;
err = LONGINT_OVERFLOW;
}
/* Let valid_suffixes == NULL mean "allow any suffix". */
/* FIXME: update all callers except the ones that allow suffixes
after the number, changing last parameter NULL to "". */
if (!valid_suffixes)
{
*val = tmp;
return err;
}
if (**p != '\0')
{
int base = 1024;
int suffixes = 1;
strtol_error overflow;
if (!strchr (valid_suffixes, **p))
{
*val = tmp;
return err | LONGINT_INVALID_SUFFIX_CHAR;
}
switch (**p)
{
case 'E': case 'G': case 'g': case 'k': case 'K': case 'M': case 'm':
case 'P': case 'T': case 't': case 'Y': case 'Z':
/* The "valid suffix" '0' is a special flag meaning that
an optional second suffix is allowed, which can change
the base. A suffix "B" (e.g. "100MB") stands for a power
of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for
a power of 1024. If no suffix (e.g. "100M"), assume
power-of-1024. */
if (strchr (valid_suffixes, '0'))
switch (p[0][1])
{
case 'i':
if (p[0][2] == 'B')
suffixes += 2;
break;
case 'B':
case 'D': /* 'D' is obsolescent */
base = 1000;
suffixes++;
break;
}
}
switch (**p)
{
case 'b':
overflow = bkm_scale (&tmp, 512);
break;
case 'B':
/* This obsolescent first suffix is distinct from the 'B'
second suffix above. E.g., 'tar -L 1000B' means change
the tape after writing 1000 KiB of data. */
overflow = bkm_scale (&tmp, 1024);
break;
case 'c':
overflow = LONGINT_OK;
break;
case 'E': /* exa or exbi */
overflow = bkm_scale_by_power (&tmp, base, 6);
break;
case 'G': /* giga or gibi */
case 'g': /* 'g' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 3);
break;
case 'k': /* kilo */
case 'K': /* kibi */
overflow = bkm_scale_by_power (&tmp, base, 1);
break;
case 'M': /* mega or mebi */
case 'm': /* 'm' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 2);
break;
case 'P': /* peta or pebi */
overflow = bkm_scale_by_power (&tmp, base, 5);
break;
case 'T': /* tera or tebi */
case 't': /* 't' is undocumented; for compatibility only */
overflow = bkm_scale_by_power (&tmp, base, 4);
break;
case 'w':
overflow = bkm_scale (&tmp, 2);
break;
case 'Y': /* yotta or 2**80 */
overflow = bkm_scale_by_power (&tmp, base, 8);
break;
case 'Z': /* zetta or 2**70 */
overflow = bkm_scale_by_power (&tmp, base, 7);
break;
default:
*val = tmp;
return err | LONGINT_INVALID_SUFFIX_CHAR;
}
err |= overflow;
*p += suffixes;
if (**p)
err |= LONGINT_INVALID_SUFFIX_CHAR;
}
*val = tmp;
return err;
}

50
gnulib/lib/xstrtol.h Normal file
View File

@@ -0,0 +1,50 @@
/* A more useful interface to strtol.
Copyright (C) 1995-1996, 1998-1999, 2001-2004, 2006-2021 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 <https://www.gnu.org/licenses/>. */
#ifndef XSTRTOL_H_
# define XSTRTOL_H_ 1
# include <inttypes.h>
# ifndef _STRTOL_ERROR
enum strtol_error
{
LONGINT_OK = 0,
/* These two values can be ORed together, to indicate that both
errors occurred. */
LONGINT_OVERFLOW = 1,
LONGINT_INVALID_SUFFIX_CHAR = 2,
LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR
| LONGINT_OVERFLOW),
LONGINT_INVALID = 4
};
typedef enum strtol_error strtol_error;
# endif
# define _DECLARE_XSTRTOL(name, type) \
strtol_error name (const char *, char **, int, type *, const char *);
_DECLARE_XSTRTOL (xstrtol, long int)
_DECLARE_XSTRTOL (xstrtoul, unsigned long int)
_DECLARE_XSTRTOL (xstrtoll, long long int)
_DECLARE_XSTRTOL (xstrtoull, unsigned long long int)
_DECLARE_XSTRTOL (xstrtoimax, intmax_t)
_DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
#endif /* not XSTRTOL_H_ */

10
gnulib/lib/xstrtoll.c Normal file
View File

@@ -0,0 +1,10 @@
/* Note the license of this file is "GPL". It is used in the daemon
* and in guestfish which have a compatible license.
*/
#define __strtol strtoll
#define __strtol_t long long int
#define __xstrtol xstrtoll
#define STRTOL_T_MINIMUM LLONG_MIN
#define STRTOL_T_MAXIMUM LLONG_MAX
#include "xstrtol.c"

6
gnulib/lib/xstrtoul.c Normal file
View File

@@ -0,0 +1,6 @@
#define __strtol strtoul
#define __strtol_t unsigned long int
#define __xstrtol xstrtoul
#define STRTOL_T_MINIMUM 0
#define STRTOL_T_MAXIMUM ULONG_MAX
#include "xstrtol.c"

6
gnulib/lib/xstrtoull.c Normal file
View File

@@ -0,0 +1,6 @@
#define __strtol strtoull
#define __strtol_t unsigned long long int
#define __xstrtol xstrtoull
#define STRTOL_T_MINIMUM 0
#define STRTOL_T_MAXIMUM ULLONG_MAX
#include "xstrtol.c"

6
gnulib/lib/xstrtoumax.c Normal file
View File

@@ -0,0 +1,6 @@
#define __strtol strtoumax
#define __strtol_t uintmax_t
#define __xstrtol xstrtoumax
#define STRTOL_T_MINIMUM 0
#define STRTOL_T_MAXIMUM UINTMAX_MAX
#include "xstrtol.c"

251
m4/.gitignore vendored
View File

@@ -1,251 +0,0 @@
/00gnulib.m4
/absolute-header.m4
/accept4.m4
/access.m4
/alloca.m4
/arpa_inet_h.m4
/asm-underscore.m4
/base64.m4
/btowc.m4
/builtin-expect.m4
/byteswap.m4
/chdir-long.m4
/clock_time.m4
/closedir.m4
/close.m4
/codeset.m4
/creat.m4
/ctype.m4
/dirent_h.m4
/dirfd.m4
/double-slash-root.m4
/d-type.m4
/dup2.m4
/dup.m4
/eaccess.m4
/eealloc.m4
/environ.m4
/errno_h.m4
/error.m4
/exponentd.m4
/extensions.m4
/extern-inline.m4
/fatal-signal.m4
/fchdir.m4
/fcntl_h.m4
/fcntl.m4
/fcntl-o.m4
/fdopen.m4
/filenamecat.m4
/findprog-in.m4
/flexmember.m4
/float_h.m4
/fnmatch_h.m4
/fnmatch.m4
/fpending.m4
/fpieee.m4
/fstatat.m4
/fstat.m4
/ftruncate.m4
/futimens.m4
/getcwd.m4
/getdelim.m4
/getdtablesize.m4
/getline.m4
/getlogin.m4
/getlogin_r.m4
/getopt.m4
/getpagesize.m4
/getprogname.m4
/getrandom.m4
/gettime.m4
/gettimeofday.m4
/glob_h.m4
/glob.m4
/gnulib-common.m4
/gnulib-comp.m4
/gnulib-tool.m4
/human.m4
/include_next.m4
/inet_pton.m4
/__inline.m4
/intlmacosx.m4
/intl-thread-locale.m4
/intmax_t.m4
/inttostr.m4
/inttypes_h.m4
/inttypes.m4
/ioctl.m4
/isblank.m4
/langinfo_h.m4
/largefile.m4
/lcmessage.m4
/limits-h.m4
/localcharset.m4
/localeconv.m4
/locale-fr.m4
/locale_h.m4
/locale-ja.m4
/localename.m4
/locale-tr.m4
/locale-zh.m4
/lock.m4
/lseek.m4
/lstat.m4
/malloca.m4
/malloc.m4
/manywarnings-c++.m4
/manywarnings.m4
/math_h.m4
/mbrtowc.m4
/mbsinit.m4
/mbsrtowcs.m4
/mbstate_t.m4
/mbtowc.m4
/memchr.m4
/memmem.m4
/mempcpy.m4
/memrchr.m4
/minmax.m4
/mkdir.m4
/mkdtemp.m4
/mkstemps.m4
/mmap-anon.m4
/mode_t.m4
/msvc-inval.m4
/msvc-nothrow.m4
/multiarch.m4
/musl.m4
/nanosleep.m4
/netdb_h.m4
/netinet_in_h.m4
/nocrash.m4
/nonblocking.m4
/off_t.m4
/openat.m4
/open-cloexec.m4
/opendir.m4
/open.m4
/open-slash.m4
/pathmax.m4
/perror.m4
/pid_t.m4
/pipe2.m4
/pipe.m4
/posix_spawn.m4
/pread.m4
/printf.m4
/priv-set.m4
/pthread_h.m4
/pthread_rwlock_rdlock.m4
/pthread_sigmask.m4
/pthread-thread.m4
/putenv.m4
/quotearg.m4
/quote.m4
/raise.m4
/rawmemchr.m4
/readdir.m4
/readlinkat.m4
/readlink.m4
/read.m4
/realloc.m4
/rmdir.m4
/safe-read.m4
/safe-write.m4
/save-cwd.m4
/sched_h.m4
/select.m4
/semaphore.m4
/setenv.m4
/setlocale.m4
/setlocale_null.m4
/sh-filename.m4
/sigaction.m4
/sig_atomic_t.m4
/signalblocking.m4
/signal_h.m4
/size_max.m4
/sleep.m4
/snprintf.m4
/socketlib.m4
/sockets.m4
/socklen.m4
/sockpfaf.m4
/spawn_h.m4
/ssize_t.m4
/stat.m4
/stat-time.m4
/stdalign.m4
/stdarg.m4
/stdbool.m4
/stddef_h.m4
/std-gnu11.m4
/stdint_h.m4
/stdint.m4
/stdio_h.m4
/stdlib_h.m4
/stpcpy.m4
/strchrnul.m4
/strdup.m4
/strerror.m4
/strerror_r.m4
/string_h.m4
/strndup.m4
/strnlen.m4
/strtoll.m4
/strtoull.m4
/strtoumax.m4
/symlinkat.m4
/symlink.m4
/sys_ioctl_h.m4
/sys_random_h.m4
/sys_select_h.m4
/sys_socket_h.m4
/sys_stat_h.m4
/sys_time_h.m4
/sys_types_h.m4
/sys_uio_h.m4
/sys_wait_h.m4
/tempname.m4
/threadlib.m4
/thread.m4
/time_h.m4
/timespec.m4
/tls.m4
/unistd_h.m4
/unistd-safer.m4
/unlinkat.m4
/unlinkdir.m4
/unlink.m4
/usleep.m4
/utimecmp.m4
/utime_h.m4
/utime.m4
/utimensat.m4
/utimens.m4
/utimes.m4
/vasnprintf.m4
/vasprintf.m4
/visibility.m4
/vsnprintf.m4
/waitpid.m4
/wait-process.m4
/warnings.m4
/warn-on-use.m4
/wchar_h.m4
/wchar_t.m4
/wcrtomb.m4
/wctob.m4
/wctomb.m4
/wctype_h.m4
/wint_t.m4
/wmemchr.m4
/wmempcpy.m4
/write.m4
/xalloc.m4
/xsize.m4
/xstrtol.m4
/xvasprintf.m4
/yield.m4
/zzgnulib.m4

View File

@@ -24,115 +24,28 @@ AC_PROG_CC_STDC
AC_PROG_INSTALL
AC_PROG_CPP
AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-werror],
[turn GCC warnings into errors (for developers)])],
[case $enableval in
yes|no) ;;
*) AC_MSG_ERROR([bad value $enableval for werror option]) ;;
esac
gl_gcc_werror=$enableval],
[gl_gcc_werror=no]
)
if test "$gl_gcc_werror" = yes; then
gl_WARN_ADD([-Werror], [WERROR_CFLAGS])
AC_SUBST([WERROR_CFLAGS])
fi
dnl This, $nw, is the list of warnings we disable.
nw=
nw="$nw -Waggregate-return" # anachronistic
nw="$nw -Wundef" # Warns on '#if GNULIB_FOO' etc in gnulib
nw="$nw -Wtraditional" # Warns on #elif which we use often
nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings
nw="$nw -Wpadded" # Our structs are not padded
nw="$nw -Wvla" # Allow variable length arrays.
nw="$nw -Wvla-larger-than=4031"
nw="$nw -Winline" # inline functions in Python binding
nw="$nw -Wshadow" # Not useful, as it applies to global vars
nw="$nw -Wunsafe-loop-optimizations" # just a warning that an optimization
# was not possible, safe to ignore
nw="$nw -Wstack-protector" # Useless warning when stack protector
# cannot being used in a function.
nw="$nw -Wcast-align" # Useless warning on arm >= 7, intel
nw="$nw -Wabi" # Broken in GCC 8.1.
dnl things I might fix soon:
nw="$nw -Wpacked" # Allow attribute((packed)) on structs
nw="$nw -Wlong-long" # Allow long long since it's required
# by Python, Ruby and xstrtoll.
nw="$nw -Wsuggest-attribute=pure" # Don't suggest pure functions.
nw="$nw -Wsuggest-attribute=const" # Don't suggest const functions.
nw="$nw -Wsuggest-attribute=malloc" # Don't suggest malloc functions.
nw="$nw -Wunsuffixed-float-constants" # Don't care about these.
nw="$nw -Wswitch-default" # This warning is actively dangerous.
nw="$nw -Woverlength-strings" # Who cares about stupid ISO C99 limit.
gl_MANYWARN_ALL_GCC([ws])
gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw])
for w in $ws; do
gl_WARN_ADD([$w])
done
dnl Normally we disable warnings in $nw above. However $nw only
dnl filters out exact matching warning strings from a list inside
dnl gnulib (see m4/manywarnings.m4). So we need to explicitly list a
dnl few disabled warnings below.
dnl Unused parameters are not a bug.
gl_WARN_ADD([-Wno-unused-parameter])
dnl Missing field initializers is not a bug in C.
gl_WARN_ADD([-Wno-missing-field-initializers])
dnl Display the name of the warning option with the warning.
gl_WARN_ADD([-fdiagnostics-show-option])
dnl Now some warnings we want to enable and/or customize ...
dnl Warn about large stack frames. This does not include alloca and
dnl variable length arrays. Coverity warns about 10000 byte frames.
gl_WARN_ADD([-Wframe-larger-than=6000])
dnl Warn about large stack frames, including estimates for alloca
dnl and variable length arrays.
gl_WARN_ADD([-Wstack-usage=10000])
dnl Warn about implicit fallthrough in case statements, but suppress
dnl the warning if /*FALLTHROUGH*/ comment is used.
gl_WARN_ADD([-Wimplicit-fallthrough=4])
dnl GCC level 2 gives incorrect warnings, so use level 1.
gl_WARN_ADD([-Wformat-truncation=1])
dnl GCC 9 at level 2 gives apparently bogus errors when %.*s is used.
gl_WARN_ADD([-Wformat-overflow=1])
dnl GCC < 11 gives warnings when disabling GCC 11 warnings.
gl_WARN_ADD([-Wno-pragmas])
AC_SUBST([WARN_CFLAGS])
NO_SNV_CFLAGS=
gl_COMPILER_OPTION_IF([-Wno-shift-negative-value],[
NO_SNV_CFLAGS="-Wno-shift-negative-value"
])
AC_SUBST([NO_SNV_CFLAGS])
NO_UM_CFLAGS=
gl_COMPILER_OPTION_IF([-Wno-unused-macros],[
NO_UM_CFLAGS="-Wno-unused-macros"
])
AC_SUBST([NO_UM_CFLAGS])
AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.])
AC_DEFINE([GNULIB_PORTCHECK], [1], [Enable some gnulib portability checks.])
AC_C_PROTOTYPES
test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant])
AM_PROG_CC_C_O
AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-error],
[turn on lots of GCC warnings (for developers)])],
[case $enableval in
yes|no) ;;
*) AC_MSG_ERROR([bad value $enableval for werror option]) ;;
esac
gcc_warnings=$enableval],
[gcc_warnings=no]
)
WARN_CFLAGS="-Wall"
AC_SUBST([WARN_CFLAGS])
if test "x$gcc_warnings" = "xyes"; then
WERROR_CFLAGS="-Werror"
fi
AC_SUBST([WERROR_CFLAGS])
# Provide a global place to set CFLAGS. (Note that setting AM_CFLAGS
# is no use because it doesn't override target_CFLAGS).
#---
@@ -205,16 +118,6 @@ resources when it runs.])])
dnl restore CFLAGS
CFLAGS="${acx_nbdkit_save_CFLAGS}"
dnl Should we run the gnulib tests?
AC_MSG_CHECKING([if we should run the GNUlib tests])
AC_ARG_ENABLE([gnulib-tests],
[AS_HELP_STRING([--disable-gnulib-tests],
[disable running GNU Portability library tests @<:@default=yes@:>@])],
[ENABLE_GNULIB_TESTS="$enableval"],
[ENABLE_GNULIB_TESTS=yes])
AM_CONDITIONAL([ENABLE_GNULIB_TESTS],[test "x$ENABLE_GNULIB_TESTS" = "xyes"])
AC_MSG_RESULT([$ENABLE_GNULIB_TESTS])
dnl Define this so that include/guestfs.h is included
dnl instead of the possibly installed <guestfs.h>. This is
dnl only needed when compiling libguestfs itself. It is

View File

@@ -30,6 +30,7 @@
#include <termios.h>
#include <poll.h>
#include <locale.h>
#include <limits.h>
#include <assert.h>
#include <libintl.h>
@@ -37,7 +38,6 @@
#include "getprogname.h"
#include "ignore-value.h"
#include "nonblocking.h"
#include "xvasprintf.h"
#include "guestfs.h"
#include "guestfs-utils.h"
@@ -364,9 +364,12 @@ main (int argc, char *argv[])
/* Kernel command line must include guestfs_rescue=1 (see
* appliance/init) as well as other options.
*/
append_full = xasprintf ("guestfs_rescue=1%s%s",
append ? " " : "",
append ? append : "");
if (asprintf (&append_full, "guestfs_rescue=1%s%s",
append ? " " : "",
append ? append : "") == -1) {
perror ("asprintf");
exit (EXIT_FAILURE);
}
if (guestfs_set_append (g, append_full) == -1)
exit (EXIT_FAILURE);
free (append_full);