summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore3
-rw-r--r--src/Makefile.am25
-rw-r--r--src/Makefile.in438
-rw-r--r--src/deque.c2
-rw-r--r--src/format.c2
-rw-r--r--src/internal.h3
-rw-r--r--src/io.c287
-rw-r--r--src/libHX.map24
-rw-r--r--src/map.c2
-rw-r--r--src/mc.c6
-rw-r--r--src/opt.c11
-rw-r--r--src/proc.c186
-rw-r--r--src/socket.c124
-rw-r--r--src/string.c309
-rw-r--r--src/tc-compile.c10
-rw-r--r--src/tc-io.c55
-rw-r--r--src/tc-link.c156
-rw-r--r--src/tc-list.c5
-rw-r--r--src/tc-map.c47
-rw-r--r--src/tc-memmem.c1
-rw-r--r--src/tc-proc.c3
-rw-r--r--src/tc-realpath.c10
-rw-r--r--src/tc-string.c205
-rw-r--r--src/tc-strquote.c6
-rw-r--r--src/tc-switchuser.c73
-rw-r--r--src/tc-time.c38
-rw-r--r--src/time.c62
-rw-r--r--src/tx-intdiff.cpp24
-rw-r--r--src/tx-option.cpp2
29 files changed, 1625 insertions, 494 deletions
diff --git a/src/.gitignore b/src/.gitignore
index 5658aee..035dc34 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -4,6 +4,8 @@
/t?-deque
/t?-dir
/t?-format
+/t?-intdiff
+/t?-io
/t?-link
/t?-list
/t?-list2
@@ -20,6 +22,7 @@
/t?-strchr2
/t?-string
/t?-strquote
+/t?-switchuser
/t?-time
# automake tests
diff --git a/src/Makefile.am b/src/Makefile.am
index 73a6bdb..c30b56c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,10 +10,10 @@ lib_LTLIBRARIES += libHX_rtcheck.la
endif
libHX_la_SOURCES = deque.c dl.c format.c io.c map.c \
- mc.c misc.c opt.c \
- rand.c string.c time.c
-libHX_la_LIBADD = ${libdl_LIBS} ${libpthread_LIBS} ${librt_LIBS}
-libHX_la_LDFLAGS = -no-undefined -version-info 32:0:0
+ mc.c misc.c opt.c proc.c \
+ rand.c socket.c string.c time.c
+libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS}
+libHX_la_LDFLAGS = -no-undefined -version-info 35:0:3
if WITH_GNU_LD
libHX_la_LDFLAGS += -Wl,--version-script=${srcdir}/libHX.map
endif
@@ -21,9 +21,7 @@ EXTRA_libHX_la_DEPENDENCIES = libHX.map
if MINGW32
libHX_la_SOURCES += ux-file.c ux-mmap.c
-endif
-if B_PROC
-libHX_la_SOURCES += proc.c
+libHX_la_LIBADD += -lws2_32
endif
libHX_rtcheck_la_SOURCES = rtcheck.c
@@ -35,17 +33,18 @@ endif
EXTRA_DIST = internal.h map_int.h libHX.map
-check_PROGRAMS = tc-compile tc-cast tc-deque tc-dir tc-format tc-link \
+check_PROGRAMS = tc-compile tc-cast tc-deque tc-dir tc-format tc-io \
tc-list tc-list2 tc-map tc-memmem tc-misc tc-netio \
tc-option tc-proc tc-rand tc-realpath \
- tc-shconfig tc-strchr2 tc-string tc-strquote tc-time
+ tc-shconfig tc-strchr2 tc-string tc-strquote \
+ tc-switchuser tc-time
TESTS = tc-strchr2 tc-strquote
tc_cast_CFLAGS = ${AM_CFLAGS} -std=gnu99
tc_cast_LDADD = libHX.la -lm
tc_compile_LDADD = libHX.la
tc_dir_LDADD = libHX.la
tc_format_LDADD = libHX.la
-tc_link_LDADD = libHX.la
+tc_io_LDADD = libHX.la
tc_list_LDADD = libHX.la
tc_list2_LDADD = libHX.la
tc_list2_CFLAGS = ${AM_CFLAGS} -O2 -fstrict-aliasing
@@ -61,22 +60,24 @@ tc_shconfig_LDADD = libHX.la
tc_strchr2_LDADD = libHX.la
tc_string_LDADD = libHX.la
tc_strquote_LDADD = libHX.la
+tc_switchuser_LDADD = libHX.la
tc_time_LDADD = libHX.la
if HAVE_CXX
-check_PROGRAMS += tx-compile tx-cast tx-deque tx-dir tx-list tx-list2 \
+check_PROGRAMS += tx-compile tx-cast tx-deque tx-dir \
+ tx-intdiff tx-list tx-list2 \
tx-misc tx-netio \
tx-option tx-proc tx-rand tx-strchr2 tx-string \
tx-strquote tx-time
TESTS += tx-strchr2 tx-strquote
tx_cast_SOURCES = tx-cast.cpp
-tx_cast_CXXFLAGS = ${AM_CXXFLAGS} -std=c++98
tx_cast_LDADD = libHX.la -lm
tx_compile_SOURCES = tx-compile.cpp
tx_compile_LDADD = libHX.la
tx_deque_SOURCES = tx-deque.cpp
tx_dir_SOURCES = tx-dir.cpp
tx_dir_LDADD = libHX.la
+tx_intdiff_SOURCES = tx-intdiff.cpp
tx_list_SOURCES = tx-list.cpp
tx_list_LDADD = libHX.la
tx_list2_SOURCES = tx-list2.cpp
diff --git a/src/Makefile.in b/src/Makefile.in
index 632d4ab..356dcfe 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -93,18 +93,19 @@ host_triplet = @host@
@HAVE_DLFCN_H_TRUE@am__append_1 = libHX_rtcheck.la
@WITH_GNU_LD_TRUE@am__append_2 = -Wl,--version-script=${srcdir}/libHX.map
@MINGW32_TRUE@am__append_3 = ux-file.c ux-mmap.c
-@B_PROC_TRUE@am__append_4 = proc.c
+@MINGW32_TRUE@am__append_4 = -lws2_32
@WITH_GNU_LD_TRUE@am__append_5 = -Wl,--version-script=${srcdir}/libHX.map
check_PROGRAMS = tc-compile$(EXEEXT) tc-cast$(EXEEXT) \
tc-deque$(EXEEXT) tc-dir$(EXEEXT) tc-format$(EXEEXT) \
- tc-link$(EXEEXT) tc-list$(EXEEXT) tc-list2$(EXEEXT) \
+ tc-io$(EXEEXT) tc-list$(EXEEXT) tc-list2$(EXEEXT) \
tc-map$(EXEEXT) tc-memmem$(EXEEXT) tc-misc$(EXEEXT) \
tc-netio$(EXEEXT) tc-option$(EXEEXT) tc-proc$(EXEEXT) \
tc-rand$(EXEEXT) tc-realpath$(EXEEXT) tc-shconfig$(EXEEXT) \
tc-strchr2$(EXEEXT) tc-string$(EXEEXT) tc-strquote$(EXEEXT) \
- tc-time$(EXEEXT) $(am__EXEEXT_1)
+ tc-switchuser$(EXEEXT) tc-time$(EXEEXT) $(am__EXEEXT_1)
TESTS = tc-strchr2$(EXEEXT) tc-strquote$(EXEEXT) $(am__EXEEXT_2)
-@HAVE_CXX_TRUE@am__append_6 = tx-compile tx-cast tx-deque tx-dir tx-list tx-list2 \
+@HAVE_CXX_TRUE@am__append_6 = tx-compile tx-cast tx-deque tx-dir \
+@HAVE_CXX_TRUE@ tx-intdiff tx-list tx-list2 \
@HAVE_CXX_TRUE@ tx-misc tx-netio \
@HAVE_CXX_TRUE@ tx-option tx-proc tx-rand tx-strchr2 tx-string \
@HAVE_CXX_TRUE@ tx-strquote tx-time
@@ -123,6 +124,14 @@ mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+@HAVE_CXX_TRUE@am__EXEEXT_1 = tx-compile$(EXEEXT) tx-cast$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-deque$(EXEEXT) tx-dir$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-intdiff$(EXEEXT) tx-list$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-list2$(EXEEXT) tx-misc$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-netio$(EXEEXT) tx-option$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-proc$(EXEEXT) tx-rand$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-strchr2$(EXEEXT) tx-string$(EXEEXT) \
+@HAVE_CXX_TRUE@ tx-strquote$(EXEEXT) tx-time$(EXEEXT)
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -154,14 +163,14 @@ am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libHX_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am__libHX_la_SOURCES_DIST = deque.c dl.c format.c io.c map.c mc.c \
- misc.c opt.c rand.c string.c time.c ux-file.c ux-mmap.c proc.c
+ misc.c opt.c proc.c rand.c socket.c string.c time.c ux-file.c \
+ ux-mmap.c
@MINGW32_TRUE@am__objects_1 = ux-file.lo ux-mmap.lo
-@B_PROC_TRUE@am__objects_2 = proc.lo
am_libHX_la_OBJECTS = deque.lo dl.lo format.lo io.lo map.lo mc.lo \
- misc.lo opt.lo rand.lo string.lo time.lo $(am__objects_1) \
- $(am__objects_2)
+ misc.lo opt.lo proc.lo rand.lo socket.lo string.lo time.lo \
+ $(am__objects_1)
libHX_la_OBJECTS = $(am_libHX_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -178,14 +187,6 @@ libHX_rtcheck_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_CFLAGS) $(CFLAGS) $(libHX_rtcheck_la_LDFLAGS) $(LDFLAGS) \
-o $@
@HAVE_DLFCN_H_TRUE@am_libHX_rtcheck_la_rpath = -rpath $(libdir)
-@HAVE_CXX_TRUE@am__EXEEXT_1 = tx-compile$(EXEEXT) tx-cast$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-deque$(EXEEXT) tx-dir$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-list$(EXEEXT) tx-list2$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-misc$(EXEEXT) tx-netio$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-option$(EXEEXT) tx-proc$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-rand$(EXEEXT) tx-strchr2$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-string$(EXEEXT) tx-strquote$(EXEEXT) \
-@HAVE_CXX_TRUE@ tx-time$(EXEEXT)
tc_cast_SOURCES = tc-cast.c
tc_cast_OBJECTS = tc_cast-tc-cast.$(OBJEXT)
tc_cast_DEPENDENCIES = libHX.la
@@ -204,9 +205,9 @@ tc_dir_DEPENDENCIES = libHX.la
tc_format_SOURCES = tc-format.c
tc_format_OBJECTS = tc-format.$(OBJEXT)
tc_format_DEPENDENCIES = libHX.la
-tc_link_SOURCES = tc-link.c
-tc_link_OBJECTS = tc-link.$(OBJEXT)
-tc_link_DEPENDENCIES = libHX.la
+tc_io_SOURCES = tc-io.c
+tc_io_OBJECTS = tc-io.$(OBJEXT)
+tc_io_DEPENDENCIES = libHX.la
tc_list_SOURCES = tc-list.c
tc_list_OBJECTS = tc-list.$(OBJEXT)
tc_list_DEPENDENCIES = libHX.la
@@ -252,16 +253,16 @@ tc_string_DEPENDENCIES = libHX.la
tc_strquote_SOURCES = tc-strquote.c
tc_strquote_OBJECTS = tc-strquote.$(OBJEXT)
tc_strquote_DEPENDENCIES = libHX.la
+tc_switchuser_SOURCES = tc-switchuser.c
+tc_switchuser_OBJECTS = tc-switchuser.$(OBJEXT)
+tc_switchuser_DEPENDENCIES = libHX.la
tc_time_SOURCES = tc-time.c
tc_time_OBJECTS = tc-time.$(OBJEXT)
tc_time_DEPENDENCIES = libHX.la
am__tx_cast_SOURCES_DIST = tx-cast.cpp
-@HAVE_CXX_TRUE@am_tx_cast_OBJECTS = tx_cast-tx-cast.$(OBJEXT)
+@HAVE_CXX_TRUE@am_tx_cast_OBJECTS = tx-cast.$(OBJEXT)
tx_cast_OBJECTS = $(am_tx_cast_OBJECTS)
@HAVE_CXX_TRUE@tx_cast_DEPENDENCIES = libHX.la
-tx_cast_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(tx_cast_CXXFLAGS) \
- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__tx_compile_SOURCES_DIST = tx-compile.cpp
@HAVE_CXX_TRUE@am_tx_compile_OBJECTS = tx-compile.$(OBJEXT)
tx_compile_OBJECTS = $(am_tx_compile_OBJECTS)
@@ -274,6 +275,10 @@ am__tx_dir_SOURCES_DIST = tx-dir.cpp
@HAVE_CXX_TRUE@am_tx_dir_OBJECTS = tx-dir.$(OBJEXT)
tx_dir_OBJECTS = $(am_tx_dir_OBJECTS)
@HAVE_CXX_TRUE@tx_dir_DEPENDENCIES = libHX.la
+am__tx_intdiff_SOURCES_DIST = tx-intdiff.cpp
+@HAVE_CXX_TRUE@am_tx_intdiff_OBJECTS = tx-intdiff.$(OBJEXT)
+tx_intdiff_OBJECTS = $(am_tx_intdiff_OBJECTS)
+tx_intdiff_LDADD = $(LDADD)
am__tx_list_SOURCES_DIST = tx-list.cpp
@HAVE_CXX_TRUE@am_tx_list_OBJECTS = tx-list.$(OBJEXT)
tx_list_OBJECTS = $(am_tx_list_OBJECTS)
@@ -335,7 +340,33 @@ am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/deque.Plo ./$(DEPDIR)/dl.Plo \
+ ./$(DEPDIR)/format.Plo ./$(DEPDIR)/io.Plo ./$(DEPDIR)/map.Plo \
+ ./$(DEPDIR)/mc.Plo ./$(DEPDIR)/misc.Plo ./$(DEPDIR)/opt.Plo \
+ ./$(DEPDIR)/proc.Plo ./$(DEPDIR)/rand.Plo \
+ ./$(DEPDIR)/rtcheck.Plo ./$(DEPDIR)/socket.Plo \
+ ./$(DEPDIR)/string.Plo ./$(DEPDIR)/tc-compile.Po \
+ ./$(DEPDIR)/tc-deque.Po ./$(DEPDIR)/tc-dir.Po \
+ ./$(DEPDIR)/tc-format.Po ./$(DEPDIR)/tc-io.Po \
+ ./$(DEPDIR)/tc-list.Po ./$(DEPDIR)/tc-map.Po \
+ ./$(DEPDIR)/tc-memmem.Po ./$(DEPDIR)/tc-misc.Po \
+ ./$(DEPDIR)/tc-netio.Po ./$(DEPDIR)/tc-option.Po \
+ ./$(DEPDIR)/tc-proc.Po ./$(DEPDIR)/tc-rand.Po \
+ ./$(DEPDIR)/tc-realpath.Po ./$(DEPDIR)/tc-shconfig.Po \
+ ./$(DEPDIR)/tc-strchr2.Po ./$(DEPDIR)/tc-string.Po \
+ ./$(DEPDIR)/tc-strquote.Po ./$(DEPDIR)/tc-switchuser.Po \
+ ./$(DEPDIR)/tc-time.Po ./$(DEPDIR)/tc_cast-tc-cast.Po \
+ ./$(DEPDIR)/tc_list2-tc-list2.Po ./$(DEPDIR)/time.Plo \
+ ./$(DEPDIR)/tx-cast.Po ./$(DEPDIR)/tx-compile.Po \
+ ./$(DEPDIR)/tx-deque.Po ./$(DEPDIR)/tx-dir.Po \
+ ./$(DEPDIR)/tx-intdiff.Po ./$(DEPDIR)/tx-list.Po \
+ ./$(DEPDIR)/tx-misc.Po ./$(DEPDIR)/tx-netio.Po \
+ ./$(DEPDIR)/tx-option.Po ./$(DEPDIR)/tx-proc.Po \
+ ./$(DEPDIR)/tx-rand.Po ./$(DEPDIR)/tx-strchr2.Po \
+ ./$(DEPDIR)/tx-string.Po ./$(DEPDIR)/tx-strquote.Po \
+ ./$(DEPDIR)/tx-time.Po ./$(DEPDIR)/tx_list2-tx-list2.Po \
+ ./$(DEPDIR)/ux-file.Plo ./$(DEPDIR)/ux-mmap.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -374,23 +405,25 @@ am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libHX_la_SOURCES) $(libHX_rtcheck_la_SOURCES) tc-cast.c \
- tc-compile.c tc-deque.c tc-dir.c tc-format.c tc-link.c \
- tc-list.c tc-list2.c tc-map.c tc-memmem.c tc-misc.c tc-netio.c \
+ tc-compile.c tc-deque.c tc-dir.c tc-format.c tc-io.c tc-list.c \
+ tc-list2.c tc-map.c tc-memmem.c tc-misc.c tc-netio.c \
tc-option.c tc-proc.c tc-rand.c tc-realpath.c tc-shconfig.c \
- tc-strchr2.c tc-string.c tc-strquote.c tc-time.c \
- $(tx_cast_SOURCES) $(tx_compile_SOURCES) $(tx_deque_SOURCES) \
- $(tx_dir_SOURCES) $(tx_list_SOURCES) $(tx_list2_SOURCES) \
- $(tx_misc_SOURCES) $(tx_netio_SOURCES) $(tx_option_SOURCES) \
- $(tx_proc_SOURCES) $(tx_rand_SOURCES) $(tx_strchr2_SOURCES) \
- $(tx_string_SOURCES) $(tx_strquote_SOURCES) $(tx_time_SOURCES)
+ tc-strchr2.c tc-string.c tc-strquote.c tc-switchuser.c \
+ tc-time.c $(tx_cast_SOURCES) $(tx_compile_SOURCES) \
+ $(tx_deque_SOURCES) $(tx_dir_SOURCES) $(tx_intdiff_SOURCES) \
+ $(tx_list_SOURCES) $(tx_list2_SOURCES) $(tx_misc_SOURCES) \
+ $(tx_netio_SOURCES) $(tx_option_SOURCES) $(tx_proc_SOURCES) \
+ $(tx_rand_SOURCES) $(tx_strchr2_SOURCES) $(tx_string_SOURCES) \
+ $(tx_strquote_SOURCES) $(tx_time_SOURCES)
DIST_SOURCES = $(am__libHX_la_SOURCES_DIST) \
$(libHX_rtcheck_la_SOURCES) tc-cast.c tc-compile.c tc-deque.c \
- tc-dir.c tc-format.c tc-link.c tc-list.c tc-list2.c tc-map.c \
+ tc-dir.c tc-format.c tc-io.c tc-list.c tc-list2.c tc-map.c \
tc-memmem.c tc-misc.c tc-netio.c tc-option.c tc-proc.c \
tc-rand.c tc-realpath.c tc-shconfig.c tc-strchr2.c tc-string.c \
- tc-strquote.c tc-time.c $(am__tx_cast_SOURCES_DIST) \
- $(am__tx_compile_SOURCES_DIST) $(am__tx_deque_SOURCES_DIST) \
- $(am__tx_dir_SOURCES_DIST) $(am__tx_list_SOURCES_DIST) \
+ tc-strquote.c tc-switchuser.c tc-time.c \
+ $(am__tx_cast_SOURCES_DIST) $(am__tx_compile_SOURCES_DIST) \
+ $(am__tx_deque_SOURCES_DIST) $(am__tx_dir_SOURCES_DIST) \
+ $(am__tx_intdiff_SOURCES_DIST) $(am__tx_list_SOURCES_DIST) \
$(am__tx_list2_SOURCES_DIST) $(am__tx_misc_SOURCES_DIST) \
$(am__tx_netio_SOURCES_DIST) $(am__tx_option_SOURCES_DIST) \
$(am__tx_proc_SOURCES_DIST) $(am__tx_rand_SOURCES_DIST) \
@@ -418,8 +451,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
am__tty_colors_dummy = \
mgn= red= grn= lgn= blu= brg= std=; \
am__color_tests=no
@@ -575,6 +606,7 @@ am__set_TESTS_bases = \
bases='$(TEST_LOGS)'; \
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
RECHECK_LOGS = $(TEST_LOGS)
AM_RECURSIVE_TARGETS = check recheck
@HAVE_CXX_TRUE@am__EXEEXT_2 = tx-strchr2$(EXEEXT) tx-strquote$(EXEEXT)
@@ -613,8 +645,9 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
-CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
@@ -629,8 +662,10 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
+ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FILECMD = @FILECMD@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@@ -646,7 +681,6 @@ LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
-LYX = @LYX@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
@@ -723,6 +757,7 @@ psdir = @psdir@
regular_CFLAGS = @regular_CFLAGS@
regular_CPPFLAGS = @regular_CPPFLAGS@
regular_CXXFLAGS = @regular_CXXFLAGS@
+runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -736,9 +771,10 @@ AM_CFLAGS = ${regular_CFLAGS}
AM_CXXFLAGS = ${regular_CXXFLAGS}
lib_LTLIBRARIES = libHX.la $(am__append_1)
libHX_la_SOURCES = deque.c dl.c format.c io.c map.c mc.c misc.c opt.c \
- rand.c string.c time.c $(am__append_3) $(am__append_4)
-libHX_la_LIBADD = ${libdl_LIBS} ${libpthread_LIBS} ${librt_LIBS}
-libHX_la_LDFLAGS = -no-undefined -version-info 32:0:0 $(am__append_2)
+ proc.c rand.c socket.c string.c time.c $(am__append_3)
+libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS} \
+ $(am__append_4)
+libHX_la_LDFLAGS = -no-undefined -version-info 35:0:3 $(am__append_2)
EXTRA_libHX_la_DEPENDENCIES = libHX.map
libHX_rtcheck_la_SOURCES = rtcheck.c
libHX_rtcheck_la_LIBADD = ${libdl_LIBS}
@@ -750,7 +786,7 @@ tc_cast_LDADD = libHX.la -lm
tc_compile_LDADD = libHX.la
tc_dir_LDADD = libHX.la
tc_format_LDADD = libHX.la
-tc_link_LDADD = libHX.la
+tc_io_LDADD = libHX.la
tc_list_LDADD = libHX.la
tc_list2_LDADD = libHX.la
tc_list2_CFLAGS = ${AM_CFLAGS} -O2 -fstrict-aliasing
@@ -766,15 +802,16 @@ tc_shconfig_LDADD = libHX.la
tc_strchr2_LDADD = libHX.la
tc_string_LDADD = libHX.la
tc_strquote_LDADD = libHX.la
+tc_switchuser_LDADD = libHX.la
tc_time_LDADD = libHX.la
@HAVE_CXX_TRUE@tx_cast_SOURCES = tx-cast.cpp
-@HAVE_CXX_TRUE@tx_cast_CXXFLAGS = ${AM_CXXFLAGS} -std=c++98
@HAVE_CXX_TRUE@tx_cast_LDADD = libHX.la -lm
@HAVE_CXX_TRUE@tx_compile_SOURCES = tx-compile.cpp
@HAVE_CXX_TRUE@tx_compile_LDADD = libHX.la
@HAVE_CXX_TRUE@tx_deque_SOURCES = tx-deque.cpp
@HAVE_CXX_TRUE@tx_dir_SOURCES = tx-dir.cpp
@HAVE_CXX_TRUE@tx_dir_LDADD = libHX.la
+@HAVE_CXX_TRUE@tx_intdiff_SOURCES = tx-intdiff.cpp
@HAVE_CXX_TRUE@tx_list_SOURCES = tx-list.cpp
@HAVE_CXX_TRUE@tx_list_LDADD = libHX.la
@HAVE_CXX_TRUE@tx_list2_SOURCES = tx-list2.cpp
@@ -819,8 +856,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -832,6 +869,15 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
@@ -873,15 +919,6 @@ libHX.la: $(libHX_la_OBJECTS) $(libHX_la_DEPENDENCIES) $(EXTRA_libHX_la_DEPENDEN
libHX_rtcheck.la: $(libHX_rtcheck_la_OBJECTS) $(libHX_rtcheck_la_DEPENDENCIES) $(EXTRA_libHX_rtcheck_la_DEPENDENCIES)
$(AM_V_CCLD)$(libHX_rtcheck_la_LINK) $(am_libHX_rtcheck_la_rpath) $(libHX_rtcheck_la_OBJECTS) $(libHX_rtcheck_la_LIBADD) $(LIBS)
-clean-checkPROGRAMS:
- @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
- echo " rm -f" $$list; \
- rm -f $$list || exit $$?; \
- test -n "$(EXEEXT)" || exit 0; \
- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f" $$list; \
- rm -f $$list
-
tc-cast$(EXEEXT): $(tc_cast_OBJECTS) $(tc_cast_DEPENDENCIES) $(EXTRA_tc_cast_DEPENDENCIES)
@rm -f tc-cast$(EXEEXT)
$(AM_V_CCLD)$(tc_cast_LINK) $(tc_cast_OBJECTS) $(tc_cast_LDADD) $(LIBS)
@@ -902,9 +939,9 @@ tc-format$(EXEEXT): $(tc_format_OBJECTS) $(tc_format_DEPENDENCIES) $(EXTRA_tc_fo
@rm -f tc-format$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tc_format_OBJECTS) $(tc_format_LDADD) $(LIBS)
-tc-link$(EXEEXT): $(tc_link_OBJECTS) $(tc_link_DEPENDENCIES) $(EXTRA_tc_link_DEPENDENCIES)
- @rm -f tc-link$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(tc_link_OBJECTS) $(tc_link_LDADD) $(LIBS)
+tc-io$(EXEEXT): $(tc_io_OBJECTS) $(tc_io_DEPENDENCIES) $(EXTRA_tc_io_DEPENDENCIES)
+ @rm -f tc-io$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tc_io_OBJECTS) $(tc_io_LDADD) $(LIBS)
tc-list$(EXEEXT): $(tc_list_OBJECTS) $(tc_list_DEPENDENCIES) $(EXTRA_tc_list_DEPENDENCIES)
@rm -f tc-list$(EXEEXT)
@@ -962,13 +999,17 @@ tc-strquote$(EXEEXT): $(tc_strquote_OBJECTS) $(tc_strquote_DEPENDENCIES) $(EXTRA
@rm -f tc-strquote$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tc_strquote_OBJECTS) $(tc_strquote_LDADD) $(LIBS)
+tc-switchuser$(EXEEXT): $(tc_switchuser_OBJECTS) $(tc_switchuser_DEPENDENCIES) $(EXTRA_tc_switchuser_DEPENDENCIES)
+ @rm -f tc-switchuser$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tc_switchuser_OBJECTS) $(tc_switchuser_LDADD) $(LIBS)
+
tc-time$(EXEEXT): $(tc_time_OBJECTS) $(tc_time_DEPENDENCIES) $(EXTRA_tc_time_DEPENDENCIES)
@rm -f tc-time$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tc_time_OBJECTS) $(tc_time_LDADD) $(LIBS)
tx-cast$(EXEEXT): $(tx_cast_OBJECTS) $(tx_cast_DEPENDENCIES) $(EXTRA_tx_cast_DEPENDENCIES)
@rm -f tx-cast$(EXEEXT)
- $(AM_V_CXXLD)$(tx_cast_LINK) $(tx_cast_OBJECTS) $(tx_cast_LDADD) $(LIBS)
+ $(AM_V_CXXLD)$(CXXLINK) $(tx_cast_OBJECTS) $(tx_cast_LDADD) $(LIBS)
tx-compile$(EXEEXT): $(tx_compile_OBJECTS) $(tx_compile_DEPENDENCIES) $(EXTRA_tx_compile_DEPENDENCIES)
@rm -f tx-compile$(EXEEXT)
@@ -982,6 +1023,10 @@ tx-dir$(EXEEXT): $(tx_dir_OBJECTS) $(tx_dir_DEPENDENCIES) $(EXTRA_tx_dir_DEPENDE
@rm -f tx-dir$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(tx_dir_OBJECTS) $(tx_dir_LDADD) $(LIBS)
+tx-intdiff$(EXEEXT): $(tx_intdiff_OBJECTS) $(tx_intdiff_DEPENDENCIES) $(EXTRA_tx_intdiff_DEPENDENCIES)
+ @rm -f tx-intdiff$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(tx_intdiff_OBJECTS) $(tx_intdiff_LDADD) $(LIBS)
+
tx-list$(EXEEXT): $(tx_list_OBJECTS) $(tx_list_DEPENDENCIES) $(EXTRA_tx_list_DEPENDENCIES)
@rm -f tx-list$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(tx_list_OBJECTS) $(tx_list_LDADD) $(LIBS)
@@ -1032,57 +1077,66 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deque.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dl.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rand.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtcheck.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-compile.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-deque.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-dir.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-format.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-link.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-list.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-map.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-memmem.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-misc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-netio.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-option.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-proc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rand.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-realpath.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-shconfig.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-strchr2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-string.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-strquote.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-time.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc_cast-tc-cast.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc_list2-tc-list2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-compile.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-deque.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-dir.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-list.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-misc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-netio.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-option.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-proc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-rand.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-strchr2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-string.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-strquote.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-time.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx_cast-tx-cast.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx_list2-tx-list2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ux-file.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ux-mmap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deque.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dl.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rand.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtcheck.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-compile.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-deque.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-dir.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-format.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-io.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-list.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-map.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-memmem.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-misc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-netio.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-option.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-proc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rand.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-realpath.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-shconfig.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-strchr2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-string.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-strquote.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-switchuser.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-time.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc_cast-tc-cast.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc_list2-tc-list2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-cast.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-compile.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-deque.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-dir.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-intdiff.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-list.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-misc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-netio.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-option.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-proc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-rand.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-strchr2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-string.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-strquote.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx-time.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx_list2-tx-list2.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ux-file.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ux-mmap.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -1160,20 +1214,6 @@ tc_list2-tc-list2.obj: tc-list2.c
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
-tx_cast-tx-cast.o: tx-cast.cpp
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tx_cast_CXXFLAGS) $(CXXFLAGS) -MT tx_cast-tx-cast.o -MD -MP -MF $(DEPDIR)/tx_cast-tx-cast.Tpo -c -o tx_cast-tx-cast.o `test -f 'tx-cast.cpp' || echo '$(srcdir)/'`tx-cast.cpp
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tx_cast-tx-cast.Tpo $(DEPDIR)/tx_cast-tx-cast.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tx-cast.cpp' object='tx_cast-tx-cast.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tx_cast_CXXFLAGS) $(CXXFLAGS) -c -o tx_cast-tx-cast.o `test -f 'tx-cast.cpp' || echo '$(srcdir)/'`tx-cast.cpp
-
-tx_cast-tx-cast.obj: tx-cast.cpp
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tx_cast_CXXFLAGS) $(CXXFLAGS) -MT tx_cast-tx-cast.obj -MD -MP -MF $(DEPDIR)/tx_cast-tx-cast.Tpo -c -o tx_cast-tx-cast.obj `if test -f 'tx-cast.cpp'; then $(CYGPATH_W) 'tx-cast.cpp'; else $(CYGPATH_W) '$(srcdir)/tx-cast.cpp'; fi`
-@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tx_cast-tx-cast.Tpo $(DEPDIR)/tx_cast-tx-cast.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tx-cast.cpp' object='tx_cast-tx-cast.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tx_cast_CXXFLAGS) $(CXXFLAGS) -c -o tx_cast-tx-cast.obj `if test -f 'tx-cast.cpp'; then $(CYGPATH_W) 'tx-cast.cpp'; else $(CYGPATH_W) '$(srcdir)/tx-cast.cpp'; fi`
-
tx_list2-tx-list2.o: tx-list2.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tx_list2_CXXFLAGS) $(CXXFLAGS) -MT tx_list2-tx-list2.o -MD -MP -MF $(DEPDIR)/tx_list2-tx-list2.Tpo -c -o tx_list2-tx-list2.o `test -f 'tx-list2.cpp' || echo '$(srcdir)/'`tx-list2.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tx_list2-tx-list2.Tpo $(DEPDIR)/tx_list2-tx-list2.Po
@@ -1353,7 +1393,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
fi; \
echo "$${col}$$br$${std}"; \
- echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
echo "$${col}$$br$${std}"; \
create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \
@@ -1366,7 +1406,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
fi; \
$$success || exit 1
-check-TESTS:
+check-TESTS: $(check_PROGRAMS)
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@@ -1429,8 +1469,10 @@ tx-strquote.log: tx-strquote$(EXEEXT)
@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
-distdir: $(DISTFILES)
+distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@@ -1465,6 +1507,8 @@ check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(LTLIBRARIES)
+install-checkPROGRAMS: install-libLTLIBRARIES
+
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -1508,7 +1552,60 @@ clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
clean-libtool mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR)
+ -rm -f ./$(DEPDIR)/deque.Plo
+ -rm -f ./$(DEPDIR)/dl.Plo
+ -rm -f ./$(DEPDIR)/format.Plo
+ -rm -f ./$(DEPDIR)/io.Plo
+ -rm -f ./$(DEPDIR)/map.Plo
+ -rm -f ./$(DEPDIR)/mc.Plo
+ -rm -f ./$(DEPDIR)/misc.Plo
+ -rm -f ./$(DEPDIR)/opt.Plo
+ -rm -f ./$(DEPDIR)/proc.Plo
+ -rm -f ./$(DEPDIR)/rand.Plo
+ -rm -f ./$(DEPDIR)/rtcheck.Plo
+ -rm -f ./$(DEPDIR)/socket.Plo
+ -rm -f ./$(DEPDIR)/string.Plo
+ -rm -f ./$(DEPDIR)/tc-compile.Po
+ -rm -f ./$(DEPDIR)/tc-deque.Po
+ -rm -f ./$(DEPDIR)/tc-dir.Po
+ -rm -f ./$(DEPDIR)/tc-format.Po
+ -rm -f ./$(DEPDIR)/tc-io.Po
+ -rm -f ./$(DEPDIR)/tc-list.Po
+ -rm -f ./$(DEPDIR)/tc-map.Po
+ -rm -f ./$(DEPDIR)/tc-memmem.Po
+ -rm -f ./$(DEPDIR)/tc-misc.Po
+ -rm -f ./$(DEPDIR)/tc-netio.Po
+ -rm -f ./$(DEPDIR)/tc-option.Po
+ -rm -f ./$(DEPDIR)/tc-proc.Po
+ -rm -f ./$(DEPDIR)/tc-rand.Po
+ -rm -f ./$(DEPDIR)/tc-realpath.Po
+ -rm -f ./$(DEPDIR)/tc-shconfig.Po
+ -rm -f ./$(DEPDIR)/tc-strchr2.Po
+ -rm -f ./$(DEPDIR)/tc-string.Po
+ -rm -f ./$(DEPDIR)/tc-strquote.Po
+ -rm -f ./$(DEPDIR)/tc-switchuser.Po
+ -rm -f ./$(DEPDIR)/tc-time.Po
+ -rm -f ./$(DEPDIR)/tc_cast-tc-cast.Po
+ -rm -f ./$(DEPDIR)/tc_list2-tc-list2.Po
+ -rm -f ./$(DEPDIR)/time.Plo
+ -rm -f ./$(DEPDIR)/tx-cast.Po
+ -rm -f ./$(DEPDIR)/tx-compile.Po
+ -rm -f ./$(DEPDIR)/tx-deque.Po
+ -rm -f ./$(DEPDIR)/tx-dir.Po
+ -rm -f ./$(DEPDIR)/tx-intdiff.Po
+ -rm -f ./$(DEPDIR)/tx-list.Po
+ -rm -f ./$(DEPDIR)/tx-misc.Po
+ -rm -f ./$(DEPDIR)/tx-netio.Po
+ -rm -f ./$(DEPDIR)/tx-option.Po
+ -rm -f ./$(DEPDIR)/tx-proc.Po
+ -rm -f ./$(DEPDIR)/tx-rand.Po
+ -rm -f ./$(DEPDIR)/tx-strchr2.Po
+ -rm -f ./$(DEPDIR)/tx-string.Po
+ -rm -f ./$(DEPDIR)/tx-strquote.Po
+ -rm -f ./$(DEPDIR)/tx-time.Po
+ -rm -f ./$(DEPDIR)/tx_list2-tx-list2.Po
+ -rm -f ./$(DEPDIR)/ux-file.Plo
+ -rm -f ./$(DEPDIR)/ux-mmap.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -1554,7 +1651,60 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
+ -rm -f ./$(DEPDIR)/deque.Plo
+ -rm -f ./$(DEPDIR)/dl.Plo
+ -rm -f ./$(DEPDIR)/format.Plo
+ -rm -f ./$(DEPDIR)/io.Plo
+ -rm -f ./$(DEPDIR)/map.Plo
+ -rm -f ./$(DEPDIR)/mc.Plo
+ -rm -f ./$(DEPDIR)/misc.Plo
+ -rm -f ./$(DEPDIR)/opt.Plo
+ -rm -f ./$(DEPDIR)/proc.Plo
+ -rm -f ./$(DEPDIR)/rand.Plo
+ -rm -f ./$(DEPDIR)/rtcheck.Plo
+ -rm -f ./$(DEPDIR)/socket.Plo
+ -rm -f ./$(DEPDIR)/string.Plo
+ -rm -f ./$(DEPDIR)/tc-compile.Po
+ -rm -f ./$(DEPDIR)/tc-deque.Po
+ -rm -f ./$(DEPDIR)/tc-dir.Po
+ -rm -f ./$(DEPDIR)/tc-format.Po
+ -rm -f ./$(DEPDIR)/tc-io.Po
+ -rm -f ./$(DEPDIR)/tc-list.Po
+ -rm -f ./$(DEPDIR)/tc-map.Po
+ -rm -f ./$(DEPDIR)/tc-memmem.Po
+ -rm -f ./$(DEPDIR)/tc-misc.Po
+ -rm -f ./$(DEPDIR)/tc-netio.Po
+ -rm -f ./$(DEPDIR)/tc-option.Po
+ -rm -f ./$(DEPDIR)/tc-proc.Po
+ -rm -f ./$(DEPDIR)/tc-rand.Po
+ -rm -f ./$(DEPDIR)/tc-realpath.Po
+ -rm -f ./$(DEPDIR)/tc-shconfig.Po
+ -rm -f ./$(DEPDIR)/tc-strchr2.Po
+ -rm -f ./$(DEPDIR)/tc-string.Po
+ -rm -f ./$(DEPDIR)/tc-strquote.Po
+ -rm -f ./$(DEPDIR)/tc-switchuser.Po
+ -rm -f ./$(DEPDIR)/tc-time.Po
+ -rm -f ./$(DEPDIR)/tc_cast-tc-cast.Po
+ -rm -f ./$(DEPDIR)/tc_list2-tc-list2.Po
+ -rm -f ./$(DEPDIR)/time.Plo
+ -rm -f ./$(DEPDIR)/tx-cast.Po
+ -rm -f ./$(DEPDIR)/tx-compile.Po
+ -rm -f ./$(DEPDIR)/tx-deque.Po
+ -rm -f ./$(DEPDIR)/tx-dir.Po
+ -rm -f ./$(DEPDIR)/tx-intdiff.Po
+ -rm -f ./$(DEPDIR)/tx-list.Po
+ -rm -f ./$(DEPDIR)/tx-misc.Po
+ -rm -f ./$(DEPDIR)/tx-netio.Po
+ -rm -f ./$(DEPDIR)/tx-option.Po
+ -rm -f ./$(DEPDIR)/tx-proc.Po
+ -rm -f ./$(DEPDIR)/tx-rand.Po
+ -rm -f ./$(DEPDIR)/tx-strchr2.Po
+ -rm -f ./$(DEPDIR)/tx-string.Po
+ -rm -f ./$(DEPDIR)/tx-strquote.Po
+ -rm -f ./$(DEPDIR)/tx-time.Po
+ -rm -f ./$(DEPDIR)/tx_list2-tx-list2.Po
+ -rm -f ./$(DEPDIR)/ux-file.Plo
+ -rm -f ./$(DEPDIR)/ux-mmap.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -1575,17 +1725,17 @@ uninstall-am: uninstall-libLTLIBRARIES
.MAKE: check-am install-am install-strip
-.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
- clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
- clean-libtool cscopelist-am ctags ctags-am distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am \
- install-libLTLIBRARIES install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
recheck tags tags-am uninstall uninstall-am \
diff --git a/src/deque.c b/src/deque.c
index 3ff7dc9..bc39e0e 100644
--- a/src/deque.c
+++ b/src/deque.c
@@ -122,6 +122,8 @@ EXPORT_SYMBOL void *HXdeque_del(struct HXdeque_node *node)
EXPORT_SYMBOL void HXdeque_free(struct HXdeque *dq)
{
+ if (dq == NULL)
+ return;
struct HXdeque_node *node, *next;
for (node = dq->first; node != NULL; node = next) {
next = node->next;
diff --git a/src/format.c b/src/format.c
index 0c463b0..b691dc7 100644
--- a/src/format.c
+++ b/src/format.c
@@ -101,6 +101,8 @@ static const struct HXmap_ops func_entry_ops = {
EXPORT_SYMBOL void HXformat_free(struct HXformat_map *blk)
{
+ if (blk == NULL)
+ return;
HXmap_free(blk->vars);
HXmap_free(blk->funcs);
free(blk);
diff --git a/src/internal.h b/src/internal.h
index d348520..ec60817 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -42,6 +42,9 @@
#define MAXLNLEN 1024 /* max length for usual line */
#define HXMC_IDENT 0x200571AF
+#if !defined(__cplusplus)
+# define nullptr NULL
+#endif
struct memcont {
size_t alloc, length;
diff --git a/src/io.c b/src/io.c
index a4dd962..b5bdc08 100644
--- a/src/io.c
+++ b/src/io.c
@@ -14,6 +14,7 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -25,12 +26,18 @@
# include <dirent.h>
# include <unistd.h>
#endif
+#if __linux__
+# include <sys/sendfile.h>
+#endif
#include <libHX/ctype_helper.h>
#include <libHX/defs.h>
#include <libHX/io.h>
#include <libHX/misc.h>
#include <libHX/string.h>
#include "internal.h"
+#ifndef O_CLOEXEC
+# define O_CLOEXEC 0
+#endif
struct HXdir {
#if defined _WIN32
@@ -159,46 +166,72 @@ EXPORT_SYMBOL void HXdir_close(struct HXdir *d)
EXPORT_SYMBOL int HX_copy_file(const char *src, const char *dest,
unsigned int opts, ...)
{
- char buf[MAXLNLEN];
+ static const size_t bufsize = 0x10000;
+ void *buf;
unsigned int extra_flags = 0;
- int dd, eax = 0, sd, l;
+ int srcfd, dstfd;
- if ((sd = open(src, O_RDONLY | O_BINARY)) < 0)
+ buf = malloc(bufsize);
+ if (buf == nullptr)
return -errno;
+ srcfd = open(src, O_RDONLY | O_BINARY);
+ if (srcfd < 0) {
+ free(buf);
+ return -errno;
+ }
if (opts & HXF_KEEP)
extra_flags = O_EXCL;
- dd = open(dest, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC |
- extra_flags, S_IRUGO | S_IWUGO);
- if (dd < 0) {
- eax = errno;
- close(sd);
- errno = eax;
- if (extra_flags != 0 && eax == EEXIST)
- return 1;
- return -errno;
+ dstfd = open(dest, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC |
+ extra_flags, S_IRUGO | S_IWUGO);
+ if (dstfd < 0) {
+ int saved_errno = errno;
+ free(buf);
+ close(srcfd);
+ return -(errno = saved_errno);
}
- while ((l = read(sd, buf, MAXLNLEN)) > 0 && write(dd, buf, l) > 0)
- ;
- close(sd);
-
if (opts & (HXF_UID | HXF_GID)) {
struct stat sb;
long uid, gid;
va_list argp;
va_start(argp, opts);
- fstat(dd, &sb);
+ if (fstat(dstfd, &sb) < 0) {
+ int saved_errno = errno;
+ unlink(dest);
+ close(dstfd);
+ close(srcfd);
+ return -(errno = saved_errno);
+ }
uid = sb.st_uid;
gid = sb.st_gid;
if (opts & HXF_UID) uid = va_arg(argp, long);
if (opts & HXF_GID) gid = va_arg(argp, long);
- if (fchown(dd, uid, gid) < 0)
- {};
+ if (fchown(dstfd, uid, gid) < 0) {
+ int saved_errno = errno;
+ unlink(dest);
+ close(dstfd);
+ close(srcfd);
+ return -(errno = saved_errno);
+ }
va_end(argp);
}
- close(dd);
+
+ while (true) {
+ ssize_t rdret = HX_sendfile(dstfd, srcfd, SIZE_MAX);
+ if (rdret == 0)
+ break;
+ if (rdret < 0 && errno != EINTR) {
+ int saved_errno = errno;
+ close(srcfd);
+ close(dstfd);
+ return -(errno = saved_errno);
+ }
+ }
+ close(srcfd);
+ close(dstfd);
+ free(buf);
return 1;
}
@@ -300,27 +333,42 @@ EXPORT_SYMBOL int HX_mkdir(const char *idir, unsigned int mode)
/* Readlink - with a trailing zero (provided by HXmc) */
EXPORT_SYMBOL int HX_readlink(hxmc_t **target, const char *path)
{
- bool dnull = *target == NULL;
- char *tb;
- int ret;
+ bool allocate = *target == NULL;
+ size_t linkbuf_size;
- if (dnull) {
- *target = HXmc_meminit(NULL, PATH_MAX);
+ if (allocate) {
+ linkbuf_size = 32;
+ *target = HXmc_meminit(NULL, 32);
if (*target == NULL)
return -errno;
+ } else {
+ linkbuf_size = HXmc_length(*target);
}
- tb = *target;
- ret = readlink(path, tb, PATH_MAX);
- if (ret < 0) {
- ret = -errno;
- if (!dnull) {
- HXmc_free(*target);
- *target = NULL;
+ while (true) {
+ ssize_t ret = readlink(path, *target, linkbuf_size);
+ if (ret < 0) {
+ int saved_errno = errno;
+ if (allocate) {
+ HXmc_free(*target);
+ *target = nullptr;
+ }
+ return -(errno = saved_errno);
+ }
+ if (static_cast(size_t, ret) < linkbuf_size) {
+ HXmc_setlen(target, ret);
+ return ret;
+ }
+ linkbuf_size *= 2;
+ if (HXmc_setlen(target, linkbuf_size) == NULL) {
+ int saved_errno = errno;
+ if (allocate) {
+ HXmc_free(*target);
+ *target = nullptr;
+ }
+ return -(errno = saved_errno);
}
- return ret;
}
- HXmc_setlen(target, ret);
- return ret;
+ return 0;
}
/**
@@ -533,31 +581,176 @@ EXPORT_SYMBOL int HX_rrmdir(const char *dir)
EXPORT_SYMBOL ssize_t HXio_fullread(int fd, void *vbuf, size_t size)
{
char *buf = vbuf;
- size_t rem = size;
- ssize_t ret;
+ size_t done = 0;
+ if (size > SSIZE_MAX)
+ size = SSIZE_MAX;
- while (rem > 0) {
- ret = read(fd, buf, rem);
+ while (done < size) {
+ ssize_t ret = read(fd, buf, size - done);
if (ret < 0)
return ret;
- rem -= ret;
+ else if (ret == 0)
+ break;
+ done += ret;
buf += ret;
}
- return size;
+ return done;
}
EXPORT_SYMBOL ssize_t HXio_fullwrite(int fd, const void *vbuf, size_t size)
{
const char *buf = vbuf;
- size_t rem = size;
- ssize_t ret;
+ size_t done = 0;
+ if (size > SSIZE_MAX)
+ size = SSIZE_MAX;
- while (rem > 0) {
- ret = write(fd, buf, rem);
+ while (done < size) {
+ ssize_t ret = write(fd, buf, size - done);
if (ret < 0)
return ret;
- rem -= ret;
+ else if (ret == 0)
+ break;
+ done += ret;
buf += ret;
}
- return size;
+ return done;
+}
+
+#if __linux__
+static ssize_t HX_sendfile_linux(int dst, int src, size_t count)
+{
+ long pagesize = sysconf(_SC_PAGE_SIZE);
+ size_t xfersize;
+ ssize_t ret, xferd = 0;
+
+ if (pagesize < 0)
+ pagesize = 4096;
+ xfersize = SSIZE_MAX - pagesize;
+ if (count > xfersize)
+ count = xfersize;
+ while ((ret = sendfile(dst, src, nullptr, count)) > 0)
+ xferd += ret;
+ if (xferd > 0)
+ return xferd;
+ if (ret < 0)
+ return -errno;
+ return 0;
+}
+#endif
+
+static ssize_t HX_sendfile_rw(int dst, int src, size_t count)
+{
+ static const size_t bufsize = 0x10000;
+ size_t xferd = 0;
+ ssize_t ret;
+ void *buf = malloc(bufsize);
+ if (buf == nullptr)
+ return -ENOMEM;
+ if (count > SSIZE_MAX)
+ count = SSIZE_MAX;
+ while (count > 0) {
+ size_t readsize = bufsize;
+ if (count < readsize)
+ readsize = count;
+ ret = HXio_fullread(src, buf, readsize);
+ if (ret < 0) {
+ errno = -ret;
+ break;
+ }
+ ret = HXio_fullwrite(dst, buf, ret);
+ if (ret < 0) {
+ errno = -ret;
+ break;
+ }
+ xferd += ret;
+ count -= ret;
+ }
+ if (xferd > 0)
+ return xferd;
+ if (ret < 0)
+ return -errno;
+ return 0;
+}
+
+EXPORT_SYMBOL ssize_t HX_sendfile(int dst, int src, size_t count)
+{
+#if __linux__
+ ssize_t ret = HX_sendfile_linux(dst, src, count);
+ if (ret != -ENOSYS)
+ return ret;
+#endif
+ return HX_sendfile_rw(dst, src, count);
+}
+
+EXPORT_SYMBOL char *HX_slurp_fd(int fd, size_t *outsize)
+{
+ struct stat sb;
+ if (fstat(fd, &sb) < 0)
+ return NULL;
+ if (sb.st_size == 0) {
+ /* e.g. ttys (S_ISCHR) or special procfs files */
+ size_t bufsize = 4096, offset = 0;
+ char *buf = malloc(bufsize);
+ if (buf == nullptr)
+ return nullptr;
+ ssize_t rdret;
+ while ((rdret = read(fd, buf, bufsize - 1 - offset)) > 0) {
+ offset += rdret;
+ if (bufsize - offset >= 4095)
+ /* any value would work, but >=1 is not all that efficient */
+ continue;
+ if (bufsize > SSIZE_MAX)
+ /* No more doubling */
+ break;
+ bufsize *= 2;
+ void *nbuf = realloc(buf, bufsize + 1);
+ if (nbuf == nullptr) {
+ int se = errno;
+ free(buf);
+ errno = se;
+ return nullptr;
+ }
+ buf = nbuf;
+ }
+ buf[offset] = '\0';
+ if (outsize != nullptr)
+ *outsize = offset;
+ return buf;
+ }
+ size_t fsize = sb.st_size; /* may truncate from loff_t to size_t */
+ if (fsize == SIZE_MAX)
+ --fsize;
+ char *buf = malloc(fsize + 1);
+ if (buf == NULL)
+ return NULL;
+ ssize_t rdret = HXio_fullread(fd, buf, fsize);
+ if (rdret < 0) {
+ int se = errno;
+ free(buf);
+ errno = se;
+ return NULL;
+ }
+ buf[rdret] = '\0';
+ if (outsize != NULL)
+ *outsize = rdret;
+ return buf;
+}
+
+EXPORT_SYMBOL char *HX_slurp_file(const char *file, size_t *outsize)
+{
+ int fd = open(file, O_RDONLY | O_BINARY | O_CLOEXEC);
+ if (fd < 0)
+ return NULL;
+ size_t tmpsize;
+ if (outsize == NULL)
+ outsize = &tmpsize;
+ char *buf = HX_slurp_fd(fd, outsize);
+ if (buf == NULL) {
+ int se = errno;
+ close(fd);
+ errno = se;
+ return NULL;
+ }
+ close(fd);
+ return buf;
}
diff --git a/src/libHX.map b/src/libHX.map
index d5ea9c7..085b74f 100644
--- a/src/libHX.map
+++ b/src/libHX.map
@@ -126,3 +126,27 @@ global:
local:
*;
};
+
+LIBHX_3.27 {
+global:
+ HX_socket_from_env;
+ HX_slurp_fd;
+ HX_slurp_file;
+ HXproc_switch_user;
+ HXproc_top_fd;
+} LIBHX_3.25;
+
+LIBHX_4.2 {
+global:
+ HX_strtod_unit;
+ HX_strtoull_unit;
+ HX_unit_size;
+ HX_unit_size_cu;
+} LIBHX_3.27;
+
+LIBHX_4.3 {
+global:
+ HX_sendfile;
+ HX_unit_seconds;
+ HX_strtoull_sec;
+} LIBHX_4.2;
diff --git a/src/map.c b/src/map.c
index 6d89e36..a90a731 100644
--- a/src/map.c
+++ b/src/map.c
@@ -102,6 +102,8 @@ static void HXrbtree_free(struct HXrbtree *btree)
EXPORT_SYMBOL void HXmap_free(struct HXmap *xmap)
{
+ if (xmap == NULL)
+ return;
void *vmap = xmap;
const struct HXmap_private *map = vmap;
diff --git a/src/mc.c b/src/mc.c
index 33500e7..d16dcbb 100644
--- a/src/mc.c
+++ b/src/mc.c
@@ -79,11 +79,13 @@ EXPORT_SYMBOL hxmc_t *HXmc_memcpy(hxmc_t **vp, const void *ptr, size_t len)
if (ptr == NULL) {
ctx->length = 0;
ctx->data[0] = '\0';
+ // coverity[leaked_storage]
return *vp = ctx->data;
}
memcpy(ctx->data, ptr, ctx->length = len);
ctx->data[len] = '\0';
+ // coverity[leaked_storage]
return *vp = ctx->data;
}
@@ -123,6 +125,7 @@ EXPORT_SYMBOL hxmc_t *HXmc_trunc(hxmc_t **vp, size_t len)
ctx->data[len] = '\0';
ctx->length = len;
}
+ // coverity[leaked_storage]
return *vp = ctx->data;
}
@@ -146,11 +149,13 @@ EXPORT_SYMBOL hxmc_t *HXmc_memcat(hxmc_t **vp, const void *ptr, size_t len)
ctx->alloc = nl;
}
if (ptr == NULL)
+ // coverity[leaked_storage]
return *vp = ctx->data;
memcpy(ctx->data + ctx->length, ptr, len);
ctx->length = nl;
ctx->data[nl] = '\0';
+ // coverity[leaked_storage]
return *vp = ctx->data;
}
@@ -200,6 +205,7 @@ EXPORT_SYMBOL hxmc_t *HXmc_memins(hxmc_t **vp, size_t pos, const void *ptr,
memcpy(ctx->data + pos, ptr, len);
ctx->length += len;
ctx->data[ctx->length] = '\0';
+ // coverity[leaked_storage]
return *vp = ctx->data;
}
diff --git a/src/opt.c b/src/opt.c
index 8efbf52..fe2bff3 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -758,6 +758,7 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
out:
if (ret == HXOPT_ERR_SUCCESS) {
+ if (!(ps.flags & HXOPT_KEEP_ARGV)) {
const char **nvec = reinterpret_cast(const char **,
HXdeque_to_vec(ps.remaining, &argk));
if (nvec == NULL)
@@ -776,6 +777,10 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
*argv = nvec;
if (argc != NULL)
*argc = argk;
+ /* pointers are owned by nvec/argv now */
+ HXdeque_free(ps.remaining);
+ ps.remaining = nullptr;
+ }
} else if (ret < 0) {
if (!(ps.flags & HXOPT_QUIET))
fprintf(stderr, "%s: %s\n", __func__, strerror(errno));
@@ -786,8 +791,8 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
else if (ps.flags & HXOPT_USAGEONERR)
HX_getopt_usage(&ps.cbi, stderr);
}
-
- HXdeque_free(ps.remaining);
+ if (ps.remaining != nullptr)
+ HXdeque_genocide2(ps.remaining, free);
return ret;
out_errno:
@@ -1011,6 +1016,8 @@ EXPORT_SYMBOL int HX_shconfig_pv(const char **path, const char *file,
EXPORT_SYMBOL void HX_shconfig_free(const struct HXoption *table)
{
+ if (table == NULL)
+ return;
for (; table->ln != NULL; ++table) {
char **ptr = table->ptr;
if (table->type == HXTYPE_STRING &&
diff --git a/src/proc.c b/src/proc.c
index a7b47aa..1151fff 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -7,42 +7,118 @@
* General Public License as published by the Free Software Foundation;
* either version 2.1 or (at your option) any later version.
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
#include "internal.h"
-
-#if !defined(HAVE_FORK) || !defined(HAVE_PIPE) || !defined(HAVE_EXECV) || \
- !defined(HAVE_EXECVP)
#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
#include <libHX/proc.h>
+#ifdef _WIN32
+# include <winsock2.h>
+#endif
-struct HXproc;
+#if defined(HAVE_INITGROUPS) && defined(HAVE_SETGID)
+#include <grp.h>
+#include <pwd.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
-EXPORT_SYMBOL int HXproc_run_async(const char *const *argv, struct HXproc *p)
+static int HXproc_switch_gid(const struct passwd *pw, gid_t gr_gid)
{
- return -ENOSYS;
+ bool do_setgid = getgid() != gr_gid || getegid() != gr_gid;
+ if (do_setgid && setgid(gr_gid) != 0) {
+ if (errno == 0)
+ errno = -EINVAL;
+ return HXPROC_SETGID_FAILED;
+ }
+ if (pw == NULL)
+ return do_setgid ? HXPROC_SU_SUCCESS : HXPROC_SU_NOOP;
+
+ /* pw!=NULL: user switch requested, do initgroups now. */
+
+ if (geteuid() == pw->pw_uid) {
+ /*
+ * Target identity (usually unprivileged) already reached.
+ * initgroups is unlikely to succeed.
+ */
+ if (initgroups(pw->pw_name, gr_gid) < 0)
+ /* ignore */;
+ return do_setgid ? HXPROC_SU_SUCCESS : HXPROC_SU_NOOP;
+ }
+ if (initgroups(pw->pw_name, gr_gid) != 0)
+ return HXPROC_INITGROUPS_FAILED;
+ return do_setgid ? HXPROC_SU_SUCCESS : HXPROC_SU_NOOP;
}
-EXPORT_SYMBOL int HXproc_run_sync(const char *const *argv, unsigned int flags)
+static int HXproc_switch_group(const struct passwd *pw, const char *group)
{
- /* Might use system() here... */
- return -ENOSYS;
+ char *end;
+ unsigned long gid = strtoul(group, &end, 10);
+ const struct group *gr = *end == '\0' ? getgrgid(gid) : getgrnam(group);
+ if (gr == NULL) {
+ if (errno == 0)
+ errno = ENOENT;
+ return HXPROC_GROUP_NOT_FOUND;
+ }
+ return HXproc_switch_gid(pw, gr->gr_gid);
}
-EXPORT_SYMBOL int HXproc_wait(struct HXproc *p)
+EXPORT_SYMBOL int HXproc_switch_user(const char *user, const char *group)
+{
+ const struct passwd *pw = NULL;
+ if (user != NULL && *user != '\0') {
+ char *end;
+ unsigned long uid = strtoul(user, &end, 10);
+ pw = *end == '\0' ? getpwuid(uid) : getpwnam(user);
+ if (pw == NULL) {
+ if (errno == 0)
+ errno = ENOENT;
+ return HXPROC_USER_NOT_FOUND;
+ }
+ }
+ int ret = HXPROC_SU_NOOP;
+ if (group != NULL && *group != '\0') {
+ ret = HXproc_switch_group(pw, group);
+ if (ret < 0)
+ return ret;
+ } else if (group == NULL && pw != NULL) {
+ ret = HXproc_switch_gid(pw, pw->pw_gid);
+ if (ret < 0)
+ return ret;
+ }
+ bool do_setuid = pw != NULL && (getuid() != pw->pw_uid || geteuid() != pw->pw_uid);
+ if (do_setuid && setuid(pw->pw_uid) != 0) {
+ if (errno == 0)
+ errno = -EINVAL;
+ return HXPROC_SETUID_FAILED;
+ }
+ return do_setuid ? HXPROC_SU_SUCCESS : ret;
+}
+
+#else
+
+EXPORT_SYMBOL int HXproc_switch_user(const char *user, const char *group)
{
return -ENOSYS;
}
-#else /* HAVE_FORK, HAVE_PIPE, HAVE_EXECVE */
+#endif /* HAVE_lots */
+#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_EXECV) && \
+ defined(HAVE_EXECVP)
#include <sys/wait.h>
#include <fcntl.h>
-#include <errno.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libHX/defs.h>
-#include <libHX/proc.h>
#include "internal.h"
#ifdef _WIN32
@@ -88,18 +164,20 @@ HXproc_build_pipes(const struct HXproc *proc, int (*p)[2])
*/
static void HXproc_close_pipes(int (*p)[2])
{
+#define xc(fd) do { close(fd); (fd) = -1; } while (false)
if (p[0][0] >= 0)
- close(p[0][0]);
+ xc(p[0][0]);
if (p[0][1] >= 0)
- close(p[0][1]);
+ xc(p[0][1]);
if (p[1][0] >= 0)
- close(p[1][0]);
+ xc(p[1][0]);
if (p[1][1] >= 0)
- close(p[1][1]);
+ xc(p[1][1]);
if (p[2][0] >= 0)
- close(p[2][0]);
+ xc(p[2][0]);
if (p[2][1] >= 0)
- close(p[2][1]);
+ xc(p[2][1]);
+#undef xc
}
/**
@@ -113,29 +191,27 @@ EXPORT_SYMBOL int
HXproc_run_async(const char *const *argv, struct HXproc *proc)
{
int pipes[3][2], nullfd = -1, ret, saved_errno;
- unsigned int t;
if (argv == NULL || *argv == NULL)
return -EFAULT;
-
- proc->p_stdin = proc->p_stdout = proc->p_stderr = -1;
-
- t = (proc->p_flags & (HXPROC_STDIN | HXPROC_NULL_STDIN)) ==
- (HXPROC_STDIN | HXPROC_NULL_STDIN);
- t |= (proc->p_flags & (HXPROC_STDOUT | HXPROC_NULL_STDOUT)) ==
- (HXPROC_STDOUT | HXPROC_NULL_STDOUT);
- t |= (proc->p_flags & (HXPROC_STDERR | HXPROC_NULL_STDERR)) ==
- (HXPROC_STDERR | HXPROC_NULL_STDERR);
- if (t > 0)
+ if ((proc->p_flags & (HXPROC_STDIN | HXPROC_NULL_STDIN)) ==
+ (HXPROC_STDIN | HXPROC_NULL_STDIN))
+ return -EINVAL;
+ if ((proc->p_flags & (HXPROC_STDOUT | HXPROC_NULL_STDOUT)) ==
+ (HXPROC_STDOUT | HXPROC_NULL_STDOUT))
+ return -EINVAL;
+ if ((proc->p_flags & (HXPROC_STDERR | HXPROC_NULL_STDERR)) ==
+ (HXPROC_STDERR | HXPROC_NULL_STDERR))
return -EINVAL;
-
if (proc->p_flags & (HXPROC_NULL_STDIN | HXPROC_NULL_STDOUT |
HXPROC_NULL_STDERR)) {
if ((nullfd = open(NULL_DEVICE, O_RDWR)) < 0)
return -errno;
}
+ proc->p_stdin = proc->p_stdout = proc->p_stderr = -1;
if ((ret = HXproc_build_pipes(proc, pipes)) <= 0) {
saved_errno = errno;
+ HXproc_close_pipes(pipes);
if (nullfd >= 0)
close(nullfd);
errno = saved_errno;
@@ -183,17 +259,17 @@ HXproc_run_async(const char *const *argv, struct HXproc *proc)
*/
HXproc_close_pipes(pipes);
if ((proc->p_flags & (HXPROC_STDIN | HXPROC_NULL_STDIN)) &&
- proc->p_stdin != STDIN_FILENO) {
+ proc->p_stdin >= 0 && proc->p_stdin != STDIN_FILENO) {
dup2(proc->p_stdin, STDIN_FILENO);
close(proc->p_stdin);
}
if ((proc->p_flags & (HXPROC_STDOUT | HXPROC_NULL_STDOUT)) &&
- proc->p_stdout != STDOUT_FILENO) {
+ proc->p_stdout >= 0 && proc->p_stdout != STDOUT_FILENO) {
dup2(proc->p_stdout, STDOUT_FILENO);
close(proc->p_stdout);
}
if ((proc->p_flags & (HXPROC_STDERR | HXPROC_NULL_STDERR)) &&
- proc->p_stderr != STDERR_FILENO) {
+ proc->p_stderr >= 0 && proc->p_stderr != STDERR_FILENO) {
dup2(proc->p_stderr, STDERR_FILENO);
close(proc->p_stderr);
}
@@ -223,7 +299,8 @@ HXproc_run_async(const char *const *argv, struct HXproc *proc)
close(pipes[2][1]);
proc->p_stderr = pipes[2][0];
}
-
+ if (nullfd >= 0)
+ close(nullfd);
return 1;
}
@@ -266,4 +343,41 @@ EXPORT_SYMBOL int HXproc_wait(struct HXproc *proc)
return static_cast(unsigned char, proc->p_status);
}
+#else
+
+EXPORT_SYMBOL int HXproc_run_async(const char *const *argv, struct HXproc *p)
+{
+ return -ENOSYS;
+}
+
+EXPORT_SYMBOL int HXproc_run_sync(const char *const *argv, unsigned int flags)
+{
+ /* Might use system() here... */
+ return -ENOSYS;
+}
+
+EXPORT_SYMBOL int HXproc_wait(struct HXproc *p)
+{
+ return -ENOSYS;
+}
+
#endif /* HAVE_lots */
+
+EXPORT_SYMBOL int HXproc_top_fd(void)
+{
+#ifndef _WIN32
+ struct rlimit r;
+ if (getrlimit(RLIMIT_NOFILE, &r) == 0) {
+ if (r.rlim_max > INT_MAX)
+ r.rlim_max = INT_MAX;
+ return r.rlim_max;
+ }
+ long v = sysconf(_SC_OPEN_MAX);
+ if (v >= 0) {
+ if (v > INT_MAX)
+ v = INT_MAX;
+ return v;
+ }
+#endif
+ return FD_SETSIZE;
+}
diff --git a/src/socket.c b/src/socket.c
new file mode 100644
index 0000000..45f4053
--- /dev/null
+++ b/src/socket.c
@@ -0,0 +1,124 @@
+/*
+ * Socket-related functions
+ * Copyright Jan Engelhardt, 2021
+ *
+ * This file is part of libHX. libHX 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.1 or (at your option) any later version.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+# include <ws2tcpip.h>
+#else
+# include <sys/socket.h>
+# include <netdb.h>
+#endif
+#include <libHX/proc.h>
+#include <libHX/socket.h>
+#include "internal.h"
+#ifdef _WIN32
+# define STUPIDWIN(x) reinterpret_cast(char *, (x))
+#else
+# define STUPIDWIN(x) (x)
+#endif
+#if defined(__sunos__) && !defined(SO_PROTOCOL)
+# define SO_PROTOCOL SO_PROTOTYPE
+#endif
+
+static int try_sk_from_env(int fd, const struct addrinfo *ai, const char *intf)
+{
+ int value = 0;
+ socklen_t optlen = sizeof(value);
+ int ret = getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, STUPIDWIN(&value), &optlen);
+ if (ret < 0 && errno != ENOPROTOOPT)
+ /*
+ * E.g. OpenBSD's getsockopt does not recognize this - even
+ * though the flag with the same name exists and is known.
+ */
+ return -1;
+ if (ret == 0 && value == 0)
+ return -1;
+#ifdef _WIN32
+ WSAPROTOCOL_INFO protinfo;
+ optlen = sizeof(protinfo);
+ ret = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL_INFO, STUPIDWIN(&protinfo), &optlen);
+ if (ret < 0 || protinfo.iAddressFamily != ai->ai_family ||
+ protinfo.iSocketType != ai->ai_socktype ||
+ protinfo.iProtocol != ai->ai_protocol)
+ return -1;
+#else
+ optlen = sizeof(value);
+ ret = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &value, &optlen);
+ if (ret < 0 || value != ai->ai_family)
+ return -1;
+ optlen = sizeof(value);
+ ret = getsockopt(fd, SOL_SOCKET, SO_TYPE, &value, &optlen);
+ if (ret < 0 || value != ai->ai_socktype)
+ return -1;
+ optlen = sizeof(value);
+ ret = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &value, &optlen);
+ if (ret < 0 || value != ai->ai_protocol)
+ return -1;
+#endif
+ struct sockaddr_storage addr;
+ memset(&addr, 0, sizeof(addr));
+ optlen = sizeof(addr);
+ ret = getsockname(fd, (struct sockaddr *)&addr, &optlen);
+ if (ret < 0)
+ return -1;
+ if (sizeof(addr) < optlen)
+ optlen = sizeof(addr);
+ if (optlen != ai->ai_addrlen || memcmp(&addr, ai->ai_addr, optlen) != 0)
+ return -1;
+ if (intf == nullptr)
+ return fd;
+#ifdef SO_BINDTODEVICE
+ char ifname[32];
+ optlen = sizeof(ifname);
+ ret = getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, &optlen);
+ if (ret < 0)
+ return -1;
+ else if (optlen < sizeof(ifname))
+ ifname[optlen] = '\0';
+ else
+ ifname[sizeof(ifname)-1] = '\0';
+ if (strcmp(intf, ifname) != 0)
+ return -1;
+#endif
+ return fd;
+}
+
+EXPORT_SYMBOL int HX_socket_from_env(const struct addrinfo *ai, const char *intf)
+{
+ int top_fd;
+ const char *env_limit = getenv("LISTEN_FDS");
+ if (env_limit != nullptr) {
+ long x = strtol(env_limit, nullptr, 0);
+ if (x > INT_MAX - 3)
+ x = INT_MAX - 3;
+ top_fd = 3 + x;
+ } else {
+ env_limit = getenv("HX_LISTEN_TOP_FD");
+ long x;
+ if (env_limit != nullptr) {
+ x = strtol(env_limit, nullptr, 0);
+ if (x > INT_MAX)
+ x = INT_MAX;
+ } else {
+ x = HXproc_top_fd();
+ }
+ top_fd = x;
+ }
+ for (int fd = 3; fd < top_fd; ++fd)
+ if (try_sk_from_env(fd, ai, intf) == fd)
+ return fd;
+ errno = ENOENT;
+ return -1;
+}
diff --git a/src/string.c b/src/string.c
index 354a409..c14f1b5 100644
--- a/src/string.c
+++ b/src/string.c
@@ -8,6 +8,8 @@
* either version 2.1 or (at your option) any later version.
*/
#include <errno.h>
+#include <limits.h>
+#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -40,11 +42,6 @@ struct HX_quote_rule {
static const char HX_hexenc[16] = "0123456789ABCDEF";
-static __inline__ unsigned int min_uint(unsigned int a, unsigned int b)
-{
- return (a < b) ? a : b;
-}
-
EXPORT_SYMBOL char *HX_basename(const char *s)
{
const char *p;
@@ -605,14 +602,16 @@ HX_quote_sqlbackslash(char *dest, const char *src, const char *trm)
* Encode @src into BASE-64 according to RFC 4648 and write result to @dest,
* which must be of appropriate size, plus one for a trailing NUL.
*/
-static char *HX_quote_base64(char *d, const char *s)
+static char *HX_quote_base64(char *d, const char *s, char x1, char x2)
{
- static const char a[] =
+ char a[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz0123456789+/";
+ "abcdefghijklmnopqrstuvwxyz0123456789??";
size_t len = strlen(s);
char *ret = d;
+ a[62] = x1;
+ a[63] = x2;
while (len > 0) {
if (len >= 3) {
len -= 3;
@@ -761,6 +760,8 @@ static size_t HX_quoted_size(const char *s, unsigned int type)
case HXQUOTE_LDAPRDN:
return HX_qsize_bsr(s, HX_quote_rules[type].chars, 2);
case HXQUOTE_BASE64:
+ case HXQUOTE_BASE64URL:
+ case HXQUOTE_BASE64IMAP:
return (strlen(s) + 2) / 3 * 4;
case HXQUOTE_URIENC:
return HX_qsize_bsa(s, HX_quote_rules[type].chars, 2);
@@ -819,7 +820,11 @@ EXPORT_SYMBOL char *HX_strquote(const char *src, unsigned int type,
case HXQUOTE_LDAPRDN:
return HX_quote_ldap(*free_me, src, rule->chars);
case HXQUOTE_BASE64:
- return HX_quote_base64(*free_me, src);
+ return HX_quote_base64(*free_me, src, '+', '/');
+ case HXQUOTE_BASE64URL:
+ return HX_quote_base64(*free_me, src, '-', '_');
+ case HXQUOTE_BASE64IMAP:
+ return HX_quote_base64(*free_me, src, '+', ',');
case HXQUOTE_URIENC:
return HX_quote_urlenc(*free_me, src);
case HXQUOTE_SQLSQUOTE:
@@ -836,3 +841,289 @@ EXPORT_SYMBOL char *HX_strupper(char *orig)
*expr = HX_toupper(*expr);
return orig;
}
+
+EXPORT_SYMBOL char *HX_unit_size(char *buf, size_t bufsize,
+ unsigned long long size, unsigned int divisor, unsigned int cutoff)
+{
+ static const char unit_names[] = "\0kMGTPEZYRQ";
+ unsigned int unit_idx = 0;
+ if (divisor == 0)
+ divisor = 1000;
+ if (cutoff == 0) {
+ cutoff = 10000;
+ if (cutoff < divisor)
+ cutoff = divisor;
+ }
+ while (unit_idx < ARRAY_SIZE(unit_names) - 1 && size >= cutoff) {
+ ++unit_idx;
+ size /= divisor;
+ }
+ snprintf(buf, bufsize, "%llu%.1s", size, &unit_names[unit_idx]);
+ return buf;
+}
+
+static inline unsigned long long p_90(unsigned long long x)
+{
+ /* Perform x*9/10, but without the risk of overflow. */
+ return x - x / 10 - !!(x % 10);
+}
+
+EXPORT_SYMBOL char *HX_unit_size_cu(char *buf, size_t bufsize,
+ unsigned long long orig_size, unsigned int divisor)
+{
+ /* No floating point. Take that, coreutils! */
+ static const char unit_names[] = "\0kMGTPEZYRQ";
+ unsigned int unit_idx = 0, last_rem = 0;
+ unsigned long long size = orig_size, gpow = 1, grand_rem;
+ if (divisor == 0)
+ divisor = 1000;
+
+ while (unit_idx < ARRAY_SIZE(unit_names) - 1 && size >= divisor) {
+ ++unit_idx;
+ last_rem = size % divisor;
+ size /= divisor;
+ gpow *= divisor;
+ }
+ if (unit_idx == 0) {
+ snprintf(buf, bufsize, "%llu%.1s", size, &unit_names[unit_idx]);
+ return buf;
+ }
+ grand_rem = orig_size - size * gpow;
+ if (grand_rem != 0) {
+ if (grand_rem > p_90(gpow)) {
+ ++size;
+ last_rem = 0;
+ } else {
+ last_rem *= 10;
+ last_rem /= divisor;
+ ++last_rem;
+ if (last_rem == 10 || (size >= 10 && last_rem > 0)) {
+ ++size;
+ last_rem = 0;
+ }
+ }
+ if (unit_idx < ARRAY_SIZE(unit_names) - 1 && size == divisor) {
+ /* ++size from above may brought size to @divisor again */
+ ++unit_idx;
+ size /= divisor;
+ }
+ }
+ if (size >= 10 && last_rem == 0)
+ snprintf(buf, bufsize, "%llu%.1s", size, &unit_names[unit_idx]);
+ else
+ snprintf(buf, bufsize, "%llu.%01u%.1s", size, last_rem, &unit_names[unit_idx]);
+ return buf;
+}
+
+static unsigned int suffix_power(char u)
+{
+ switch (HX_toupper(u)) {
+ case 'K': return 1;
+ case 'M': return 2;
+ case 'G': return 3;
+ case 'T': return 4;
+ case 'P': return 5;
+ case 'E': return 6;
+ case 'Z': return 7;
+ case 'Y': return 8;
+ case 'R': return 9;
+ case 'Q': return 10;
+ default: return 0;
+ }
+}
+
+EXPORT_SYMBOL double HX_strtod_unit(const char *s, char **out_end, unsigned int exponent)
+{
+ char *end;
+ double q;
+
+ while (HX_isspace(*s))
+ ++s;
+ q = strtod(s, &end);
+ if (exponent == 0)
+ exponent = 1000;
+ if (end == s) {
+ if (out_end != nullptr)
+ *out_end = end;
+ return q;
+ }
+ while (HX_isspace(*end))
+ ++end;
+ unsigned int pwr = suffix_power(*end);
+ if (pwr == 0) {
+ if (out_end != nullptr)
+ *out_end = const_cast(char *, end);
+ return q;
+ }
+ if (out_end != nullptr)
+ *out_end = const_cast(char *, end + 1);
+ return q * pow(exponent, pwr);
+}
+
+EXPORT_SYMBOL unsigned long long HX_strtoull_unit(const char *s,
+ char **out_end, unsigned int exponent)
+{
+ char *end;
+ unsigned long long ipart;
+ unsigned int pwr = 0;
+
+ while (HX_isspace(*s))
+ ++s;
+ ipart = strtoull(s, &end, 10);
+ if (*end == '.') {
+ double q = HX_strtod_unit(s, out_end, exponent);
+ bool lo_ok = q >= nextafter(-static_cast(double, ULLONG_MAX), 0);
+ bool hi_ok = q <= nextafter(static_cast(double, ULLONG_MAX), 0);
+ if (!hi_ok || !lo_ok)
+ return ULLONG_MAX;
+ return q;
+ }
+ if (exponent == 0)
+ exponent = 1000;
+ while (HX_isspace(*end))
+ ++end;
+ pwr = suffix_power(*end);
+ if (pwr == 0) {
+ if (out_end != nullptr)
+ *out_end = end;
+ return ipart;
+ }
+ if (out_end != nullptr)
+ *out_end = const_cast(char *, end + 1);
+ while (pwr-- > 0) {
+ if (ipart >= ULLONG_MAX / exponent) {
+ errno = ERANGE;
+ return ULLONG_MAX;
+ }
+ ipart *= exponent;
+ }
+ return ipart;
+}
+
+#define SECONDS_PER_YEAR 31557600
+#define SECONDS_PER_MONTH 2629800
+
+static const struct {
+ const char name[8];
+ unsigned int len;
+ uint32_t mult;
+} time_multiplier[] = {
+ {"seconds", 7, 1},
+ {"second", 6, 1},
+ {"sec", 3, 1},
+ {"s", 1, 1},
+ {"minutes", 7, 60},
+ {"minute", 6, 60},
+ {"min", 3, 60},
+ {"hours", 5, 3600},
+ {"hour", 4, 3600},
+ {"h", 1, 3600},
+ {"days", 4, 86400},
+ {"day", 3, 86400},
+ {"d", 1, 86400},
+ {"weeks", 5, 604800},
+ {"week", 4, 604800},
+ {"months", 6, SECONDS_PER_MONTH},
+ {"month", 5, SECONDS_PER_MONTH},
+ {"years", 5, SECONDS_PER_YEAR},
+ {"year", 4, SECONDS_PER_YEAR},
+ {"y", 1, SECONDS_PER_YEAR},
+};
+
+EXPORT_SYMBOL unsigned long long HX_strtoull_sec(const char *s, char **out_end)
+{
+ unsigned long long seconds = 0;
+
+ while (*s != '\0') {
+ while (HX_isspace(*s))
+ ++s;
+ if (*s == '-') {
+ break;
+ }
+ char *end = nullptr;
+ unsigned long long num = strtoull(s, &end, 10);
+ if (end == s)
+ break;
+ s = end;
+ while (HX_isspace(*s))
+ ++s;
+ if (!HX_isalpha(*s)) {
+ seconds += num;
+ continue;
+ }
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(time_multiplier); ++i)
+ if (strncmp(s, time_multiplier[i].name,
+ time_multiplier[i].len) == 0 &&
+ !HX_isalpha(s[time_multiplier[i].len]))
+ break;
+ if (i == ARRAY_SIZE(time_multiplier))
+ break;
+ seconds += num * time_multiplier[i].mult;
+ s += time_multiplier[i].len;
+ }
+ if (out_end != nullptr)
+ *out_end = const_cast(char *, s);
+ return seconds;
+}
+
+EXPORT_SYMBOL char *HX_unit_seconds(char *out, size_t outsize,
+ unsigned long long secs, unsigned int flags)
+{
+ unsigned long years = 0, months = 0, weeks = 0, days, hours, mins;
+ char buf[HXSIZEOF_Z64+4];
+ if (flags & HXUNIT_YEARS) {
+ years = secs / SECONDS_PER_YEAR;
+ secs %= SECONDS_PER_YEAR;
+ }
+ if (flags & HXUNIT_MONTHS) {
+ months = secs / SECONDS_PER_MONTH;
+ secs %= SECONDS_PER_MONTH;
+ }
+ if (flags & HXUNIT_WEEKS) {
+ weeks = secs / 604800;
+ secs %= 604800;
+ }
+ days = secs / 86400;
+ secs %= 86400;
+ hours = secs / 3600;
+ secs %= 3600;
+ mins = secs / 60;
+ secs %= 60;
+ *out = '\0';
+ if (years > 0) {
+ snprintf(buf, ARRAY_SIZE(buf), "%luy", years);
+ HX_strlcat(out, buf, outsize);
+ }
+ if (months == 1) {
+ HX_strlcat(out, "1month", outsize);
+ } else if (months > 0) {
+ snprintf(buf, ARRAY_SIZE(buf), "%lumonths", months);
+ HX_strlcat(out, buf, outsize);
+ }
+ if (weeks == 1) {
+ HX_strlcat(out, "1week", outsize);
+ } else if (weeks > 0) {
+ snprintf(buf, ARRAY_SIZE(buf), "%luweeks", weeks);
+ HX_strlcat(out, buf, outsize);
+ }
+ if (days > 0) {
+ snprintf(buf, ARRAY_SIZE(buf), "%lud", days);
+ HX_strlcat(out, buf, outsize);
+ }
+ if (hours > 0) {
+ snprintf(buf, ARRAY_SIZE(buf), "%luh", hours);
+ HX_strlcat(out, buf, outsize);
+ }
+ if (mins > 0) {
+ snprintf(buf, ARRAY_SIZE(buf), "%lumin", mins);
+ HX_strlcat(out, buf, outsize);
+ }
+ if (secs > 0 ||
+ (years == 0 && months == 0 && weeks == 0 &&
+ days == 0 && hours == 0 && mins == 0)) {
+ snprintf(buf, ARRAY_SIZE(buf), "%llus", secs);
+ HX_strlcat(out, buf, outsize);
+ }
+ return out;
+}
diff --git a/src/tc-compile.c b/src/tc-compile.c
index 657f4f7..d2b0d09 100644
--- a/src/tc-compile.c
+++ b/src/tc-compile.c
@@ -10,11 +10,11 @@
int main(void)
{
- unsigned long long bmllong[HXbitmap_size(unsigned long long, 256)];
- unsigned long bmlong[HXbitmap_size(unsigned long, 256)];
- unsigned int bmint[HXbitmap_size(unsigned int, 256)];
- unsigned short bmshort[HXbitmap_size(unsigned short, 256)];
- unsigned char bmchar[HXbitmap_size(unsigned char, 256)];
+ unsigned long long bmllong[HXbitmap_size(unsigned long long, 256)] = {0};
+ unsigned long bmlong[HXbitmap_size(unsigned long, 256)] = {0};
+ unsigned int bmint[HXbitmap_size(unsigned int, 256)] = {0};
+ unsigned short bmshort[HXbitmap_size(unsigned short, 256)] = {0};
+ unsigned char bmchar[HXbitmap_size(unsigned char, 256)] = {0};
if (HX_init() <= 0)
abort();
diff --git a/src/tc-io.c b/src/tc-io.c
new file mode 100644
index 0000000..1e95e65
--- /dev/null
+++ b/src/tc-io.c
@@ -0,0 +1,55 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libHX/io.h>
+#include "internal.h"
+
+static void sf(void)
+{
+ int src = open("tc-io.c", O_RDONLY);
+ if (src < 0)
+ return;
+ int dst = open("/dev/null", O_WRONLY);
+ if (dst < 0) {
+ close(src);
+ return;
+ }
+ ssize_t ret = HX_sendfile(dst, src, SIZE_MAX);
+ printf("sendfile transferred %zd bytes\n", ret);
+ close(dst);
+ close(src);
+}
+
+int main(void)
+{
+ size_t z;
+ char *s = HX_slurp_file("tc-io.c", &z);
+ if (s == nullptr) {
+ fprintf(stderr, "HX_slurp_file: %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+ printf("%s\n", s);
+ printf("Dumped %zu bytes\n", z);
+ free(s);
+ s = HX_slurp_file("/proc/version", &z);
+ if (s == nullptr) {
+ fprintf(stderr, "HX_slurp_file: %s\n", strerror(errno));
+ return EXIT_FAILURE;
+ }
+ printf(">%s<\n", s);
+ free(s);
+
+ sf();
+ int ret = HX_copy_file("tc-io.c", "tciocopy.txt", 0);
+ if (ret <= 0) {
+ fprintf(stderr, "HX_copy_file: %s\n", strerror(errno));
+ } else {
+ fprintf(stderr, "copy_file ok\n");
+ unlink("tciocopy.txt");
+ }
+ return 0;
+}
diff --git a/src/tc-link.c b/src/tc-link.c
deleted file mode 100644
index f20bfd7..0000000
--- a/src/tc-link.c
+++ /dev/null
@@ -1,156 +0,0 @@
-#include <stdlib.h>
-#include <libHX.h>
-#include "internal.h"
-
-static void *funcs[] = {
- HXdeque_init,
- HXdeque_push,
- HXdeque_pop,
- HXdeque_unshift,
- HXdeque_shift,
- HXdeque_move,
- HXdeque_del,
- HXdeque_free,
- HXdeque_find,
- HXdeque_get,
- HXdeque_genocide2,
- HXdeque_to_vec,
- HX_dlopen,
- HX_dlsym,
- HX_dlclose,
- HX_dlerror,
- HXformat_init,
- HXformat_free,
- HXformat_add,
- HXformat_aprintf,
- HXformat_fprintf,
- HXformat_sprintf,
- HXdir_open,
- HXdir_read,
- HXdir_close,
- HX_copy_file,
- HX_copy_dir,
- HX_mkdir,
- HX_readlink,
- HX_realpath,
- HX_rrmdir,
- HXio_fullread,
- HXio_fullwrite,
- HXmap_free,
- HXhash_jlookup3,
- HXhash_jlookup3s,
- HXhash_djb2,
- HXmap_init5,
- HXmap_init,
- HXmap_find,
- HXmap_get,
- HXmap_add,
- HXmap_del,
- HXmap_keysvalues,
- HXmap_travinit,
- HXmap_traverse,
- HXmap_travfree,
- HXmap_qfe,
- HXmc_strinit,
- HXmc_meminit,
- HXmc_strcpy,
- HXmc_memcpy,
- HXmc_length,
- HXmc_setlen,
- HXmc_trunc,
- HXmc_strcat,
- HXmc_memcat,
- HXmc_strpcat,
- HXmc_mempcat,
- HXmc_strins,
- HXmc_memins,
- HXmc_memdel,
- HXmc_free,
- HXmc_zvecfree,
- HX_ffs,
- HX_fls,
- HX_hexdump,
- HX_zvecfree,
- HX_getopt,
- HX_getopt_help,
- HX_getopt_help_cb,
- HX_getopt_usage,
- HX_getopt_usage_cb,
- HX_shconfig,
- HX_shconfig_map,
- HX_shconfig_pv,
- HX_shconfig_free,
- HXproc_run_async,
- HXproc_run_sync,
- HXproc_wait,
- HX_init,
- HX_exit,
- HX_rand,
- HX_drand,
- HX_irand,
- HX_basename,
- HX_basename_exact,
- HX_chomp,
- HX_dirname,
- HX_getl,
- HX_memmem,
- HX_split,
- HX_split_fixed,
- HX_split_inplace,
- HX_stpltrim,
- HX_strbchr,
- HX_strchr2,
- HX_strclone,
- HX_strdup,
- HX_strlcat,
- HX_strlcpy,
- HX_strlncat,
- HX_strlower,
- HX_strltrim,
- HX_strmid,
- HX_strndup,
- HX_strnlen,
- HX_strrcspn,
- HX_strrev,
- HX_strrtrim,
- HX_strsep,
- HX_strsep2,
- HX_strquote,
- HX_strupper,
- HX_time_compare,
-#ifdef HAVE_STRUCT_TIMESPEC_TV_NSEC
- HX_timespec_add,
- HX_timespec_isneg,
- HX_timespec_mul,
- HX_timespec_mulf,
- HX_timespec_neg,
- HX_timespec_sub,
-#endif
-#ifdef HAVE_STRUCT_TIMEVAL_TV_USEC
- HX_timeval_sub,
-#endif
-#ifdef _WIN32
- chown,
- fchmod,
- fchown,
- lchown,
- lstat,
- mkfifo,
- mknod,
- readlink,
- symlink,
- mmap,
- munmap,
-#endif
-};
-
-int main(void)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(funcs); ++i)
- printf("%p ", funcs[i]);
- printf("\n");
- printf("There are %" HX_SIZET_FMT "u exported functions\n", ARRAY_SIZE(funcs));
- return EXIT_SUCCESS;
-}
diff --git a/src/tc-list.c b/src/tc-list.c
index c30f5aa..751f462 100644
--- a/src/tc-list.c
+++ b/src/tc-list.c
@@ -39,6 +39,8 @@ static void l_init(unsigned int max, bool unshift)
obj = new struct text_object;
#else
obj = malloc(sizeof(*obj));
+ if (obj == NULL)
+ abort();
#endif
HXlist_init(&obj->list);
obj->id[0] = HX_irand('a', 'z'+1);
@@ -111,6 +113,8 @@ static void l_empty(void)
static void l_shift(void)
{
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
/* Check for -Wshadow warnings */
struct object {
int value;
@@ -130,6 +134,7 @@ static void l_shift(void)
HXclist_push(&clh, &q.anchor);
x = p = HXclist_pop(&clh, struct object, anchor);
printf("%d\n", p->value);
+#pragma GCC diagnostic pop
}
int main(int argc, const char **argv)
diff --git a/src/tc-map.c b/src/tc-map.c
index 8a22259..ce55688 100644
--- a/src/tc-map.c
+++ b/src/tc-map.c
@@ -25,6 +25,7 @@
#include <sys/time.h>
#include "internal.h"
#include "map_int.h"
+#pragma GCC diagnostic ignored "-Wunused-const-variable"
union HXpoly {
struct HXmap *map;
@@ -60,12 +61,14 @@ static void tmap_printf(const char *fmt, ...)
va_end(args);
}
-static void tmap_time(struct timeval *tv)
+static void tmap_time(struct timespec *tv)
{
#ifdef HAVE_SYS_RESOURCE_H
struct rusage r;
- if (getrusage(RUSAGE_SELF, &r) == 0)
- *tv = r.ru_utime;
+ if (getrusage(RUSAGE_SELF, &r) == 0) {
+ tv->tv_sec = r.ru_utime.tv_sec;
+ tv->tv_nsec = r.ru_utime.tv_usec * 1000;
+ }
#else
memset(tv, 0, sizeof(*tv));
#endif
@@ -134,7 +137,7 @@ static void tmap_flush(struct HXmap *map, bool verbose)
static void tmap_add_speed(struct HXmap *map)
{
- struct timeval start, stop, delta;
+ struct timespec start, stop, delta;
unsigned int threshold;
tmap_printf("MAP test 1: Timing add operation\n");
@@ -143,20 +146,20 @@ static void tmap_add_speed(struct HXmap *map)
do {
tmap_add_rand(map, 1);
tmap_time(&stop);
- HX_timeval_sub(&delta, &stop, &start);
+ HX_timespec_sub(&delta, &stop, &start);
} while (!(delta.tv_sec >= 1 || map->items >= 1000000));
- tmap_printf("%u elements in " HX_TIMEVAL_FMT
+ tmap_printf("%u elements in " HX_TIMESPEC_FMT
" (plus time measurement overhead)\n",
- map->items, HX_TIMEVAL_EXP(&delta));
+ map->items, HX_TIMESPEC_EXP(&delta));
threshold = map->items;
tmap_flush(map, false);
tmap_time(&start);
tmap_add_rand(map, threshold);
tmap_time(&stop);
- HX_timeval_sub(&delta, &stop, &start);
- tmap_printf("%u elements in " HX_TIMEVAL_FMT " (w/o overhead)\n",
- map->items, HX_TIMEVAL_EXP(&delta));
+ HX_timespec_sub(&delta, &stop, &start);
+ tmap_printf("%u elements in " HX_TIMESPEC_FMT " (w/o overhead)\n",
+ map->items, HX_TIMESPEC_EXP(&delta));
tmap_ipop();
}
@@ -167,7 +170,7 @@ static bool tmap_each_fn(const struct HXmap_node *node, void *arg)
static void tmap_trav_speed(struct HXmap *map)
{
- struct timeval start, stop, delta, delta2;
+ struct timespec start, stop, delta, delta2;
const struct HXmap_node *node;
struct HXmap_trav *iter;
@@ -178,17 +181,17 @@ static void tmap_trav_speed(struct HXmap *map)
while ((node = HXmap_traverse(iter)) != NULL)
;
tmap_time(&stop);
- HX_timeval_sub(&delta, &stop, &start);
+ HX_timespec_sub(&delta, &stop, &start);
HXmap_travfree(iter);
- tmap_printf("Open traversal of %u nodes: " HX_TIMEVAL_FMT "s\n",
- map->items, HX_TIMEVAL_EXP(&delta));
+ tmap_printf("Open traversal of %u nodes: " HX_TIMESPEC_FMT "s\n",
+ map->items, HX_TIMESPEC_EXP(&delta));
tmap_time(&start);
HXmap_qfe(map, tmap_each_fn, NULL);
tmap_time(&stop);
- HX_timeval_sub(&delta, &stop, &start);
- tmap_printf("QFE traversal of %u nodes: " HX_TIMEVAL_FMT "s\n",
- map->items, HX_TIMEVAL_EXP(&delta));
+ HX_timespec_sub(&delta, &stop, &start);
+ tmap_printf("QFE traversal of %u nodes: " HX_TIMESPEC_FMT "s\n",
+ map->items, HX_TIMESPEC_EXP(&delta));
tmap_ipop();
tmap_printf("MAP test 2a: Timing lookup\n");
@@ -198,14 +201,14 @@ static void tmap_trav_speed(struct HXmap *map)
while ((node = HXmap_traverse(iter)) != NULL)
HXmap_find(map, node->key);
tmap_time(&stop);
- HX_timeval_sub(&delta2, &stop, &start);
+ HX_timespec_sub(&delta2, &stop, &start);
HXmap_travfree(iter);
/* delta2 includes traversal time */
start = delta;
stop = delta2;
- HX_timeval_sub(&delta, &stop, &start);
- tmap_printf("Lookup of %u nodes: " HX_TIMEVAL_FMT "s\n",
- map->items, HX_TIMEVAL_EXP(&delta));
+ HX_timespec_sub(&delta, &stop, &start);
+ tmap_printf("Lookup of %u nodes: " HX_TIMESPEC_FMT "s\n",
+ map->items, HX_TIMESPEC_EXP(&delta));
tmap_ipop();
}
@@ -222,7 +225,7 @@ static void tmap_flat(const struct HXmap *map)
abort();
}
for (i = 0; i < map->items; ++i)
- tmap_printf("%u. %s -> %s\n", i, nodes[i].key, nodes[i].data);
+ tmap_printf("%u. %s -> %s\n", i, nodes[i].skey, nodes[i].sdata);
tmap_ipop();
free(nodes);
}
diff --git a/src/tc-memmem.c b/src/tc-memmem.c
index 342500f..3b62ef1 100644
--- a/src/tc-memmem.c
+++ b/src/tc-memmem.c
@@ -35,6 +35,7 @@ static void long_scan(void)
printf("long_scan: filler2=%p p=%p\n", filler2, p);
HX_timespec_sub(&delta, &stop, &start);
printf("long_scan: " HX_TIMESPEC_FMT "\n", HX_TIMESPEC_EXP(&delta));
+ free(filler2);
}
int main(void)
diff --git a/src/tc-proc.c b/src/tc-proc.c
index 7ec982f..904c450 100644
--- a/src/tc-proc.c
+++ b/src/tc-proc.c
@@ -7,10 +7,12 @@
*/
#ifdef __cplusplus
# include <cerrno>
+# include <cstdio>
# include <cstdlib>
# include <cstring>
#else
# include <errno.h>
+# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#endif
@@ -56,6 +58,7 @@ int main(void)
{
if (HX_init() <= 0)
abort();
+ printf("top fd: %d\n", HXproc_top_fd());
/* let it fail - test verbosity */
HXproc_run_sync(t_args1 + 2, HXPROC_VERBOSE);
diff --git a/src/tc-realpath.c b/src/tc-realpath.c
index 5dd9aa2..c2ef15a 100644
--- a/src/tc-realpath.c
+++ b/src/tc-realpath.c
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <libHX/io.h>
#include <libHX/option.h>
+#include <libHX/string.h>
static unsigned int rp_flags;
static unsigned int rp_absolute;
@@ -42,6 +43,14 @@ static bool rp_get_options(int *argc, const char ***argv)
return true;
}
+static void t_1(void)
+{
+ hxmc_t *tmp = HXmc_strinit("");
+ /* two components, so that HX_readlink gets called twice */
+ HX_realpath(&tmp, "/dev/tty", HX_REALPATH_DEFAULT);
+ HXmc_free(tmp);
+}
+
int main(int argc, const char **argv)
{
hxmc_t *res;
@@ -49,6 +58,7 @@ int main(int argc, const char **argv)
if (!rp_get_options(&argc, &argv))
return EXIT_FAILURE;
+ t_1();
res = NULL;
while (--argc > 0) {
diff --git a/src/tc-string.c b/src/tc-string.c
index 6e85f66..db242a3 100644
--- a/src/tc-string.c
+++ b/src/tc-string.c
@@ -90,9 +90,12 @@ static void t_strncat(void)
{
char data[5] = "DATA";
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-truncation"
if (snprintf(data, sizeof(data), "12345678") >=
static_cast(ssize_t, sizeof(data)))
printf("Not enough space\n");
+#pragma GCC diagnostic pop
printf("String: >%s<\n", data);
HX_strlcat(data, "pqrstuv__", 2);
@@ -271,11 +274,13 @@ static void t_strlcpy(void)
HX_timespec_sub(&d2, &stop, &start);
HX_timespec_sub(&d3, &d1, &d2);
- printf("%4zu->%4zu: %1ld.%09ld (str=%ld.%09ld mem=%ld.%09ld)\n",
+ printf("%4zu->%4zu: " HX_TIMESPEC_FMT
+ " (str=" HX_TIMESPEC_FMT
+ " mem=" HX_TIMESPEC_FMT ")\n",
strlen(ibuf), picksizes[opick],
- static_cast(long, d3.tv_sec), d3.tv_nsec,
- static_cast(long, d1.tv_sec), d1.tv_nsec,
- static_cast(long, d2.tv_sec), d2.tv_nsec
+ HX_TIMESPEC_EXP(&d3),
+ HX_TIMESPEC_EXP(&d1),
+ HX_TIMESPEC_EXP(&d2)
);
}
}
@@ -288,6 +293,193 @@ static void t_strlcpy2(void)
assert(a[0] == 49 && a[0] == a[1] && a[1] == a[2]);
}
+static void t_units(void)
+{
+ static const struct {
+ unsigned long long num;
+ const char exp_1024[6], exp_1000[6];
+ } vt[] = {
+ {1023, "1023", "1023"},
+ {1024, "1024", "1024"},
+ {1945, "1945", "1945"},
+ {1946, "1946", "1946"},
+ {1022975, "998k", "1022k"},
+ {1022976, "999k", "1022k"},
+ {1022977, "999k", "1022k"},
+ {1047552, "1023k", "1047k"},
+ {1047553, "1023k", "1047k"},
+ {1992294, "1945k", "1992k"},
+ {1992295, "1945k", "1992k"},
+ {1072693248, "1023M", "1072M"},
+ {1072693249, "1023M", "1072M"},
+ {ULLONG_MAX, "15E", "18E"},
+ };
+ char buf[HXSIZEOF_Z64+3];
+ printf("unit_size:\n");
+
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ HX_unit_size(buf, ARRAY_SIZE(buf), vt[i].num, 1024, 9120);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1024) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1024);
+ abort();
+ }
+ HX_unit_size(buf, ARRAY_SIZE(buf), vt[i].num, 1000, 9120);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1000) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1000);
+ abort();
+ }
+ }
+}
+
+static void t_units_cu(void)
+{
+ static const struct {
+ unsigned long long num;
+ const char exp_1024[6], exp_1000[6];
+ } vt[] = {
+ {1023, "1023", "1.1k"},
+ {1024, "1.0k", "1.1k"},
+ {1945, "1.9k", "2.0k"},
+ {1946, "2.0k", "2.0k"},
+ {1022975, "999k", "1.1M"},
+ {1022976, "999k", "1.1M"},
+ {1022977, "1000k", "1.1M"},
+ {1047552, "1023k", "1.1M"},
+ {1047553, "1.0M", "1.1M"},
+ {1992294, "1.9M", "2.0M"},
+ {1992295, "2.0M", "2.0M"},
+ {1072693248, "1023M", "1.1G"},
+ {1072693249, "1.0G", "1.1G"},
+ {ULLONG_MAX, "16E", "19E"},
+ };
+ char buf[80];
+ printf("unit_size_cu:\n");
+
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ HX_unit_size_cu(buf, ARRAY_SIZE(buf), vt[i].num, 1024);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1024) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1024);
+ abort();
+ }
+ HX_unit_size_cu(buf, ARRAY_SIZE(buf), vt[i].num, 1000);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1000) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1000);
+ abort();
+ }
+ }
+}
+
+static void t_units_strto(void)
+{
+ static const struct {
+ const char input[24];
+ unsigned int exponent;
+ unsigned long long expect_out;
+ const char expect_rem[8];
+ } vt[] = {
+ {"-5k", 1000, ULLONG_MAX, "-5k"},
+ {" -5.2k", 1000, ULLONG_MAX, "-5.2k"},
+ {"1", 9999, 1, ""},
+ {"1024", 9999, 1ULL << 10, ""},
+ {"1048576", 9999, 1ULL << 20, ""},
+ {"1073741824", 9999, 1ULL << 30, ""},
+ {"1099511627776", 9999, 1ULL << 40, ""},
+ {"1125899906842624", 9999, 1ULL << 50, ""},
+ {"1152921504606846976", 9999, 1ULL << 60, ""},
+ {"18446744073709551615", 9, ULLONG_MAX, ""},
+ {"1k", 1000, 1000ULL, ""},
+ {"1M", 1000, 1000000ULL, ""},
+ {"1G", 1000, 1000000000ULL, ""},
+ {"1T", 1000, 1000000000000ULL, ""},
+ {"1P", 1000, 1000000000000000ULL, ""},
+ {"1E", 1000, 1000000000000000000ULL, ""},
+ {"1k", 1024, 1ULL << 10, ""},
+ {"1M", 1024, 1ULL << 20, ""},
+ {"1G", 1024, 1ULL << 30, ""},
+ {"1T", 1024, 1ULL << 40, ""},
+ {"1P", 1024, 1ULL << 50, ""},
+ {"1E", 1024, 1ULL << 60, ""},
+ {"0", 0, 0, ""},
+ {"0k", 0, 0, ""},
+ {"0 Z", 0, 0, ""},
+ {"0.1k", 1000, 100, ""},
+ {"0.1k", 1024, 102, ""},
+ {" 0.1k", 1024, 102, ""},
+ {"0.00000000000000001E", 1024, 11, ""},
+ {"1.525444GiB", 1000, 1525444000, "iB"},
+ {"1.525444GiB", 1024, 1637933022, "iB"},
+ };
+ char *end;
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ unsigned long long q = HX_strtoull_unit(vt[i].input, &end, vt[i].exponent);
+ printf("%s -> %llu __ %s\n", vt[i].input, q, end);
+ if (q != vt[i].expect_out || strcmp(end, vt[i].expect_rem) != 0)
+ printf("BUG\n");
+ }
+}
+
+static void t_time_units(void)
+{
+ static const struct {
+ unsigned long long input;
+ unsigned int flags;
+ const char expect_out[24];
+ } vt[] = {
+ {31536000, 0, "365d"},
+ {31622400, 0, "366d"},
+ {31622400, HXUNIT_YEARS, "1y18h"},
+ {31622400, HXUNIT_MONTHS, "1y"},
+ {31622400, HXUNIT_WEEKS, "1y"},
+ {31622400, HXUNIT_MONTHS | HXUNIT_WEEKS, "1y"},
+ {2678400, HXUNIT_MONTHS, "1month13h30min"},
+ {2592000, HXUNIT_MONTHS, "30d"},
+ {608400, HXUNIT_WEEKS, "1week1h"},
+ {90061, 0, "1d1h1min1s"},
+ {3692, 0, "1h1min32s"},
+ {67, 0, "1min7s"},
+ {1, 0, "1s"},
+ {0, 0, "0s"},
+ };
+ printf("===== HX_unit_seconds\n");
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ char out[60];
+ char *ret = HX_unit_seconds(out, ARRAY_SIZE(out), vt[i].input, vt[i].flags);
+ printf("%llus => \"%s\"\n", vt[i].input, ret);
+ if (strcmp(ret, vt[i].expect_out) != 0)
+ printf("\tBUG, expected \"%s\"\n", vt[i].expect_out);
+ }
+}
+
+static void t_time_strto(void)
+{
+ static const struct {
+ const char *input;
+ unsigned long long expect_out;
+ const char expect_rem[4];
+ } vt[] = {
+ {"1y1month1week1d1h1min1s ", 31557600+2629800+86400*8+3600+60+1, ""},
+ {" -1d", 0, "-1d"},
+ {"1 -", 1, "-"},
+ {"1s", 1, ""},
+ {"1min", 60, ""},
+ {"0", 0, ""},
+ };
+ char *end;
+ printf("===== t_time_strto\n");
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ unsigned long long q = HX_strtoull_sec(vt[i].input, &end);
+ printf("\"%s\" => %llus + \"%s\"\n", vt[i].input, q, end);
+ if (q != vt[i].expect_out)
+ printf("\tBUG: expected %llus\n", vt[i].expect_out);
+ if (strcmp(end, vt[i].expect_rem) != 0)
+ printf("\tBUG: expected remainder \"%s\"\n", vt[i].expect_rem);
+ }
+}
+
int main(int argc, const char **argv)
{
hxmc_t *tx = NULL;
@@ -316,6 +508,11 @@ int main(int argc, const char **argv)
t_strtrim();
t_split();
t_split2();
+ t_units();
+ t_units_cu();
+ t_units_strto();
+ t_time_units();
+ t_time_strto();
t_strlcpy();
t_strlcpy2();
HXmc_free(tx);
diff --git a/src/tc-strquote.c b/src/tc-strquote.c
index f26ff54..fab305e 100644
--- a/src/tc-strquote.c
+++ b/src/tc-strquote.c
@@ -26,6 +26,10 @@ static const char input4[] = "http://user:pass@host.de/~path/file(msvc);stuff.
static const char output4[] = "http%3A%2F%2Fuser%3Apass%40host.de%2F~path%2Ffile%28msvc%29%3Bstuff.php%3Fquery%5Bphpindex%5D%3Dvalue%26another%3Done%3Bstuff";
static const char input5[] = "echo hello `echo world`";
static const char output5[] = "echo hello ``echo world``";
+static const char input6[] = "\xfb\xef\xff";
+static const char output6[] = "++//";
+static const char input7[] = "\xfb\xef\xff";
+static const char output7[] = "--__";
static int test(const char *input, unsigned int mode, const char *expect)
{
@@ -65,6 +69,8 @@ int main(void)
tst(input3, HXQUOTE_BASE64, output3c);
tst(input4, HXQUOTE_URIENC, output4);
tst(input5, HXQUOTE_SQLBQUOTE, output5);
+ tst(input6, HXQUOTE_BASE64, output6);
+ tst(input7, HXQUOTE_BASE64URL, output7);
return 0;
#undef tst
}
diff --git a/src/tc-switchuser.c b/src/tc-switchuser.c
new file mode 100644
index 0000000..3bb3fe9
--- /dev/null
+++ b/src/tc-switchuser.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright Jan Engelhardt
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the WTF Public License version 2 or
+ * (at your option) any later version.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#if defined(HAVE_INITGROUPS)
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libHX/defs.h>
+#include <libHX/option.h>
+#include <libHX/proc.h>
+
+static char *user_name, *group_name;
+static const struct HXoption options_table[] = {
+ {.sh = 'u', .type = HXTYPE_STRING, .ptr = &user_name},
+ {.sh = 'g', .type = HXTYPE_STRING, .ptr= &group_name},
+ HXOPT_TABLEEND,
+};
+
+int main(int argc, const char **argv)
+{
+ HX_getopt(options_table, &argc, &argv, HXOPT_USAGEONERR);
+ const char *user = user_name != NULL ? user_name : "-";
+ const char *group = group_name != NULL ? group_name : "-";
+ switch (HXproc_switch_user(user_name, group_name)) {
+ case HXPROC_USER_NOT_FOUND:
+ if (user_name == NULL)
+ abort(); /* impossible outcomes */
+ printf("No such user \"%s\": %s\n", user_name, strerror(errno));
+ break;
+ case HXPROC_GROUP_NOT_FOUND:
+ if (group_name == NULL || *group_name == '\0')
+ abort(); /* impossible outcome */
+ printf("No such group \"%s\": %s\n", group_name, strerror(errno));
+ break;
+ case HXPROC_SETUID_FAILED:
+ printf("setuid %s: %s\n", user, strerror(errno));
+ break;
+ case HXPROC_SETGID_FAILED:
+ printf("setgid %s: %s\n", group, strerror(errno));
+ break;
+ case HXPROC_INITGROUPS_FAILED:
+ printf("initgroups for %s: %s\n", user, strerror(errno));
+ break;
+ case HXPROC_SU_NOOP:
+ printf("No action was performed./User identity already reached.\n");
+ /* fallthrough */
+ case HXPROC_SU_SUCCESS: {
+ gid_t list[64] = {-1};
+ int numgroups = getgroups(ARRAY_SIZE(list), list);
+ printf("Identity now: uid %lu euid %lu gid %lu egid %lu\n",
+ static_cast(unsigned long, getuid()),
+ static_cast(unsigned long, geteuid()),
+ static_cast(unsigned long, getgid()),
+ static_cast(unsigned long, getegid()));
+ printf("Secondary groups:");
+ for (int i = 0; i < numgroups; ++i)
+ printf(" %lu", static_cast(unsigned long, list[i]));
+ printf("\n");
+ break;
+ }
+ }
+ return EXIT_SUCCESS;
+}
+#endif
diff --git a/src/tc-time.c b/src/tc-time.c
index e842e77..e86ed67 100644
--- a/src/tc-time.c
+++ b/src/tc-time.c
@@ -5,6 +5,7 @@
* modify it under the terms of the WTF Public License version 2 or
* (at your option) any later version.
*/
+#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
@@ -36,10 +37,12 @@ static const struct timespec pairs[] = {
};
/*
- * Variant that uses full 64 bit division and is thus slower on
- * a handful of hardware.
+ * The playing fields it not level at all!
+ * HX_timespec_add_DIVQ benefits from inlining and near jumps,
+ * while HX_timespec_add has to go via PLT, and also has the PIC tax.
+ * It is actually worse by 7% on i7-8250U/-m64.
*/
-static struct timespec *HX_timespec_add_FDIV(struct timespec *r,
+static struct timespec *HX_timespec_add_DIVQ(struct timespec *r,
const struct timespec *a, const struct timespec *b)
{
long long p, q;
@@ -105,6 +108,20 @@ HX_timespec_mulf_S(struct timespec *r, const struct timespec *a, double f)
return r;
}
+static void test_basic(void)
+{
+ struct timeval a = {1, 769298}, b = {2, 430520}, c;
+ struct timespec p = {1, 769298000}, q = {2, 430520000}, r;
+ HX_timeval_sub(&c, &b, &a);
+ HX_timespec_sub(&r, &q, &p);
+ printf(HX_TIMEVAL_FMT "\n", HX_TIMEVAL_EXP(&c));
+ printf(HX_TIMESPEC_FMT "\n", HX_TIMESPEC_EXP(&r));
+ assert(c.tv_sec == 0);
+ assert(c.tv_usec == 661222);
+ assert(r.tv_sec == 0);
+ assert(r.tv_nsec == 661222000);
+}
+
static void test_same(void)
{
static const struct timespec zero = {0, 0};
@@ -205,9 +222,9 @@ static void test_add(void)
for (a = pairs; a < pairs + ARRAY_SIZE(pairs); ++a) {
for (b = pairs; b < pairs + ARRAY_SIZE(pairs); ++b) {
HX_timespec_add(&r, a, b);
- print_op2(&r, a, "+N", b);
- HX_timespec_add_FDIV(&s, a, b);
- print_op2(&r, a, "+F", b);
+ print_op2(&r, a, "+L", b);
+ HX_timespec_add_DIVQ(&s, a, b);
+ print_op2(&r, a, "+Q", b);
if (r.tv_sec != s.tv_sec || r.tv_nsec != s.tv_nsec)
abort();
HX_timespec_sub(&r, a, b);
@@ -288,7 +305,7 @@ static void test_adds(void)
{
printf("# Test addition speed\n");
test_adds_1("normal: ", HX_timespec_add);
- test_adds_1("fulldiv: ", HX_timespec_add_FDIV);
+ test_adds_1("div64: ", HX_timespec_add_DIVQ);
printf("\n");
}
@@ -335,11 +352,10 @@ static void test_mul(void)
static void test_muls_1i(const char *text, mul_func_t fn)
{
struct timespec r, s, start, delta;
- unsigned int i;
printf("%s", text);
clock_gettime(clock_id, &start);
- for (i = 0; i < step_mul; ++i) {
+ for (time_t i = 0; i < step_mul; ++i) {
r.tv_sec = -i;
r.tv_nsec = -i / 4;
(*fn)(&s, &r, 7);
@@ -352,11 +368,10 @@ static void test_muls_1i(const char *text, mul_func_t fn)
static void test_muls_1f(const char *text, mulf_func_t fn)
{
struct timespec r, s, start, delta;
- unsigned int i;
printf("%s", text);
clock_gettime(clock_id, &start);
- for (i = 0; i < step_mul; ++i) {
+ for (time_t i = 0; i < step_mul; ++i) {
r.tv_sec = -i;
r.tv_nsec = -i / 4;
(*fn)(&s, &r, 7);
@@ -382,6 +397,7 @@ int main(void)
if (HX_init() <= 0)
abort();
+ test_basic();
test_same();
test_neg();
test_add();
diff --git a/src/time.c b/src/time.c
index e7eee3f..4daef27 100644
--- a/src/time.c
+++ b/src/time.c
@@ -6,6 +6,7 @@
* General Public License as published by the Free Software Foundation;
* either version 2.1 or (at your option) any later version.
*/
+#include <stdint.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <stdbool.h>
@@ -39,38 +40,13 @@ HX_timespec_neg(struct timespec *r, const struct timespec *a)
EXPORT_SYMBOL struct timespec *HX_timespec_add(struct timespec *r,
const struct timespec *a, const struct timespec *b)
{
- /*
- * Split the value represented by the struct into two
- * independent values that can be added individually.
- */
- long nsec[2];
- nsec[0] = (a->tv_sec < 0) ? -a->tv_nsec : a->tv_nsec;
- nsec[1] = (b->tv_sec < 0) ? -b->tv_nsec : b->tv_nsec;
-
- r->tv_sec = a->tv_sec + b->tv_sec;
- r->tv_nsec = nsec[0] + nsec[1];
- if (r->tv_nsec >= NANOSECOND) {
- ++r->tv_sec;
- r->tv_nsec -= NANOSECOND;
- } else if (r->tv_nsec <= -NANOSECOND) {
- --r->tv_sec;
- r->tv_nsec += NANOSECOND;
- }
-
- /* Combine again */
- if (r->tv_sec < 0) {
- if (r->tv_nsec < 0) {
- r->tv_nsec = -r->tv_nsec;
- } else if (r->tv_nsec > 0) {
- if (++r->tv_sec == 0)
- r->tv_nsec = -NANOSECOND + r->tv_nsec;
- else
- r->tv_nsec = NANOSECOND - r->tv_nsec;
- }
- } else if (r->tv_sec > 0 && r->tv_nsec < 0) {
- --r->tv_sec;
- r->tv_nsec = NANOSECOND + r->tv_nsec;
- }
+ long aa = a->tv_sec * NANOSECOND_LL +
+ ((a->tv_sec >= 0) ? a->tv_nsec : -a->tv_nsec);
+ long bb = b->tv_sec * NANOSECOND_LL +
+ ((b->tv_sec >= 0) ? b->tv_nsec : -b->tv_nsec);
+ long rr = aa + bb;
+ r->tv_sec = rr / NANOSECOND;
+ r->tv_nsec = ((r->tv_sec < 0) ? -rr : rr) % NANOSECOND;
return r;
}
@@ -119,20 +95,14 @@ HX_timespec_mulf(struct timespec *r, const struct timespec *a, double f)
EXPORT_SYMBOL struct timeval *HX_timeval_sub(struct timeval *delta,
const struct timeval *future, const struct timeval *past)
{
- delta->tv_sec = future->tv_sec - past->tv_sec;
- delta->tv_usec = future->tv_usec - past->tv_usec;
- if (future->tv_sec < past->tv_sec || (future->tv_sec == past->tv_sec &&
- future->tv_usec < past->tv_usec)) {
- if (future->tv_usec > past->tv_usec) {
- delta->tv_usec = -MICROSECOND + delta->tv_usec;
- ++delta->tv_sec;
- }
- if (delta->tv_sec < 0)
- delta->tv_usec *= -1;
- } else if (delta->tv_usec < 0) {
- delta->tv_usec += MICROSECOND;
- --delta->tv_sec;
- }
+ struct timespec d, f, p;
+ f.tv_sec = future->tv_sec;
+ f.tv_nsec = future->tv_usec * 1000;
+ p.tv_sec = past->tv_sec;
+ p.tv_nsec = past->tv_usec * 1000;
+ HX_timespec_sub(&d, &f, &p);
+ delta->tv_sec = d.tv_sec;
+ delta->tv_usec = d.tv_nsec / 1000;
return delta;
}
#endif
diff --git a/src/tx-intdiff.cpp b/src/tx-intdiff.cpp
new file mode 100644
index 0000000..cd8ec7a
--- /dev/null
+++ b/src/tx-intdiff.cpp
@@ -0,0 +1,24 @@
+#include <cstdio>
+#include <iterator>
+#include <vector>
+#include <libHX/intdiff.hpp>
+int main()
+{
+ std::vector<int> a{1, 2, 5};
+ std::vector<long> b{2, 3, 4, 5};
+ std::vector<float> comm, left, right;
+
+ HX::set_intersect_diff(a.cbegin(), a.cend(), b.cbegin(), b.cend(),
+ std::back_inserter(comm), std::back_inserter(left),
+ std::back_inserter(right));
+ for (auto e : comm)
+ printf("%f,", e);
+ printf("\n");
+ for (auto e : left)
+ printf("%f,", e);
+ printf("\n");
+ for (auto e : right)
+ printf("%f,", e);
+ printf("\n");
+ return 0;
+}
diff --git a/src/tx-option.cpp b/src/tx-option.cpp
index 55e3566..b70110f 100644
--- a/src/tx-option.cpp
+++ b/src/tx-option.cpp
@@ -5,7 +5,9 @@
#endif
#include <libHX/option.h>
+static unsigned int g_verbose;
static const struct HXoption t[] = {
+ {nullptr, 'v', HXTYPE_NONE | HXOPT_INC, &g_verbose},
HXOPT_AUTOHELP,
HXOPT_TABLEEND,
};