From eece9692d707ccb20356ec06955f8308c4e59ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 17 Dec 2023 14:18:48 +0100 Subject: New upstream version 4.19 --- src/Makefile.am | 17 +--- src/Makefile.in | 126 ++++++++++++------------ src/analyze.sh | 3 + src/internal.h | 5 +- src/libHX.map | 5 + src/opt.c | 64 ++++++------ src/proc.c | 2 +- src/rtcheck.c | 274 ---------------------------------------------------- src/socket.c | 12 ++- src/string.c | 68 +++++++++++-- src/tc-dir.c | 2 +- src/tc-format.c | 2 +- src/tc-list.c | 18 ++-- src/tc-memmem.c | 2 +- src/tc-misc.c | 6 +- src/tc-option.c | 68 +++++++++---- src/tc-realpath.c | 15 +-- src/tc-shconfig.c | 4 +- src/tc-string.c | 173 ++++++++++++--------------------- src/tc-switchuser.c | 8 +- src/tx-option.cpp | 6 +- src/uxcompat.h | 104 ++++++++++++++++++++ 22 files changed, 425 insertions(+), 559 deletions(-) create mode 100755 src/analyze.sh delete mode 100644 src/rtcheck.c create mode 100644 src/uxcompat.h (limited to 'src') 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 +#include #include #include #ifdef __cplusplus /* Only for our dual C/C++ testsuites */ -# define const_cast(type, expr) const_cast(expr) -# define const_cast1(type, expr) const_cast(expr) -# define const_cast2(type, expr) const_cast(expr) -# define const_cast3(type, expr) const_cast(expr) # define dynamic_cast(type, expr) dynamic_cast(expr) # define signed_cast(type, expr) signed_cast(expr) # define reinterpret_cast(type, expr) reinterpret_cast(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 #include #include +#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 -#ifdef RTLD_NEXT - -#include -#include -#include -#include -#include -#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 #include #include +#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 #include -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 #include #include +#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 #include #include +#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 +# include +#else +# include +# include +#endif +#include + +#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 */ -- cgit v1.2.3