diff --git a/CHANGES b/CHANGES index df2cfc3..3251e53 100644 --- a/CHANGES +++ b/CHANGES @@ -166,6 +166,10 @@ Corrections: by Socat. Now an error is printed when, e.g,, a read-only type address is opened for writing. + A lot of minor corrections, e.g., catch readline() errors in filan, + detect byte order in procan + Test: EXEC_SIGINT + Coding: Introduced groups_t instead of uint32_t, for more flexibility. diff --git a/configure.ac b/configure.ac index adff4c5..90362c0 100644 --- a/configure.ac +++ b/configure.ac @@ -328,26 +328,6 @@ AC_ARG_ENABLE(interface, [ --disable-interface disable network interface suppo *) AC_MSG_RESULT(yes); WITH_INTERFACE=1 ;; esac], [AC_MSG_RESULT(yes); WITH_INTERFACE=1 ]) -if test "$WITH_INTERFACE"; then - AC_CHECK_HEADER(linux/if_packet.h, - AC_DEFINE(HAVE_LINUX_IF_PACKET_H), - [WITH_INTERFACE=; - AC_MSG_WARN([include file linux/if_packet.h not found, disabling interface])]) -fi -if test "$WITH_INTERFACE"; then - AC_CHECK_HEADER(netinet/if_ether.h, - AC_DEFINE(HAVE_NETINET_IF_ETHER_H), - [WITH_INTERFACE=; - AC_MSG_WARN([include file netinet/if_ether.h not found, disabling interface])], - [AC_INCLUDES_DEFAULT - #if HAVE_NET_IF_H && HAVE_NETINET_IN_H - #include - #include - #endif]) -fi -if test "$WITH_INTERFACE"; then - AC_DEFINE(WITH_INTERFACE) -fi AC_MSG_CHECKING(whether to include TCP support) AC_ARG_ENABLE(tcp, [ --disable-tcp disable TCP support], @@ -835,6 +815,28 @@ if test -n "$WITH_TUN"; then AC_DEFINE(WITH_TUN) fi +if test "$WITH_INTERFACE"; then + AC_CHECK_HEADER(netinet/if_ether.h, + AC_DEFINE(HAVE_NETINET_IF_ETHER_H), + [WITH_INTERFACE=; + AC_MSG_WARN([include file netinet/if_ether.h not found, disabling interface])], + [AC_INCLUDES_DEFAULT + #if HAVE_NET_IF_H && HAVE_NETINET_IN_H + #include + #include + #endif]) +fi + +if test "$WITH_INTERFACE" || test "$WITH_TUN"; then + AC_CHECK_HEADER(linux/if_packet.h, + AC_DEFINE(HAVE_LINUX_IF_PACKET_H), + [WITH_INTERFACE=; + AC_MSG_WARN([include file linux/if_packet.h not found, disabling interface])]) +fi +if test "$WITH_INTERFACE"; then + AC_DEFINE(WITH_INTERFACE) +fi + AC_MSG_CHECKING(whether to include system call tracing) AC_ARG_ENABLE(sycls, [ --disable-sycls disable system call tracing], [case "$enableval" in diff --git a/filan.c b/filan.c index 18b2bf4..26f4668 100644 --- a/filan.c +++ b/filan.c @@ -412,8 +412,12 @@ int filan_stat( { char linktarget[PATH_MAX+1]; memset(linktarget, 0, PATH_MAX+1); - Readlink(filename, linktarget, PATH_MAX); - fprintf(outfile, "LINKTARGET=%s", linktarget); + if (Readlink(filename, linktarget, PATH_MAX) < 0) { + Warn3("readlink(\"%s\", linktarget, %d): %s", + filename, PATH_MAX, strerror(errno)); + } else { + fprintf(outfile, "LINKTARGET=%s", linktarget); + } } break; #endif /* S_IFLNK */ diff --git a/hostan.c b/hostan.c index 07212af..74d3dbd 100644 --- a/hostan.c +++ b/hostan.c @@ -32,6 +32,23 @@ int hostan(FILE *outfile) { fprintf(outfile, "sizeof(long long) = %u\n", (unsigned int)sizeof(long long)); #endif fprintf(outfile, "sizeof(size_t) = %u\n", (unsigned int)sizeof(size_t)); + { + union { + uint16_t s; + uint8_t c[2]; + } bo; + bo.c[0] = 0x05; + bo.c[1] = 0xa0; + if (bo.s == 0x05a0) { + fprintf(outfile, "host byte order: network (BE \"big endian\", most significast byte first)\n"); + } else if (bo.s == 0xa005) { + fprintf(outfile, "host byte order: intel (LE \"little endian\", least significast byte first\n"); + } else { + fprintf(outfile, "host byte order: unknown\n"); + fprintf(stderr, "failed to determine host byte order"); + } + } + #include /* select(); OpenBSD: struct timespec */ fprintf(outfile, "sizeof(struct timespec) = %u\n", (unsigned int)sizeof(struct timespec)); fprintf(outfile, "sizeof(struct diag_dgram) = %u\n", (unsigned int)sizeof(struct diag_dgram)); diff --git a/socat.c b/socat.c index f8ea83d..864415b 100644 --- a/socat.c +++ b/socat.c @@ -399,12 +399,14 @@ int main(int argc, const char *argv[]) { } } +#if WITH_STATS #if HAVE_SIGACTION act.sa_handler = socat_signal_logstats; Sigaction(SIGUSR1, &act, NULL); #else Signal(SIGUSR1, socat_signal_logstats); #endif +#endif /* WITH_STATS */ } Signal(SIGPIPE, SIG_IGN); @@ -419,9 +421,11 @@ int main(int argc, const char *argv[]) { } Atexit(socat_unlock); +#if WITH_STATS if (socat_opts.statistics) { Atexit(socat_print_stats); } +#endif /* WITH_STATS */ result = socat(arg1[0], arg1[1]); if (result == EXIT_SUCCESS && engine_result != EXIT_SUCCESS) { diff --git a/socat.spec b/socat.spec index 90f7309..caaab79 100644 --- a/socat.spec +++ b/socat.spec @@ -49,6 +49,7 @@ rm -rf $RPM_BUILD_ROOT %doc README CHANGES EXAMPLES SECURITY doc/socat.html FAQ BUGREPORTS %doc COPYING COPYING.OpenSSL FILES PORTING DEVELOPMENT %{_bindir}/socat1 +%{_bindir}/socat %{_bindir}/procan %{_bindir}/filan %{_mandir}/man1/socat1.1 diff --git a/sysutils.h b/sysutils.h index e84df00..5e8ae10 100644 --- a/sysutils.h +++ b/sysutils.h @@ -30,7 +30,7 @@ union sockaddr_union { #if WITH_VSOCK struct sockaddr_vm vm; #endif /* WITH_IP6 */ -#if WITH_INTERFACE +#if _WITH_INTERFACE struct sockaddr_ll ll; #endif } ; diff --git a/test.sh b/test.sh index 2225f3c..df336a6 100755 --- a/test.sh +++ b/test.sh @@ -71,7 +71,7 @@ while [ "$1" ]; do X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;; X-N) shift; NUMCOND="test \$N -ge $1" ;; X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;; - X-foreign) FOREIGN=1 ;; # allow access to 3rd party Internet hosts + X-foreign|X--foreign) FOREIGN=1 ;; # allow access to 3rd party Internet hosts X-expect-fail|X--expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;; X-*) echo "Unknown option \"$1\"" >&2 usage >&2 @@ -136,6 +136,22 @@ if [ -z "$SOCAT_VERSION" ]; then echo "Warning: failed to retrieve Socat version" >&2 fi +if type ip >/dev/null 2>&1; then + if ip -V |grep -q -i -e "^ip utility, iproute2-" -e BusyBox; then + IP=$(type -p ip) + else + unset IP + fi +fi + +if type ss >/dev/null 2>&1; then + if ss -V |grep -q "^ss utility, iproute2-"; then + SS=$(type -p ss) + else + unset SS + fi +fi + # for some tests we need a network interface if type ip >/dev/null 2>&1; then INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") @@ -354,22 +370,6 @@ else SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)" fi -if type ip >/dev/null 2>&1; then - if ip -V |grep -q "^ip utility, iproute2-"; then - IP=$(type -p ip) - else - unset IP - fi -fi - -if type ss >/dev/null 2>&1; then - if ss -V |grep -q "^ss utility, iproute2-"; then - SS=$(type -p ss) - else - unset SS - fi -fi - if [ -z "$SS" ]; then # non-root users might miss ifconfig in their path case "$UNAME" in @@ -4458,7 +4458,7 @@ N=$((N+1)) NAME=READLINE #set -vx case "$TESTS" in -*%$N%*|*%functions%*|*%pty%*|*%readline%*|*%$NAME%*) +*%$N%*|*%functions%*|*%pty%*|*%readline%*|*%sigint%*|*%$NAME%*) TEST="$NAME: readline with password and sigint" if ! eval $NUMCOND; then :; elif ! feat=$(testfeats readline pty); then @@ -8462,23 +8462,27 @@ kill "$pid1" 2>/dev/null; wait; if [ "$rc2" -ne 0 ]; then $PRINTF "$FAILED: $TRACE $SOCAT:\n" echo "$CMD1 &" + cat "${te}1" >&2 echo "$CMD2" - cat "${te}1" - cat "${te}2" + cat "${te}2" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" elif ! echo "$da" |diff - "$tf" >"$tdiff"; then $PRINTF "$FAILED\n" - cat "$tdiff" + echo "$CMD1 &" + cat "${te}1" >&2 + echo "$CMD2" + cat "${te}2" >&2 + echo diff: >&2 + cat "$tdiff" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" else $PRINTF "$OK\n" - if [ -n "$VERBOSE" ]; then - echo "$CMD1 &" - echo "$CMD2" - fi - if [ -n "$debug" ]; then cat $te; fi + if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi + if [ "$DEBUG" ]; then cat "${te}1" >&2; fi + if [ "$VERBOSE" ]; then echo "$CMD2"; fi + if [ "$DEBUG" ]; then cat "${te}2" >&2; fi numOK=$((numOK+1)) fi fi ;; # NUMCOND @@ -14751,6 +14755,7 @@ TEST="$NAME: UDP4-SEND with lowport" # succeeded. # This test does not require root because it just checks log of bind() but does # not require success +# This test fails if WITH_SYCLS is turned off if ! eval $NUMCOND; then :; else tf="$td/test$N.stdout" te="$td/test$N.stderr" @@ -14766,13 +14771,18 @@ LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head #type socat >&2 if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then $PRINTF "$OK\n" - if [ "$VERBOSE" ]; then - echo "$CMD" >&2 - fi + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi numOK=$((numOK+1)) +elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then + $PRINTF "$CANT (no SYCLS)\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" else $PRINTF "$FAILED\n" - echo "$CMD" >&2 + echo "$CMD" cat "${te}" >&2 numFAIL=$((numFAIL+1)) listFAIL="$listFAIL $N" @@ -15785,8 +15795,8 @@ case "$TESTS" in *%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*) TEST="$NAME: test the children-shutup option" # Run a UNIX domain listening server with options fork and children-shutup, and -# an TCP client to invalid port that will fail. -# Connect to the server and check if it logs the connect failure as warning. +# that connects to a closed TCP4 port. +# Connect to the server and check if it logs the TCP4-CONNECT failure as warning. if ! eval $NUMCOND; then :; elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N @@ -15813,7 +15823,7 @@ printf "test $F_n $TEST... " $N $CMD0 >/dev/null 2>"${te}0" & pid0=$! waitunixport $ts 1 -$CMD1 2>"${te}1" +{ $CMD1 2>"${te}1"; sleep 1; } rc1=$? kill $pid0 2>/dev/null; wait relsleep 1 # child process might need more time @@ -17056,6 +17066,60 @@ esac N=$((N+1)) +# Test the sigint option +NAME=EXEC_SIGINT +case "$TESTS" in +*%$N%*|*%functions%*|*%socket%*|*%exec%*|*%sigint%*|*%$NAME%*) +TEST="$NAME: sigint option with EXEC" +# Run Socat with an EXEC address invoking Socat, with option sigint +# Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM) +# the test succeeded +if ! eval $NUMCOND; then :; +# Remove unneeded checks, adapt lists of the remaining ones +elif ! F=$(testfeats STDIO EXEC PIPE); then + $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif ! A=$(testaddrs STDIO EXEC PIPE); then + $PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +elif ! o=$(testoptions setsid sigint) >/dev/null; then + $PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N + numCANT=$((numCANT+1)) + listCANT="$listCANT $N" +else +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da="test$N $(date) $RANDOM" +CMD0="$TRACE $SOCAT $opts -T 1 PIPE EXEC:cat,setsid,sigint" +printf "test $F_n $TEST... " $N +$CMD0 >/dev/null 2>"${te}0" & +pid0=$! +relsleep 2 +kill -INT $pid0 +wait +if grep -q " W waitpid..: child .* exited with status 130" "${te}0" || + grep -q " W waitpid..: child .* exited on signal 2" "${te}0"; then + $PRINTF "$OK\n" + if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi + if [ "$DEBUG" ]; then cat "${te}0" >&2; fi + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD0 &" + cat "${te}0" >&2 + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" + namesFAIL="$namesFAIL $NAME" +fi +fi # NUMCOND + ;; +esac +N=$((N+1)) + + # end of common tests ################################################################################## diff --git a/xio-interface.c b/xio-interface.c index ba03f52..f29012f 100644 --- a/xio-interface.c +++ b/xio-interface.c @@ -47,7 +47,7 @@ const struct optdesc opt_iff_automedia = { "iff-automedia", "automedia", O #endif /*const struct optdesc opt_iff_dynamic = { "iff-dynamic", "dynamic", OPT_IFF_DYNAMIC, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(short), IFF_DYNAMIC };*/ #ifdef PACKET_AUXDATA -const struct optdesc opt_retrieve_vlan = { "retrieve-vlan", NULL, OPT_RETRIEVE_VLAN, GROUP_INTERFACE, PH_LATE, TYPE_INT, OFUNC_SPEC }; +const struct optdesc opt_retrieve_vlan = { "retrieve-vlan", NULL, OPT_RETRIEVE_VLAN, GROUP_INTERFACE, PH_LATE, TYPE_CONST, OFUNC_SPEC }; #endif #if LATER const struct optdesc opt_route = { "route", NULL, OPT_ROUTE, GROUP_INTERFACE, PH_INIT, TYPE_STRING, OFUNC_SPEC }; diff --git a/xio-ip6.c b/xio-ip6.c index e24d18f..49a18d1 100644 --- a/xio-ip6.c +++ b/xio-ip6.c @@ -612,7 +612,7 @@ int xiotype_ip6_join_source_group( opt->value3.u_string/*srcaddr*/); if (!xioparms.experimental) { - Warn("option ipv6-join-source-group is experimental"); + Warn1("option %s is experimental", opt->desc->defname); } return 0; diff --git a/xio-posixmq.c b/xio-posixmq.c index 78d26fe..c88dba1 100644 --- a/xio-posixmq.c +++ b/xio-posixmq.c @@ -58,6 +58,7 @@ static int xioopen_posixmq( if (!xioparms.experimental) { Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); + return STAT_NORETRY; } if (argc != 2) { Error2("%s: wrong number of parameters (%d instead of 1)", @@ -210,9 +211,11 @@ static int xioopen_posixmq( ; } +#if WITH_RETRY if (with_intv) { Nanosleep(&sfd->intervall, NULL); } +#endif /* now we are ready to handle signals */ Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); diff --git a/xio-socket.c b/xio-socket.c index 26eda94..fff32d3 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -1524,7 +1524,7 @@ int xiodopacketinfo( valbuff, sizeof(valbuff)-1); break; #endif /* WITH_IP6 */ -#if HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA +#if _WITH_INTERFACE && HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA case SOL_PACKET: xiolog_ancillary_packet(sfd, cmsg, &num, typbuff, sizeof(typbuff)-1, nambuff, sizeof(nambuff)-1, diff --git a/xio-socks5.c b/xio-socks5.c index fb85202..30feb23 100644 --- a/xio-socks5.c +++ b/xio-socks5.c @@ -517,12 +517,18 @@ static int xioopen_socks5( char infobuff[256]; if (!xioparms.experimental) { - Error1("%s: requires option --experimental", argv[0]); + Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); return STAT_NORETRY; } if (argc != 5) { - Error1("%s: 4 parameters required like ::::", - argv[0]); +#if WITH_HELP + Error2("%s: 4 parameters required like %s", argv[0], + socks_command==SOCKS5_COMMAND_CONNECT ? + xioaddr_socks5_connect.syntax : + xioaddr_socks5_listen.syntax); +#else + Error1("%s: 4 parameters required", argv[0]); +#endif return STAT_NORETRY; } diff --git a/xio.h b/xio.h index 3c47d64..8d1cb05 100644 --- a/xio.h +++ b/xio.h @@ -95,7 +95,7 @@ enum xiotag { } ; /* Keep condition consistent with xioopts.h:GROUP_*! */ -#if WITH_SCTP +#if WITH_SCTP || WITH_POSIXMQ typedef uint64_t groups_t; #define F_groups_t F_uint64_x #else @@ -327,7 +327,7 @@ typedef union bipipe { enum xiotag tag; const struct addrdesc *addr; int flags; - } common; + } common; /* "bipipe.common" */ struct single stream; struct { enum xiotag tag; diff --git a/xiohelp.c b/xiohelp.c index 1c69cd1..60689e2 100644 --- a/xiohelp.c +++ b/xiohelp.c @@ -14,7 +14,7 @@ /* keep consistent with xioopts.h:enum e_types ! */ static const char *optiontypenames[] = { "CONST", "BIN", "BOOL", "BYTE", - "INT", "LONG", "STRING", "PTRDIFF", + "INT", "INT/NULL", "LONG", "STRING", "PTRDIFF", "SHORT", "SIZE_T", "SOCKADDR", "UNSIGNED-INT", "UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T", "GID_T", "UID_T", "INT[3]", "STRUCT-TIMEVAL", "STRUCT-TIMESPEC", @@ -23,7 +23,6 @@ static const char *optiontypenames[] = { "INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", "INT:INT:GENERIC", "IP4NAME", - #if HAVE_STRUCT_LINGER "STRUCT-LINGER", #endif @@ -49,7 +48,7 @@ static const char *addressgroupnames[] = { "UNIX", "IP4", "IP6", "INTERFACE", "UDP", "TCP", "SOCKS4", "OPENSSL", "PROCESS", "APPL", "HTTP", "undef", - "SCTP" + "SCTP", "POSIXMQ" } ; /* keep consistent with xioopts.h:enum ephase ! */ @@ -66,7 +65,8 @@ static char *optionphasenames[] = { "CONNECTED", "PREFORK", "FORK", "PASTFORK", "LATE", "LATE2", - "PREEXEC", "EXEC", "SPECIFIC", + "PREEXEC", "EXEC", "PASTEXEC", + "SPECIFIC", NULL } ; diff --git a/xioopen.c b/xioopen.c index e466630..eb532ab 100644 --- a/xioopen.c +++ b/xioopen.c @@ -33,7 +33,7 @@ const struct addrname addressnames[] = { { "ABSTRACT-RECVFROM", &xioaddr_abstract_recvfrom }, { "ABSTRACT-SENDTO", &xioaddr_abstract_sendto }, #endif /* defined(WITH_UNIX) && defined(WITH_ABSTRACT_UNIXSOCKET) */ -#if WITH_LISTEN +#if WITH_LISTEN && WITH_FDNUM { "ACCEPT", &xioaddr_accept_fd }, { "ACCEPT-FD", &xioaddr_accept_fd }, #endif diff --git a/xioopts.c b/xioopts.c index 324147a..5aca01f 100644 --- a/xioopts.c +++ b/xioopts.c @@ -309,7 +309,9 @@ const struct optname optionnames[] = { IF_OPENSSL("cert", &opt_openssl_certificate) IF_OPENSSL("certificate", &opt_openssl_certificate) IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw) +#if WITH_LISTEN IF_ANY ("children-shutup", &opt_children_shutup) +#endif IF_ANY ("chroot", &opt_chroot) IF_ANY ("chroot-early", &opt_chroot_early) /*IF_TERMIOS("cibaud", &opt_cibaud)*/ @@ -2593,7 +2595,7 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts, break; #endif -#if HAVE_STRUCT_GROUP_SOURCE_REQ +#if WITH_IP6 && HAVE_STRUCT_GROUP_SOURCE_REQ case TYPE_GROUP_SOURCE_REQ: xiotype_ip6_join_source_group(token, ent, opt); break; @@ -3831,7 +3833,7 @@ int applyopt( #if _WITH_INTERFACE case OPT_RETRIEVE_VLAN: if (!xioparms.experimental) { - Warn("option retrieve-vlan is experimental"); + Warn1("option %s is experimental", opt->desc->defname); } if (_interface_setsockopt_auxdata(fd, 1) < 0) { return -1; @@ -3953,8 +3955,8 @@ int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to) { int applyopts_optgroup( int fd, struct opt *opts, - unsigned int from, /* -1: from first phase, not in order */ - unsigned int to, /* -1: to last phase, not in order */ + int from, /* -1: from first phase, not in order */ + int to, /* -1: to last phase, not in order */ groups_t groups) { struct opt *opt = opts; diff --git a/xioopts.h b/xioopts.h index f03f204..7211322 100644 --- a/xioopts.h +++ b/xioopts.h @@ -24,11 +24,10 @@ enum e_types { TYPE_CONST, /* keyword means a fix value - implies int type */ TYPE_BIN, /* raw binary data, length determined by data */ TYPE_BOOL, /* value is 0 or 1 (no-value is interpreted as 1) */ - TYPE_BOOL_NULL, /* value is 0 or 1 (no-value is interpreted as 1), or just opt= */ TYPE_BYTE, /* unsigned char */ TYPE_INT, /* int */ - TYPE_INT_NULL, /* int, or opt= for no action (instead of default) */ + TYPE_INT_NULL, /* int, or just opt= for no action (instead of default) */ TYPE_LONG, /* long */ TYPE_STRING, /* char * */ TYPE_NAME = TYPE_STRING, @@ -152,7 +151,6 @@ enum e_func { #define GROUP_FILE GROUP_REG #define GROUP_SOCKET 0x00000020 #define GROUP_READLINE 0x00000040 -#define GROUP_POSIXMQ 0x00000080 #define GROUP_NAMED 0x00000100 /* file system entry */ #define GROUP_OPEN 0x00000200 /* flags for open() */ @@ -186,12 +184,15 @@ enum e_func { #define GROUP_HTTP 0x40000000 /* any HTTP client */ /* Keep condition consistent with xio.h:groups_t! */ -#if WITH_SCTP +#if WITH_SCTP || WITH_POSIXMQ /* The following groups are not expected on systems without uint64_t */ +/* The following groups are not expected on systems withous uint64_t */ #define GROUP_IP_SCTP 0x0100000000U +#define GROUP_POSIXMQ 0x0200000000U #define GROUP_ALL 0x03ffffffffU #else #define GROUP_IP_SCTP 0 +#define GROUP_POSIXMQ 0 #define GROUP_ALL 0xffffffffU #endif @@ -902,34 +903,44 @@ enum e_phase { PH_OFFSET, /* automatically applied to xio-fd */ PH_INIT, /* retrieving info from original state */ PH_EARLY, /* before any other processing */ + PH_PREOPEN, /* before file descriptor is created/opened */ PH_OPEN, /* during filesystem entry creation/open */ PH_PASTOPEN, /* past filesystem entry creation/open */ + PH_PRESOCKET, /* before socket call */ PH_SOCKET, /* for socket call */ PH_PASTSOCKET, /* after socket call */ + PH_PREBIGEN, /* before socketpair() pipe() openpty() */ PH_BIGEN, /* during socketpair() pipe() openpty() */ PH_PASTBIGEN, /* past socketpair() pipe() openpty() */ PH_FD, /* soon after FD creation or identification */ + PH_PREBIND, /* before socket bind() */ PH_BIND, /* during socket bind() ? */ PH_PASTBIND, /* past socket bind() - for client and server sockets! */ + PH_PRELISTEN, /* before socket listen() */ PH_LISTEN, /* during socket listen() ? */ PH_PASTLISTEN, /* after socket listen() */ + PH_PRECONNECT, /* before socket connect() */ PH_CONNECT, /* during socket connect() ? */ PH_PASTCONNECT, /* after socket connect() */ + PH_PREACCEPT, /* before socket accept() */ PH_ACCEPT, /* during socket accept() ? */ PH_PASTACCEPT, /* after socket accept() */ PH_CONNECTED, /* for sockets, after connect() or accept() */ + PH_PREFORK, /* before fork() (with both listen and exec!) */ PH_FORK, /* during fork() (with both listen and exec!) */ PH_PASTFORK, /* after fork() (with both listen and exec!) */ + PH_LATE, /* FD is ready, before start of data loop */ PH_LATE2, /* FD is ready, dropping privileges */ + PH_PREEXEC, /* before exec() or system() */ PH_EXEC, /* during exec() or system() */ PH_PASTEXEC, /* only reached on addresses that do NOT exec() */ @@ -971,7 +982,7 @@ extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *resu extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, const int ai_flags[2]); extern int applyopts(int fd, struct opt *opts, enum e_phase phase); extern int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to); -extern int applyopts_optgroup(int fd, struct opt *opts, unsigned int from, unsigned int to, groups_t groups); +extern int applyopts_optgroup(int fd, struct opt *opts, int from, int to, groups_t groups); extern int applyopts_flags(struct opt *opts, groups_t group, flags_t *result); extern int applyopts_cloexec(int fd, struct opt *opts); extern int applyopts_early(const char *path, struct opt *opts); diff --git a/xioshutdown.c b/xioshutdown.c index 2175916..1e8e3d0 100644 --- a/xioshutdown.c +++ b/xioshutdown.c @@ -72,6 +72,7 @@ int xioshutdown(xiofile_t *sock, int how) { return 0; #if _WITH_SOCKET case XIOSHUT_NULL: + writenull = '\0'; /* assign something to make gcc happy */ /* send an empty packet; only useful on datagram sockets? */ xiowrite(sock, &writenull, 0); return 0;