diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 3 | ||||
-rw-r--r-- | src/Makefile.am | 25 | ||||
-rw-r--r-- | src/Makefile.in | 438 | ||||
-rw-r--r-- | src/deque.c | 2 | ||||
-rw-r--r-- | src/format.c | 2 | ||||
-rw-r--r-- | src/internal.h | 3 | ||||
-rw-r--r-- | src/io.c | 287 | ||||
-rw-r--r-- | src/libHX.map | 24 | ||||
-rw-r--r-- | src/map.c | 2 | ||||
-rw-r--r-- | src/mc.c | 6 | ||||
-rw-r--r-- | src/opt.c | 11 | ||||
-rw-r--r-- | src/proc.c | 186 | ||||
-rw-r--r-- | src/socket.c | 124 | ||||
-rw-r--r-- | src/string.c | 309 | ||||
-rw-r--r-- | src/tc-compile.c | 10 | ||||
-rw-r--r-- | src/tc-io.c | 55 | ||||
-rw-r--r-- | src/tc-link.c | 156 | ||||
-rw-r--r-- | src/tc-list.c | 5 | ||||
-rw-r--r-- | src/tc-map.c | 47 | ||||
-rw-r--r-- | src/tc-memmem.c | 1 | ||||
-rw-r--r-- | src/tc-proc.c | 3 | ||||
-rw-r--r-- | src/tc-realpath.c | 10 | ||||
-rw-r--r-- | src/tc-string.c | 205 | ||||
-rw-r--r-- | src/tc-strquote.c | 6 | ||||
-rw-r--r-- | src/tc-switchuser.c | 73 | ||||
-rw-r--r-- | src/tc-time.c | 38 | ||||
-rw-r--r-- | src/time.c | 62 | ||||
-rw-r--r-- | src/tx-intdiff.cpp | 24 | ||||
-rw-r--r-- | src/tx-option.cpp | 2 |
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; @@ -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; @@ -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; @@ -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; } @@ -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 && @@ -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(); @@ -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, }; |