summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am17
-rw-r--r--src/Makefile.in126
-rwxr-xr-xsrc/analyze.sh3
-rw-r--r--src/internal.h5
-rw-r--r--src/libHX.map5
-rw-r--r--src/opt.c64
-rw-r--r--src/proc.c2
-rw-r--r--src/rtcheck.c274
-rw-r--r--src/socket.c12
-rw-r--r--src/string.c68
-rw-r--r--src/tc-dir.c2
-rw-r--r--src/tc-format.c2
-rw-r--r--src/tc-list.c18
-rw-r--r--src/tc-memmem.c2
-rw-r--r--src/tc-misc.c6
-rw-r--r--src/tc-option.c68
-rw-r--r--src/tc-realpath.c15
-rw-r--r--src/tc-shconfig.c4
-rw-r--r--src/tc-string.c173
-rw-r--r--src/tc-switchuser.c8
-rw-r--r--src/tx-option.cpp6
-rw-r--r--src/uxcompat.h104
22 files changed, 425 insertions, 559 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ac68f74..676cd73 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,15 +5,11 @@ AM_CFLAGS = ${regular_CFLAGS}
AM_CXXFLAGS = ${regular_CXXFLAGS}
lib_LTLIBRARIES = libHX.la
-if HAVE_DLFCN_H
-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 proc.c \
rand.c socket.c string.c time.c
libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS} ${libsocket_LIBS}
-libHX_la_LDFLAGS = -no-undefined -version-info 38:0:6
+libHX_la_LDFLAGS = -no-undefined -version-info 39:0:7
if WITH_GNU_LD
libHX_la_LDFLAGS += -Wl,--version-script=${srcdir}/libHX.map
endif
@@ -24,21 +20,14 @@ libHX_la_SOURCES += ux-file.c ux-mmap.c
libHX_la_LIBADD += -lws2_32
endif
-libHX_rtcheck_la_SOURCES = rtcheck.c
-libHX_rtcheck_la_LIBADD = ${libdl_LIBS}
-libHX_rtcheck_la_LDFLAGS = -no-undefined -avoid-version -module
-if WITH_GNU_LD
-libHX_rtcheck_la_LDFLAGS += -Wl,--version-script=${srcdir}/libHX.map
-endif
-
-EXTRA_DIST = internal.h map_int.h libHX.map
+EXTRA_DIST = internal.h map_int.h libHX.map uxcompat.h analyze.sh
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-socket tc-strchr2 tc-string tc-strquote \
tc-switchuser tc-time
-TESTS = tc-format tc-strchr2 tc-strquote
+TESTS = tc-format tc-option tc-strchr2 tc-string tc-strquote
tc_cast_CFLAGS = ${AM_CFLAGS} -std=gnu99
tc_cast_LDADD = libHX.la -lm
tc_compile_LDADD = libHX.la
diff --git a/src/Makefile.in b/src/Makefile.in
index d349749..7e1bd81 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -90,11 +90,9 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
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
-@MINGW32_TRUE@am__append_4 = -lws2_32
-@WITH_GNU_LD_TRUE@am__append_5 = -Wl,--version-script=${srcdir}/libHX.map
+@WITH_GNU_LD_TRUE@am__append_1 = -Wl,--version-script=${srcdir}/libHX.map
+@MINGW32_TRUE@am__append_2 = ux-file.c ux-mmap.c
+@MINGW32_TRUE@am__append_3 = -lws2_32
check_PROGRAMS = tc-compile$(EXEEXT) tc-cast$(EXEEXT) \
tc-deque$(EXEEXT) tc-dir$(EXEEXT) tc-format$(EXEEXT) \
tc-io$(EXEEXT) tc-list$(EXEEXT) tc-list2$(EXEEXT) \
@@ -104,15 +102,15 @@ check_PROGRAMS = tc-compile$(EXEEXT) tc-cast$(EXEEXT) \
tc-socket$(EXEEXT) tc-strchr2$(EXEEXT) tc-string$(EXEEXT) \
tc-strquote$(EXEEXT) tc-switchuser$(EXEEXT) tc-time$(EXEEXT) \
$(am__EXEEXT_1)
-TESTS = tc-format$(EXEEXT) tc-strchr2$(EXEEXT) tc-strquote$(EXEEXT) \
- $(am__EXEEXT_2)
-@HAVE_CXX_TRUE@am__append_6 = tx-compile tx-cast tx-deque tx-dir \
+TESTS = tc-format$(EXEEXT) tc-option$(EXEEXT) tc-strchr2$(EXEEXT) \
+ tc-string$(EXEEXT) tc-strquote$(EXEEXT) $(am__EXEEXT_2)
+@HAVE_CXX_TRUE@am__append_4 = 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
-@HAVE_CXX_TRUE@am__append_7 = tx-strchr2 tx-strquote
+@HAVE_CXX_TRUE@am__append_5 = tx-strchr2 tx-strquote
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/gcc4_visibility.m4 \
@@ -182,14 +180,6 @@ am__v_lt_1 =
libHX_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libHX_la_LDFLAGS) $(LDFLAGS) -o $@
-libHX_rtcheck_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am_libHX_rtcheck_la_OBJECTS = rtcheck.lo
-libHX_rtcheck_la_OBJECTS = $(am_libHX_rtcheck_la_OBJECTS)
-libHX_rtcheck_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) $(libHX_rtcheck_la_LDFLAGS) $(LDFLAGS) \
- -o $@
-@HAVE_DLFCN_H_TRUE@am_libHX_rtcheck_la_rpath = -rpath $(libdir)
tc_cast_SOURCES = tc-cast.c
tc_cast_OBJECTS = tc_cast-tc-cast.$(OBJEXT)
tc_cast_DEPENDENCIES = libHX.la
@@ -351,19 +341,18 @@ 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-socket.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)/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-socket.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 \
@@ -411,31 +400,31 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
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-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-socket.c 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 \
+SOURCES = $(libHX_la_SOURCES) tc-cast.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-socket.c tc-strchr2.c \
tc-string.c 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) \
- $(am__tx_strchr2_SOURCES_DIST) $(am__tx_string_SOURCES_DIST) \
- $(am__tx_strquote_SOURCES_DIST) $(am__tx_time_SOURCES_DIST)
+ $(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) tc-cast.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-socket.c \
+ tc-strchr2.c tc-string.c 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) $(am__tx_strchr2_SOURCES_DIST) \
+ $(am__tx_string_SOURCES_DIST) $(am__tx_strquote_SOURCES_DIST) \
+ $(am__tx_time_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -672,6 +661,7 @@ EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FILECMD = @FILECMD@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@@ -775,18 +765,14 @@ top_srcdir = @top_srcdir@
AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include
AM_CFLAGS = ${regular_CFLAGS}
AM_CXXFLAGS = ${regular_CXXFLAGS}
-lib_LTLIBRARIES = libHX.la $(am__append_1)
+lib_LTLIBRARIES = libHX.la
libHX_la_SOURCES = deque.c dl.c format.c io.c map.c mc.c misc.c opt.c \
- proc.c rand.c socket.c string.c time.c $(am__append_3)
+ proc.c rand.c socket.c string.c time.c $(am__append_2)
libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS} \
- ${libsocket_LIBS} $(am__append_4)
-libHX_la_LDFLAGS = -no-undefined -version-info 38:0:6 $(am__append_2)
+ ${libsocket_LIBS} $(am__append_3)
+libHX_la_LDFLAGS = -no-undefined -version-info 39:0:7 $(am__append_1)
EXTRA_libHX_la_DEPENDENCIES = libHX.map
-libHX_rtcheck_la_SOURCES = rtcheck.c
-libHX_rtcheck_la_LIBADD = ${libdl_LIBS}
-libHX_rtcheck_la_LDFLAGS = -no-undefined -avoid-version -module \
- $(am__append_5)
-EXTRA_DIST = internal.h map_int.h libHX.map
+EXTRA_DIST = internal.h map_int.h libHX.map uxcompat.h analyze.sh
tc_cast_CFLAGS = ${AM_CFLAGS} -std=gnu99
tc_cast_LDADD = libHX.la -lm
tc_compile_LDADD = libHX.la
@@ -923,9 +909,6 @@ clean-libLTLIBRARIES:
libHX.la: $(libHX_la_OBJECTS) $(libHX_la_DEPENDENCIES) $(EXTRA_libHX_la_DEPENDENCIES)
$(AM_V_CCLD)$(libHX_la_LINK) -rpath $(libdir) $(libHX_la_OBJECTS) $(libHX_la_LIBADD) $(LIBS)
-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)
-
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)
@@ -1098,7 +1081,6 @@ distclean-compile:
@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
@@ -1446,6 +1428,13 @@ tc-format.log: tc-format$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tc-option.log: tc-option$(EXEEXT)
+ @p='tc-option$(EXEEXT)'; \
+ b='tc-option'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
tc-strchr2.log: tc-strchr2$(EXEEXT)
@p='tc-strchr2$(EXEEXT)'; \
b='tc-strchr2'; \
@@ -1453,6 +1442,13 @@ tc-strchr2.log: tc-strchr2$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tc-string.log: tc-string$(EXEEXT)
+ @p='tc-string$(EXEEXT)'; \
+ b='tc-string'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
tc-strquote.log: tc-strquote$(EXEEXT)
@p='tc-strquote$(EXEEXT)'; \
b='tc-strquote'; \
@@ -1581,7 +1577,6 @@ distclean: distclean-am
-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
@@ -1681,7 +1676,6 @@ maintainer-clean: maintainer-clean-am
-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
diff --git a/src/analyze.sh b/src/analyze.sh
new file mode 100755
index 0000000..042998f
--- /dev/null
+++ b/src/analyze.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+f="--analyze -Xanalyzer -analyzer-output=text -Wall -g3"
+make -k check CC=clang CXX=clang++ CFLAGS="$f" CXXFLAGS="$f"
diff --git a/src/internal.h b/src/internal.h
index 0465d81..f7d83d8 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -11,15 +11,12 @@
#include "config.h"
#include <stdint.h>
+#include <libHX/cast.h>
#include <libHX/defs.h>
#include <libHX/string.h>
#ifdef __cplusplus
/* Only for our dual C/C++ testsuites */
-# define const_cast(type, expr) const_cast<type>(expr)
-# define const_cast1(type, expr) const_cast<type>(expr)
-# define const_cast2(type, expr) const_cast<type>(expr)
-# define const_cast3(type, expr) const_cast<type>(expr)
# define dynamic_cast(type, expr) dynamic_cast<type>(expr)
# define signed_cast(type, expr) signed_cast<type>(expr)
# define reinterpret_cast(type, expr) reinterpret_cast<type>(expr)
diff --git a/src/libHX.map b/src/libHX.map
index 37bfe0f..374a881 100644
--- a/src/libHX.map
+++ b/src/libHX.map
@@ -178,3 +178,8 @@ LIBHX_4.16 {
global:
HX_strtoull_nsec;
} LIBHX_4.15;
+
+LIBHX_4.18 {
+global:
+ HX_getopt5;
+} LIBHX_4.16;
diff --git a/src/opt.c b/src/opt.c
index f91785d..ab482ad 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -20,6 +20,7 @@
#include <libHX/misc.h>
#include <libHX/option.h>
#include <libHX/string.h>
+#undef HX_getopt
#include "internal.h"
/* Definitions */
@@ -697,16 +698,19 @@ static int HX_getopt_normal(const char *cur, const struct HX_getopt_vars *par)
return HXOPT_S_NORMAL | HXOPT_I_ADVARG;
}
-EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
- const char ***argv, unsigned int flags)
+EXPORT_SYMBOL int HX_getopt5(const struct HXoption *table, char **orig_argv,
+ int *new_argc, char ***new_argv, unsigned int flags)
{
struct HX_getopt_vars ps;
- const char **opt = *argv;
+ const char **opt = const_cast(const char **, orig_argv);
int state = HXOPT_S_NORMAL;
int ret = -ENOMEM;
- unsigned int argk;
- const char *cur;
+ unsigned int argk = 0;
+ if (new_argc != nullptr)
+ *new_argc = 0;
+ if (new_argv != nullptr)
+ *new_argv = nullptr;
memset(&ps, 0, sizeof(ps));
ps.remaining = HXdeque_init();
if (ps.remaining == NULL) {
@@ -714,7 +718,7 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
goto out;
}
ps.flags = flags;
- ps.arg0 = **argv;
+ ps.arg0 = *opt;
ps.cbi.table = table;
if (*opt != NULL) {
@@ -733,7 +737,7 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
if (posix_me_harder())
ps.flags |= HXOPT_RQ_ORDER;
- for (cur = *opt; cur != NULL; ) {
+ for (const char *cur = *opt; cur != NULL; ) {
if (state == HXOPT_S_TWOLONG)
state = HX_getopt_twolong(opt, &ps);
else if (state == HXOPT_S_LONG)
@@ -764,33 +768,19 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
state &= ~HXOPT_I_MASK;
}
- if (!(ps.flags & HXOPT_KEEP_ARGV)) {
- const char **nvec = reinterpret_cast(const char **,
- HXdeque_to_vec(ps.remaining, &argk));
- if (nvec == NULL) {
+ if (new_argv != nullptr) {
+ *new_argv = reinterpret_cast(char **, HXdeque_to_vec(ps.remaining, &argk));
+ if (*new_argv == nullptr) {
ret = -errno;
goto out;
}
- if (ps.flags & HXOPT_DESTROY_OLD)
- /*
- * Only the "true, original" argv is stored on the
- * stack - the argv that HX_getopt() produces is on
- * the heap, so the %HXOPT_DESTROY_OLD flag should be
- * passed when you use passthrough chaining, i.e. all
- * but the first call to HX_getopt() should have this
- * set.
- */
- HX_zvecfree(const_cast2(char **, *argv));
-
- *argv = nvec;
- if (argc != NULL)
- *argc = argk;
- /* pointers are owned by nvec/argv now */
+ if (new_argc != nullptr)
+ *new_argc = argk;
+ /* pointers are owned by new_argv now, so free only the deque head */
HXdeque_free(ps.remaining);
ps.remaining = nullptr;
}
ret = HXOPT_ERR_SUCCESS;
-
out:
if (ret == HXOPT_ERR_SUCCESS) {
} else if (ret < 0) {
@@ -808,6 +798,26 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
return ret;
}
+EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
+ char ***argv, unsigned int flags)
+{
+ int new_argc = 0;
+ char **new_argv = nullptr;
+ int ret = HX_getopt5(table, *argv, &new_argc,
+ flags & HXOPT_KEEP_ARGV ? nullptr : &new_argv, flags);
+ if (ret != HXOPT_ERR_SUCCESS)
+ return ret;
+ if (flags & HXOPT_KEEP_ARGV)
+ // NO_CREATE_NEW / DESTROY_NEW
+ new_argv = *argv;
+ else if (flags & HXOPT_DESTROY_OLD)
+ HX_zvecfree(*argv);
+ if (argc != nullptr)
+ *argc = new_argc;
+ *argv = new_argv;
+ return ret;
+}
+
EXPORT_SYMBOL void HX_getopt_help(const struct HXoptcb *cbi, FILE *nfp)
{
FILE *fp = (nfp == NULL) ? stderr : nfp;
diff --git a/src/proc.c b/src/proc.c
index 801023b..c8957b6 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -103,7 +103,7 @@ EXPORT_SYMBOL enum HXproc_su_status HXproc_switch_user(const char *user, const c
#else
-EXPORT_SYMBOL int HXproc_switch_user(const char *user, const char *group)
+EXPORT_SYMBOL enum HXproc_su_status HXproc_switch_user(const char *user, const char *group)
{
return -ENOSYS;
}
diff --git a/src/rtcheck.c b/src/rtcheck.c
deleted file mode 100644
index 6f04baa..0000000
--- a/src/rtcheck.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Additional runtime checks
- * Copyright Jan Engelhardt, 2011
- *
- * 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.
- *
- * libHX_rtcheck.so is a library supposed to be used together with the
- * LD_PRELOAD environment variable to dynamically add extra checks.
- */
-#define _GNU_SOURCE 1
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
-#ifdef RTLD_NEXT
-
-#include <pthread.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <libHX.h>
-#include "internal.h"
-
-#define call_next(f) \
- ((__typeof__(f) *)dlsym(RTLD_NEXT, #f))
-
-#define stub_head(f, args, invoke) \
- EXPORT_SYMBOL __typeof__(f invoke) f args \
- { \
- if (HXrefchk_count <= 0) \
- fprintf(stderr, "%s: HX_init has not been called!\n", \
- __func__);
-
-#define stub_tail(f, params) \
- return call_next(f) params; \
- }
-
-#define stub(f, args, invoke, params) \
- stub_head(f, args, invoke) \
- stub_tail(f, params)
-
-#define stubv(f, args, params) \
- EXPORT_SYMBOL void f args \
- { \
- if (HXrefchk_count <= 0) \
- fprintf(stderr, "%s: HX_init has not been called!\n", \
- __func__); \
- call_next(f) params; \
- }
-
-#define stub0(f) stub(f, (void), (), ())
-#define stub1(f, args) stub(f, args, (0), (a))
-#define stub1v(f, args) stubv(f, args, (a))
-#define stub2(f, args) stub(f, args, (0, 0), (a, b))
-#define stub2v(f, args) stubv(f, args, (a, b))
-#define stub3(f, args) stub(f, args, (0, 0, 0), (a, b, c))
-#define stub3v(f, args) stubv(f, args, (a, b, c))
-#define stub4(f, args) stub(f, args, (0, 0, 0, 0), (a, b, c, d))
-#define stub5(f, args) stub(f, args, (0, 0, 0, 0, 0), (a, b, c, d, e))
-
-static pthread_mutex_t HXrefchk_lock = PTHREAD_MUTEX_INITIALIZER;
-static unsigned long HXrefchk_count;
-
-EXPORT_SYMBOL int HX_init(void)
-{
- /*
- * The real HX_init has its own reference count check, but that
- * variable is not exported that we could test it, so the counter needs
- * to be replicated here.
- */
- pthread_mutex_lock(&HXrefchk_lock);
- if (HXrefchk_count == 0) {
- printf("# " PACKAGE_NAME " " PACKAGE_VERSION
- " runtime checker active\n");
- call_next(HX_init)();
- }
- ++HXrefchk_count;
- pthread_mutex_unlock(&HXrefchk_lock);
- return 1;
-}
-
-EXPORT_SYMBOL void HX_exit(void)
-{
- pthread_mutex_lock(&HXrefchk_lock);
- if (HXrefchk_count == 0)
- fprintf(stderr, "%s: reference count is already zero!\n", __func__);
- else
- --HXrefchk_count;
- pthread_mutex_unlock(&HXrefchk_lock);
- call_next(HX_exit)();
-}
-
-/* deque.h */
-stub0(HXdeque_init);
-stub2(HXdeque_push, (struct HXdeque *a, const void *b));
-stub2(HXdeque_unshift, (struct HXdeque *a, const void *b));
-stub1(HXdeque_pop, (struct HXdeque *a));
-stub1(HXdeque_shift, (struct HXdeque *a));
-stub2(HXdeque_move, (struct HXdeque_node *a, struct HXdeque_node *b));
-stub2(HXdeque_find, (struct HXdeque *a, const void *b));
-stub2(HXdeque_get, (struct HXdeque *a, const void *b));
-stub1(HXdeque_del, (struct HXdeque_node *a));
-stub1v(HXdeque_free, (struct HXdeque *a));
-stub2v(HXdeque_genocide2, (struct HXdeque *a, void (*b)(void *)));
-stub2(HXdeque_to_vec, (const struct HXdeque *a, unsigned int *b));
-
-/* io.h */
-stub1(HXdir_open, (const char *a));
-stub1(HXdir_read, (struct HXdir *a));
-stub1v(HXdir_close, (struct HXdir *a));
-/* HX_copy_dir: has varargs */
-/* HX_copy_file: has varargs */
-stub2(HX_mkdir, (const char *a, unsigned int b));
-stub2(HX_readlink, (hxmc_t **a, const char *b));
-stub3(HX_realpath, (hxmc_t **a, const char *b, unsigned int c));
-stub1(HX_rrmdir, (const char *a));
-
-stub3(HXio_fullread, (int a, void *b, size_t c));
-stub3(HXio_fullwrite, (int a, const void *b, size_t c));
-
-/* map.h */
-stub2(HXmap_init, (enum HXmap_type a, unsigned int b));
-stub5(HXmap_init5, (enum HXmap_type a, unsigned int b,
- const struct HXmap_ops *c, size_t d, size_t e));
-stub3(HXmap_add, (struct HXmap *a, const void *b, const void *c));
-stub2(HXmap_find, (const struct HXmap *a, const void *b));
-stub2(HXmap_get, (const struct HXmap *a, const void *b));
-stub2(HXmap_del, (struct HXmap *a, const void *b));
-stub1(HXmap_keysvalues, (const struct HXmap *a));
-stub2(HXmap_travinit, (const struct HXmap *a, unsigned int b));
-stub1(HXmap_traverse, (struct HXmap_trav *a));
-stub1v(HXmap_travfree, (struct HXmap_trav *a));
-stub3v(HXmap_qfe, (const struct HXmap *a,
- bool (*b)(const struct HXmap_node *, void *), void *c));
-stub1v(HXmap_free, (struct HXmap *a));
-
-/* misc.h */
-stub1(HX_dlopen, (const char *a));
-stub2(HX_dlsym, (void *a, const char *b));
-stub1v(HX_dlclose, (void *a));
-stub0(HX_dlerror);
-
-stub1(HX_ffs, (unsigned long a));
-stub1(HX_fls, (unsigned long a));
-stub3(HX_hexdump, (FILE *a, const void *b, unsigned int c));
-stub3(HX_timespec_add, (struct timespec *a, const struct timespec *b,
- const struct timespec *c));
-stub1(HX_timespec_isneg, (const struct timespec *a));
-stub3(HX_timespec_mul, (struct timespec *a, const struct timespec *b, int c));
-stub3(HX_timespec_mulf, (struct timespec *a, const struct timespec *b,
- double c));
-stub2(HX_timespec_neg, (struct timespec *a, const struct timespec *b));
-stub3(HX_timespec_sub, (struct timespec *a, const struct timespec *b,
- const struct timespec *c));
-stub3(HX_timeval_sub, (struct timeval *a, const struct timeval *b,
- const struct timeval *c));
-stub3(HX_time_compare, (const struct stat *a, const struct stat *b, char c));
-stub1v(HX_zvecfree, (char **a));
-
-stub0(HX_rand);
-stub2(HX_irand, (unsigned int a, unsigned int b));
-stub2(HX_drand, (double a, double b));
-
-/* option.h */
-stub0(HXformat_init);
-stub1v(HXformat_free, (struct HXformat_map *a));
-stub4(HXformat_add, (struct HXformat_map *a, const char *b, const void *c,
- unsigned int d));
-stub3(HXformat_aprintf, (const struct HXformat_map *a, hxmc_t **b,
- const char *c));
-stub4(HXformat_sprintf, (const struct HXformat_map *a, char *b, size_t c,
- const char *d));
-stub3(HXformat_fprintf, (const struct HXformat_map *a, FILE *b,
- const char *c));
-
-stub4(HX_getopt, (const struct HXoption *a, int *b, const char ***c,
- unsigned int d));
-/* HX_getopt_help: not really public */
-/* HX_getopt_help_cb: not really public */
-/* HX_getopt_usage: not really public */
-/* HX_getopt_usage_cb: not really public */
-stub2(HX_shconfig, (const char *a, const struct HXoption *b));
-stub1(HX_shconfig_map, (const char *a));
-stub4(HX_shconfig_pv, (const char **a, const char *b, const struct HXoption *c,
- unsigned int d));
-stub1v(HX_shconfig_free, (const struct HXoption *a));
-
-/* proc.h */
-stub2(HXproc_run_async, (const char *const *a, struct HXproc *b));
-stub2(HXproc_run_sync, (const char *const *a, unsigned int b));
-stub1(HXproc_wait, (struct HXproc *a));
-
-/* string.h */
-static __inline__ struct memcont *HXmc_base(const hxmc_t *p)
-{
- return containerof(p, struct memcont, data);
-}
-
-static __inline__ void HXmc_check(const char *func, const void *cv)
-{
- const struct memcont *c;
-
- if (cv == NULL)
- return;
- c = HXmc_base(cv);
- if (c->id != HXMC_IDENT)
- fprintf(stderr, "%s: %p is not a HXmc object!\n", func, cv);
-}
-
-stub1(HXmc_strinit, (const char *a));
-stub2(HXmc_meminit, (const void *a, size_t b));
-
-stub_head(HXmc_strcpy, (hxmc_t **a, const char *b), (0, 0))
-{
- if (*a != NULL)
- HXmc_check(__func__, *a);
-}
-stub_tail(HXmc_strcpy, (a, b))
-
-stub_head(HXmc_memcpy, (hxmc_t **a, const void *b, size_t c), (0, 0, 0))
-{
- if (*a != NULL)
- HXmc_check(__func__, *a);
-}
-stub_tail(HXmc_memcpy, (a, b, c))
-
-stub_head(HXmc_length, (const hxmc_t *a), (0))
-{
- if (a != NULL)
- HXmc_check(__func__, a);
-}
-stub_tail(HXmc_length, (a))
-
-stub2(HXmc_setlen, (hxmc_t **a, size_t b));
-stub2(HXmc_trunc, (hxmc_t **a, size_t b));
-stub2(HXmc_strcat, (hxmc_t **a, const char *b));
-stub3(HXmc_memcat, (hxmc_t **a, const void *b, size_t c));
-stub2(HXmc_strpcat, (hxmc_t **a, const char *b));
-stub3(HXmc_mempcat, (hxmc_t **a, const void *b, size_t c));
-stub3(HXmc_strins, (hxmc_t **a, size_t b, const char *c));
-stub4(HXmc_memins, (hxmc_t **a, size_t b, const void *c, size_t d));
-stub3(HXmc_memdel, (hxmc_t *a, size_t b, size_t c));
-stub1v(HXmc_free, (hxmc_t *a));
-stub1v(HXmc_zvecfree, (hxmc_t **a));
-
-stub1(HX_basename, (const char *a));
-stub1(HX_basename_exact, (const char *a));
-stub1(HX_chomp, (char *a));
-stub1(HX_dirname, (const char *a));
-stub2(HX_getl, (hxmc_t **a, FILE *b));
-stub4(HX_memmem, (const void *a, size_t b, const void *c, size_t d));
-stub4(HX_split, (const char *a, const char *b, int *c, int d));
-stub4(HX_split_inplace, (char *a, const char *b, int *c, int d));
-stub4(HX_split_fixed, (char *a, const char *b, int c, char **d));
-stub1(HX_stpltrim, (const char *a));
-stub1(HX_stprtrim, (char *a));
-stub3(HX_strbchr, (const char *a, const char *b, char c));
-stub2(HX_strclone, (char **a, const char *b));
-stub1(HX_strlower, (char *a));
-stub1(HX_strltrim, (char *a));
-stub3(HX_strmid, (const char *a, long b, long c));
-stub2(HX_strndup, (const char *a, size_t b));
-stub2(HX_strnlen, (const char *a, size_t b));
-stub3(HX_strquote, (const char *a, unsigned int b, char **c));
-stub2(HX_strrcspn, (const char *a, const char *b));
-stub1(HX_strrev, (char *a));
-stub1(HX_strrtrim, (char *a));
-stub2(HX_strsep, (char **a, const char *b));
-stub2(HX_strsep2, (char **a, const char *b));
-stub1(HX_strupper, (char *a));
-
-#endif /* RTLD_NEXT */
-#endif /* HAVE_DLFCN_H */
diff --git a/src/socket.c b/src/socket.c
index e2ad9ed..9fdd903 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -394,13 +394,15 @@ EXPORT_SYMBOL int HX_socket_from_env(const struct addrinfo *ai, const char *intf
}
top_fd = x;
}
- for (int fd = 3; fd < top_fd; ++fd)
- if (try_sk_from_env(fd, ai, intf) == fd) {
+ for (int fd = 3; fd < top_fd; ++fd) {
+ if (try_sk_from_env(fd, ai, intf) != fd)
+ continue;
#ifdef SOCK_CLOEXEC
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+ if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC) != 0)
+ /* ignore */;
#endif
- return fd;
- }
+ return fd;
+ }
errno = ENOENT;
return -1;
}
diff --git a/src/string.c b/src/string.c
index 4abd694..06066ce 100644
--- a/src/string.c
+++ b/src/string.c
@@ -980,6 +980,7 @@ EXPORT_SYMBOL double HX_strtod_unit(const char *s, char **out_end, unsigned int
if (end == s) {
if (out_end != nullptr)
*out_end = end;
+ errno = 0;
return q;
}
while (HX_isspace(*end))
@@ -988,10 +989,12 @@ EXPORT_SYMBOL double HX_strtod_unit(const char *s, char **out_end, unsigned int
if (pwr == 0) {
if (out_end != nullptr)
*out_end = const_cast(char *, end);
+ errno = 0;
return q;
}
if (out_end != nullptr)
*out_end = const_cast(char *, end + 1);
+ errno = 0;
return q * pow(exponent, pwr);
}
@@ -1001,17 +1004,45 @@ EXPORT_SYMBOL unsigned long long HX_strtoull_unit(const char *s,
char *end;
unsigned long long ipart;
unsigned int pwr = 0;
+ bool neg = false;
while (HX_isspace(*s))
++s;
+ if (*s == '-') {
+ /*
+ * "-5k": While (-5ULL) * 1000 is the same as (-5000ULL) under
+ * modulo arithmetic, the expression `ipart >= ULLONG_MAX /
+ * exponent` depends on seeing the true value (5 rather than
+ * (-5ULL).)
+ */
+ neg = true;
+ ++s;
+ }
+ errno = 0;
ipart = strtoull(s, &end, 10);
+ if (ipart == ULLONG_MAX && errno == ERANGE)
+ return ipart;
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)
+ if (!hi_ok || !lo_ok) {
+ errno = ERANGE;
return ULLONG_MAX;
- return q;
+ }
+ /*
+ * https://eel.is/c++draft/conv.fpint: values unrepresentable
+ * in the target type (such as forcing -5.2f into a uint) is
+ * UB. Thus check for range and apply the negation after the
+ * conversion to ULL.
+ */
+ if (q > ULLONG_MAX) {
+ errno = ERANGE;
+ return ULLONG_MAX;
+ }
+ unsigned long long r = q;
+ errno = 0;
+ return neg ? -r : r;
}
if (exponent == 0)
exponent = 1000;
@@ -1021,7 +1052,8 @@ EXPORT_SYMBOL unsigned long long HX_strtoull_unit(const char *s,
if (pwr == 0) {
if (out_end != nullptr)
*out_end = end;
- return ipart;
+ errno = 0;
+ return neg ? -ipart: ipart;
}
if (out_end != nullptr)
*out_end = const_cast(char *, end + 1);
@@ -1032,11 +1064,13 @@ EXPORT_SYMBOL unsigned long long HX_strtoull_unit(const char *s,
}
ipart *= exponent;
}
- return ipart;
+ errno = 0;
+ return neg ? -ipart : ipart;
}
-#define SECONDS_PER_YEAR 31557600
-#define SECONDS_PER_MONTH 2629800
+/* Numbers also used by systemd — the focus is on longterm averages */
+#define SECONDS_PER_YEAR 31557600 /* 365.25 days */
+#define SECONDS_PER_MONTH 2629800 /* 1/12th of that year = 30.4375 days */
#define NSEC_PER_SECOND 1000000000ULL
static const struct {
@@ -1071,7 +1105,6 @@ static const struct {
{"µs", 3, 0, 1000},
{"nsec", 4, 0, 1},
{"ns", 2, 0, 1},
- {"", 0, 1, NSEC_PER_SECOND},
};
static unsigned long long HX_strtoull_time(const char *s, char **out_end, bool nsec)
@@ -1081,10 +1114,13 @@ static unsigned long long HX_strtoull_time(const char *s, char **out_end, bool n
while (*s != '\0') {
while (HX_isspace(*s))
++s;
+ const char *numbegin = s;
if (*s == '-')
break;
char *end = nullptr;
unsigned long long num = strtoull(s, &end, 10);
+ if (num == ULLONG_MAX && errno == ERANGE)
+ return num;
double frac = 0;
bool have_frac = *end == '.';
if (have_frac)
@@ -1100,13 +1136,25 @@ static unsigned long long HX_strtoull_time(const char *s, char **out_end, bool n
time_multiplier[i].len) == 0 &&
!HX_isalpha(s[time_multiplier[i].len]))
break;
- if (i == ARRAY_SIZE(time_multiplier))
+ if (i == ARRAY_SIZE(time_multiplier)) {
+ if ((!have_frac && num == 0) || (have_frac && frac == 0))
+ /* 0 is the same no matter what unit, take it */
+ continue;
+ s = numbegin;
break;
+ }
unsigned long long mult = nsec ? time_multiplier[i].ns_mult : time_multiplier[i].s_mult;
- if (have_frac)
+ if (have_frac) {
quant += frac * mult;
- else
+ } else {
+ if (mult > 0 && num >= ULLONG_MAX / mult) {
+ if (out_end != nullptr)
+ *out_end = const_cast(char *, numbegin);
+ errno = ERANGE;
+ return ULLONG_MAX;
+ }
quant += num * mult;
+ }
s += time_multiplier[i].len;
}
if (out_end != nullptr)
diff --git a/src/tc-dir.c b/src/tc-dir.c
index ec44977..7f987bc 100644
--- a/src/tc-dir.c
+++ b/src/tc-dir.c
@@ -22,7 +22,7 @@ static void lookatdir(const char *dname)
HXdir_close(dh);
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
if (HX_init() <= 0)
return EXIT_FAILURE;
diff --git a/src/tc-format.c b/src/tc-format.c
index ed8e6d4..5c5c6e6 100644
--- a/src/tc-format.c
+++ b/src/tc-format.c
@@ -73,7 +73,7 @@ static int t_format(int argc)
return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret;
diff --git a/src/tc-list.c b/src/tc-list.c
index e8a30b6..d31a5c7 100644
--- a/src/tc-list.c
+++ b/src/tc-list.c
@@ -10,6 +10,7 @@
#include <libHX/list.h>
#include <libHX/init.h>
#include <libHX/misc.h>
+#include "internal.h"
struct text_object {
struct HXlist_head list;
@@ -64,13 +65,14 @@ static void l_traverse(void)
static void l_dump(bool pop)
{
static const char *const msg[] = {"Shifting", "Popping"};
- struct text_object *obj;
unsigned int i = 0;
- while ((obj = (pop ?
- HXclist_pop(&strings_ct, struct text_object, list) :
- HXclist_shift(&strings_ct, struct text_object, list)
- )) != NULL) {
+ while (true) {
+ struct text_object *obj = pop ?
+ HXclist_pop(&strings_ct, struct text_object, list) :
+ HXclist_shift(&strings_ct, struct text_object, list);
+ if (obj == nullptr)
+ break;
printf("%s item %u (\"%s\")\n", msg[pop], ++i, obj->id);
#ifdef __cplusplus
delete obj;
@@ -138,7 +140,7 @@ static void l_shift(void)
#pragma GCC diagnostic pop
}
-static int runner(int argc, const char **argv)
+static int runner(int argc, char **argv)
{
unsigned int max = 10;
@@ -157,10 +159,10 @@ static int runner(int argc, const char **argv)
return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret = runner(argc, argv);
- if (ret != EXIT_FAILURE)
+ if (ret == EXIT_FAILURE)
fprintf(stderr, "FAILED\n");
return ret;
}
diff --git a/src/tc-memmem.c b/src/tc-memmem.c
index 1a56f1b..6115aec 100644
--- a/src/tc-memmem.c
+++ b/src/tc-memmem.c
@@ -78,7 +78,7 @@ static int runner(void)
int main(void)
{
int ret = runner();
- if (ret != EXIT_FAILURE)
+ if (ret == EXIT_FAILURE)
fprintf(stderr, "FAILED\n");
return ret;
}
diff --git a/src/tc-misc.c b/src/tc-misc.c
index d422f21..1677807 100644
--- a/src/tc-misc.c
+++ b/src/tc-misc.c
@@ -8,7 +8,7 @@
#include <libHX/init.h>
#include <libHX/misc.h>
-static int runner(int argc, const char **argv)
+static int runner(int argc, char **argv)
{
unsigned int n;
struct stat sa, sb;
@@ -43,10 +43,10 @@ static int runner(int argc, const char **argv)
return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret = runner(argc, argv);
- if (ret != EXIT_FAILURE)
+ if (ret == EXIT_FAILURE)
fprintf(stderr, "FAILED\n");
return ret;
}
diff --git a/src/tc-option.c b/src/tc-option.c
index 83271e0..8e99b19 100644
--- a/src/tc-option.c
+++ b/src/tc-option.c
@@ -11,6 +11,7 @@
#include <libHX/init.h>
#include <libHX/map.h>
#include <libHX/option.h>
+#include "internal.h"
static int opt_v = 0, opt_mask = 0;
static char *opt_kstr = NULL;
@@ -64,45 +65,69 @@ static struct HXoption table[] = {
HXOPT_TABLEEND,
};
-static void dump_argv(const char **v)
+static void dump_argv(char **v)
{
while (*v != NULL)
printf("[%s] ", *v++);
printf("\n");
}
-static void t_pthru(void)
+static int t_pthru(void)
{
const char *argv[] = {
"ARGV0", "-Zomg", "-GZfoo", "bar",
"--unknown-f=13.37", "--unknown-a",
"foo", "bar", NULL
};
- const char **argp = argv;
- int argc = ARRAY_SIZE(argv) - 1;
+ char **nargv = nullptr;
+ int nargc = 0;
printf("PTHRU test:\n");
- HX_getopt(table, &argc, &argp, HXOPT_USAGEONERR | HXOPT_PTHRU);
- dump_argv(argp);
+ if (HX_getopt5(table, const_cast(char **, argv), &nargc, &nargv,
+ HXOPT_USAGEONERR | HXOPT_PTHRU) != HXOPT_ERR_SUCCESS)
+ return EXIT_FAILURE;
+ printf("argc = %d\n", nargc);
+ dump_argv(nargv);
printf("\n");
+ HX_zvecfree(nargv);
+ return EXIT_SUCCESS;
}
-static void t_empty_argv(void)
+static int t_empty_argv(void)
{
- const char *zero_argv[] = {NULL}, **zero_argp = zero_argv;
- int zero_argc = 0;
+ char *zero_argv[] = {nullptr};
+ char **new_argv = nullptr;
printf("Testing argv={NULL}\n");
- HX_getopt(table, &zero_argc, &zero_argp, HXOPT_USAGEONERR);
+ if (HX_getopt5(table, zero_argv, nullptr, &new_argv,
+ HXOPT_USAGEONERR) != HXOPT_ERR_SUCCESS)
+ return EXIT_FAILURE;
+ HX_zvecfree(new_argv);
+ return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+static int t_keep_argv(void)
{
- if (HX_init() <= 0)
+ static const char *const one_argv[] = {"what", nullptr};
+ const char **argv = const_cast2(const char **, one_argv);
+ if (HX_getopt(table, nullptr, &argv, HXOPT_KEEP_ARGV) != HXOPT_ERR_SUCCESS)
return EXIT_FAILURE;
- printf("Return value of HX_getopt: %d\n",
- HX_getopt(table, &argc, &argv, HXOPT_USAGEONERR));
- t_empty_argv();
+ return argv == one_argv ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+static int runner(int argc, char **argv)
+{
+ char **nargv = nullptr;
+ int ret = HX_getopt5(table, argv, &argc, &nargv, HXOPT_USAGEONERR);
+ printf("Return value of HX_getopt: %d\n", ret);
+ if (ret == EXIT_SUCCESS)
+ HX_zvecfree(nargv);
+ ret = t_empty_argv();
+ if (ret != EXIT_SUCCESS)
+ return ret;
+ ret = t_keep_argv();
+ if (ret != EXIT_SUCCESS)
+ return ret;
printf("Either-or is: %s\n", opt_eitheror[opt_dst]);
printf("values: D=%lf I=%d L=%ld S=%s\n",
@@ -110,9 +135,16 @@ int main(int argc, const char **argv)
printf("Verbosity level: %d\n", opt_v);
printf("Mask: 0x%08X\n", opt_mask);
printf("mcstr: >%s<\n", opt_mcstr);
+ return t_pthru();
+}
- t_pthru();
-
+int main(int argc, char **argv)
+{
+ if (HX_init() <= 0)
+ return EXIT_FAILURE;
+ int ret = runner(argc, argv);
+ if (ret != EXIT_SUCCESS)
+ printf("FAILED\n");
HX_exit();
- return EXIT_SUCCESS;
+ return ret;
}
diff --git a/src/tc-realpath.c b/src/tc-realpath.c
index 23609ca..b71c127 100644
--- a/src/tc-realpath.c
+++ b/src/tc-realpath.c
@@ -8,6 +8,7 @@
#include <libHX/io.h>
#include <libHX/option.h>
#include <libHX/string.h>
+#include "internal.h"
static unsigned int rp_flags;
static unsigned int rp_absolute;
@@ -24,9 +25,9 @@ static const struct HXoption rp_option_table[] = {
HXOPT_TABLEEND,
};
-static bool rp_get_options(int *argc, const char ***argv)
+static bool rp_get_options(char **oargv, int *argc, char ***argv)
{
- if (HX_getopt(rp_option_table, argc, argv, HXOPT_USAGEONERR) !=
+ if (HX_getopt5(rp_option_table, oargv, argc, argv, HXOPT_USAGEONERR) !=
HXOPT_ERR_SUCCESS)
return false;
rp_flags = HX_REALPATH_DEFAULT;
@@ -47,18 +48,19 @@ static void t_1(void)
HXmc_free(tmp);
}
-int main(int argc, const char **argv)
+int main(int argc, char **oargv)
{
+ char **argv = nullptr;
hxmc_t *res;
int ret;
- if (!rp_get_options(&argc, &argv))
+ if (!rp_get_options(oargv, &argc, &argv))
return EXIT_FAILURE;
t_1();
res = NULL;
- while (--argc > 0) {
- ret = HX_realpath(&res, *++argv, rp_flags);
+ for (int i = 1; i < argc; ++i) {
+ ret = HX_realpath(&res, argv[argc], rp_flags);
if (ret < 0) {
perror("HX_realpath");
printf("\n");
@@ -66,5 +68,6 @@ int main(int argc, const char **argv)
printf("%s\n", res);
}
}
+ HX_zvecfree(argv);
return EXIT_SUCCESS;
}
diff --git a/src/tc-shconfig.c b/src/tc-shconfig.c
index 3717c15..0dde4c5 100644
--- a/src/tc-shconfig.c
+++ b/src/tc-shconfig.c
@@ -44,7 +44,7 @@ static int t_shconfig2(const char *file)
return EXIT_SUCCESS;
}
-static int runner(int argc, const char **argv)
+static int runner(int argc, char **argv)
{
int ret;
@@ -61,7 +61,7 @@ static int runner(int argc, const char **argv)
return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret = runner(argc, argv);
if (ret != EXIT_SUCCESS)
diff --git a/src/tc-string.c b/src/tc-string.c
index 1c7ed09..e7f90c2 100644
--- a/src/tc-string.c
+++ b/src/tc-string.c
@@ -197,93 +197,6 @@ static void t_split2(void)
HX_zvecfree(a);
}
-/* avoid these being inlined */
-extern char *f_strlcpy_str(char *, const char *, size_t);
-extern char *f_strlcpy_mem(char *, const char *, size_t);
-
-EXPORT_SYMBOL char *f_strlcpy_str(char *d, const char *s, size_t n)
-{
- if (n == 0)
- return d;
- strncpy(d, s, n);
- d[n-1] = '\0';
- return d;
-}
-
-EXPORT_SYMBOL char *f_strlcpy_mem(char *dest, const char *src, size_t dsize)
-{
- size_t slen = strlen(src);
- if (slen < dsize)
- return static_cast(char *, memcpy(dest, src, slen + 1));
- if (dsize > 0) {
- memcpy(dest, src, dsize - 1);
- dest[dsize-1] = '\0';
- }
- return dest;
-}
-
-static const char s_lorem_ipsum[] = /* 1368 chars */
-"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo "
-"ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis "
-"parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, "
-"pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec "
-"pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, "
-"rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede "
-"mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper "
-"nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, "
-"consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra "
-"quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. "
-"Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur "
-"ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, "
-"tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing "
-"sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit "
-"id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut "
-"libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros "
-"faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec "
-"sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit "
-"cursus nunc,";
-
-static void t_strlcpy(void)
-{
- static const size_t picksizes[] =
- {4, 8, 16, 32, 64, 80, 128, 256, 1024, 2048};
- char ibuf[2048], obuf[2048];
- size_t ipick, opick, k, runs = 10000000 + HX_irand(0, 1);
- struct timespec start, stop, d1, d2, d3;
-
- for (ipick = 0; ipick < ARRAY_SIZE(picksizes); ++ipick) {
- /* Select string size */
- HX_strlcpy(ibuf, s_lorem_ipsum, picksizes[ipick]);
-
- for (opick = 0; opick < ARRAY_SIZE(picksizes); ++opick) {
- /* Select buffer size */
- clock_gettime(CLOCK_MONOTONIC, &start);
- for (k = 0; k < runs; ++k)
- f_strlcpy_str(reinterpret_cast(char *, obuf),
- ibuf, picksizes[opick]);
- clock_gettime(CLOCK_MONOTONIC, &stop);
- HX_timespec_sub(&d1, &stop, &start);
-
- clock_gettime(CLOCK_MONOTONIC, &start);
- for (k = 0; k < runs; ++k)
- f_strlcpy_mem(reinterpret_cast(char *, obuf),
- ibuf, picksizes[opick]);
- clock_gettime(CLOCK_MONOTONIC, &stop);
- HX_timespec_sub(&d2, &stop, &start);
-
- HX_timespec_sub(&d3, &d1, &d2);
- printf("%4zu->%4zu: " HX_TIMESPEC_FMT
- " (str=" HX_TIMESPEC_FMT
- " mem=" HX_TIMESPEC_FMT ")\n",
- strlen(ibuf), picksizes[opick],
- HX_TIMESPEC_EXP(&d3),
- HX_TIMESPEC_EXP(&d1),
- HX_TIMESPEC_EXP(&d2)
- );
- }
- }
-}
-
static void t_strlcpy2(void)
{
char a[3] = {49, 49, 49};
@@ -381,8 +294,8 @@ static int t_units_strto(void)
unsigned long long expect_out;
const char expect_rem[8];
} vt[] = {
- {"-5k", 1000, ULLONG_MAX, "-5k"},
- {" -5.2k", 1000, ULLONG_MAX, "-5.2k"},
+ {"-5k", 1000, -5000ULL, ""},
+ {" -5.2k", 1000, -5200ULL, ""},
{"1", 9999, 1, ""},
{"1024", 9999, 1ULL << 10, ""},
{"1048576", 9999, 1ULL << 20, ""},
@@ -403,6 +316,10 @@ static int t_units_strto(void)
{"1T", 1024, 1ULL << 40, ""},
{"1P", 1024, 1ULL << 50, ""},
{"1E", 1024, 1ULL << 60, ""},
+ {"15E", 1024, 15ULL << 60, ""},
+ {"16E", 1024, ULLONG_MAX, ""},
+ {"16.0E", 1024, ULLONG_MAX, ""},
+ {"1Z", 1024, ULLONG_MAX, ""},
{"0", 0, 0, ""},
{"0k", 0, 0, ""},
{"0 Z", 0, 0, ""},
@@ -412,18 +329,28 @@ static int t_units_strto(void)
{"0.00000000000000001E", 1024, 11, ""},
{"1.525444GiB", 1000, 1525444000, "iB"},
{"1.525444GiB", 1024, 1637933022, "iB"},
+ {"2M4k", 1000, 2000000, "4k"},
+ {"18446744073709551614", 0, 18446744073709551614ULL, ""},
+ {"18446744073709551615", 0, ULLONG_MAX, ""},
+ {"18446744073709551616", 0, ULLONG_MAX, ""},
+ {"-18446744073709551614", 0, 2, ""},
+ {"-18446744073709551615", 0, 1, ""},
+ {"-18446744073709551616", 0, ULLONG_MAX, ""},
};
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("Observed: %s -> %llu __ %s\n", vt[i].input, q, end);
+ if (q != vt[i].expect_out || strcmp(end, vt[i].expect_rem) != 0) {
+ printf("Expected: %s -> %llu __ %s\n", vt[i].input,
+ vt[i].expect_out, vt[i].expect_rem);
return EXIT_FAILURE;
+ }
}
return EXIT_SUCCESS;
}
-static void t_time_units(void)
+static int t_time_units(void)
{
static const struct {
unsigned long long input;
@@ -432,10 +359,13 @@ static void t_time_units(void)
} 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"},
+ {34819200, HXUNIT_WEEKS, "57weeks4d"},
+ {34819200, HXUNIT_MONTHS, "13months7d7h30min"},
+ {34819200, HXUNIT_MONTHS | HXUNIT_WEEKS, "13months1week7h30min"},
+ {34819200, HXUNIT_YEARS, "1y37d18h"},
+ {34819200, HXUNIT_YEARS | HXUNIT_WEEKS, "1y5weeks2d18h"},
+ {34819200, HXUNIT_YEARS | HXUNIT_MONTHS, "1y1month7d7h30min"},
+ {34819200, HXUNIT_YEARS | HXUNIT_MONTHS | HXUNIT_WEEKS, "1y1month1week7h30min"},
{2678400, HXUNIT_MONTHS, "1month13h30min"},
{2592000, HXUNIT_MONTHS, "30d"},
{608400, HXUNIT_WEEKS, "1week1h"},
@@ -449,41 +379,55 @@ static void t_time_units(void)
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);
+ printf("Observed: %llus => \"%s\"\n", vt[i].input, ret);
+ if (strcmp(ret, vt[i].expect_out) != 0) {
+ printf("Expected: \"%s\"\n", vt[i].expect_out);
+ return EXIT_FAILURE;
+ }
}
+ return EXIT_SUCCESS;
}
-static void t_time_strto(void)
+static int t_time_strto(void)
{
#define NS_PER_S 1000000000ULL
static const struct {
const char *input;
unsigned long long expect_s, expect_ns;
- const char expect_rem[8];
+ const char expect_rem[16];
} vt[] = {
{"29µs", 0, 29000, ""},
{"1y", 31557600, NS_PER_S * 31557600, ""},
{"1y1month1week1d1h1min1s ", 31557600+2629800+86400*8+3600+60+1, NS_PER_S * (31557600+2629800+86400*8+3600+60+1), ""},
{" -1d", 0, 0, "-1d"},
- {"1 -", 1, NS_PER_S, "-"},
+ {"1 -", 0, 0, "1 -"},
{"12.5 hours .5 hours 240 minutes 25200 seconds", 86400, NS_PER_S * 86400, ""},
{"1s", 1, NS_PER_S, ""},
{"1min", 60, 60 * NS_PER_S, ""},
{"0", 0, 0, ""},
+ {"0.0", 0, 0, ""},
+ {"1s0", 1, NS_PER_S, ""},
+ {"1s0.0", 1, NS_PER_S, ""},
+ {"1s1s", 2, 2 * NS_PER_S, ""},
+ {"1s1", 1, 1 * NS_PER_S, "1"},
+ {"584542046091y", ULLONG_MAX, ULLONG_MAX, "584542046091y"},
};
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);
unsigned long long qn = HX_strtoull_nsec(vt[i].input, &end);
- printf("\"%s\" => %llus [%lluns] + \"%s\"\n", vt[i].input, q, qn, end);
- if (q != vt[i].expect_s || qn != vt[i].expect_ns)
- printf("\tBUG: expected %llus [%lluns]\n", vt[i].expect_s, vt[i].expect_ns);
- if (strcmp(end, vt[i].expect_rem) != 0)
- printf("\tBUG: expected remainder \"%s\"\n", vt[i].expect_rem);
+ printf("Observed: \"%s\" => %llus [%lluns] + \"%s\"\n", vt[i].input, q, qn, end);
+ if (q != vt[i].expect_s || qn != vt[i].expect_ns) {
+ printf("Expected: %llus [%lluns]\n", vt[i].expect_s, vt[i].expect_ns);
+ return EXIT_FAILURE;
+ }
+ if (strcmp(end, vt[i].expect_rem) != 0) {
+ printf("Expected: remainder \"%s\"\n", vt[i].expect_rem);
+ return EXIT_FAILURE;
+ }
}
+ return EXIT_SUCCESS;
}
static int t_strmid(void)
@@ -515,7 +459,7 @@ static int t_strmid(void)
#undef T
}
-static int runner(int argc, const char **argv)
+static int runner(int argc, char **argv)
{
hxmc_t *tx = NULL;
const char *file = (argc >= 2) ? argv[1] : "tx-string.cpp";
@@ -559,19 +503,22 @@ static int runner(int argc, const char **argv)
ret = t_units_strto();
if (ret != EXIT_SUCCESS)
return EXIT_FAILURE;
- t_time_units();
- t_time_strto();
- t_strlcpy();
+ ret = t_time_units();
+ if (ret != EXIT_SUCCESS)
+ return EXIT_FAILURE;
+ ret = t_time_strto();
+ if (ret != EXIT_SUCCESS)
+ return EXIT_FAILURE;
t_strlcpy2();
HXmc_free(tx);
HX_exit();
return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret = runner(argc, argv);
- if (ret != EXIT_FAILURE)
+ if (ret == EXIT_FAILURE)
fprintf(stderr, "FAILED\n");
return ret;
}
diff --git a/src/tc-switchuser.c b/src/tc-switchuser.c
index 4cc5604..e5d2c25 100644
--- a/src/tc-switchuser.c
+++ b/src/tc-switchuser.c
@@ -19,9 +19,10 @@ static const struct HXoption options_table[] = {
HXOPT_TABLEEND,
};
-static int runner(int argc, const char **argv)
+static int runner(int argc, char **argv)
{
- HX_getopt(options_table, &argc, &argv, HXOPT_USAGEONERR);
+ if (HX_getopt(options_table, &argc, &argv, HXOPT_USAGEONERR) != HXOPT_ERR_SUCCESS)
+ return EXIT_FAILURE;
const char *user = user_name != NULL ? user_name : "-";
const char *group = group_name != NULL ? group_name : "-";
switch (HXproc_switch_user(user_name, group_name)) {
@@ -62,10 +63,11 @@ static int runner(int argc, const char **argv)
break;
}
}
+ HX_zvecfree(argv);
return EXIT_SUCCESS;
}
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
int ret = runner(argc, argv);
if (ret != EXIT_SUCCESS)
diff --git a/src/tx-option.cpp b/src/tx-option.cpp
index b70110f..248ab7c 100644
--- a/src/tx-option.cpp
+++ b/src/tx-option.cpp
@@ -12,8 +12,10 @@ static const struct HXoption t[] = {
HXOPT_TABLEEND,
};
-int main(int argc, const char **argv)
+int main(int argc, char **argv)
{
- HX_getopt(t, &argc, &argv, HXOPT_USAGEONERR);
+ if (HX_getopt(t, &argc, &argv, HXOPT_USAGEONERR) != HXOPT_ERR_SUCCESS)
+ return EXIT_FAILURE;
+ HX_zvecfree(argv);
return EXIT_SUCCESS;
}
diff --git a/src/uxcompat.h b/src/uxcompat.h
new file mode 100644
index 0000000..e735c50
--- /dev/null
+++ b/src/uxcompat.h
@@ -0,0 +1,104 @@
+#ifndef _LIBHX_UXCOMPAT_H
+#define _LIBHX_UXCOMPAT_H 1
+
+#if defined(__cplusplus) && __cplusplus >= 201100UL
+# include <cstddef>
+# include <cstdint>
+#else
+# include <stddef.h>
+# include <stdint.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ENOSYS
+# define ENOSYS 38 /* Function not implemented */
+#endif
+
+#ifndef S_IFLNK
+# define S_IFLNK 0xA000
+#endif
+#ifndef S_IFSOCK
+# define S_IFSOCK 0xC000
+#endif
+#ifndef S_IFBLK
+# define S_IFBLK 0x6000
+#endif
+#ifndef S_IFCHR
+# define S_IFCHR 0x2000
+#endif
+#ifndef S_IFIFO
+# define S_IFIFO 0x1000
+#endif
+#ifndef S_ISBLK
+# define S_ISBLK(__mode) (((__mode) & S_IFMT) == S_IFBLK)
+#endif
+#ifndef S_ISCHR
+# define S_ISCHR(__mode) (((__mode) & S_IFMT) == S_IFCHR)
+#endif
+#ifndef S_ISDIR
+# define S_ISDIR(__mode) (((__mode) & S_IFMT) == S_IFDIR)
+#endif
+#ifndef S_ISREG
+# define S_ISREG(__mode) (((__mode) & S_IFMT) == S_IFREG)
+#endif
+#ifndef S_ISLNK
+# define S_ISLNK(__mode) (((__mode) & S_IFMT) == S_IFLNK)
+#endif
+#ifndef S_ISFIFO
+# define S_ISFIFO(__mode) (((__mode) & S_IFMT) == S_IFIFO)
+#endif
+#ifndef S_ISSOCK
+# define S_ISSOCK(__mode) (((__mode) & S_IFMT) == S_IFSOCK)
+#endif
+#ifndef S_IRGRP
+# define S_IRGRP 00040
+#endif
+#ifndef S_IWGRP
+# define S_IWGRP 00020
+#endif
+#ifndef S_IROTH
+# define S_IROTH 00004
+#endif
+#ifndef S_IWOTH
+# define S_IWOTH 00002
+#endif
+
+struct stat;
+
+/*
+ * UX-FILE.C
+ */
+extern int chown(const char *, long, long);
+extern int fchmod(int, long);
+extern int fchown(int, long, long);
+extern int lchown(const char *, long, long);
+extern int lstat(const char *, struct stat *);
+extern int mkfifo(const char *, long);
+extern int mknod(const char *, long, long);
+extern int readlink(const char *, char *, size_t);
+extern int symlink(const char *, const char *);
+
+/*
+ * UX-MMAP.C
+ */
+#ifdef _WIN32
+# define MAP_FAILED reinterpret_cast(void *, static_cast(intptr_t, -1))
+# define PROT_NONE 0x0
+# define PROT_READ 0x1
+# define PROT_WRITE 0x2
+# define PROT_EXEC 0x4
+# define MAP_SHARED 0x1
+# define MAP_PRIVATE 0x2
+extern void *mmap(void *, size_t, int, int, int, off_t);
+extern int munmap(void *, size_t);
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* _LIBHX_UXCOMPAT_H */