diff --git a/CHANGES b/CHANGES index 14ac8eb..bcee6cc 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,11 @@ corrections: Option so-reuseport did not work. Thanks to Some Raghavendra Prabhu for sending a patch. + Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout + incorrectly assigned + Test: EXEC_NOFORK_UNIDIR + Thanks to David Reiss for reporting this problem. + porting: Type conflict between int and sig_atomic_t between declaration and definition of diag_immediate_type and diag_immediate_exit broke diff --git a/test.sh b/test.sh index 75194af..66c4995 100755 --- a/test.sh +++ b/test.sh @@ -12383,6 +12383,39 @@ fi # NUMCOND, SO_REUSEPORT ;; esac PORT=$((PORT+1)) + + +# Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped. +NAME=EXEC_NOFORK_UNIDIR +case "$TESTS" in +*%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*) +TEST="$NAME: Programs invoked with EXEC, nofork, and -u or -U had stdin and stdout assignment swapped" +# invoke a simple echo command with EXEC, nofork, and -u +# expected behaviour: output appears on stdout +if ! eval $NUMCOND; then :; 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 -u /dev/null EXEC:\"echo \\\"$da\\\"\",nofork" +printf "test $F_n $TEST... " $N +eval $CMD0 >"${tf}0" 2>"${te}0" +rc1=$? +if echo "$da" |diff - "${tf}0" >"$tdiff"; then + $PRINTF "$OK\n" + numOK=$((numOK+1)) +else + $PRINTF "$FAILED\n" + echo "$CMD0" + cat "${te}0" + cat "$tdiff" + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +fi +fi # NUMCOND + ;; +esac +#PORT=$((PORT+1)) N=$((N+1)) diff --git a/xio-progcall.c b/xio-progcall.c index 1ad91b0..2ee7721 100644 --- a/xio-progcall.c +++ b/xio-progcall.c @@ -168,40 +168,32 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */ } #endif + /* remember: fdin is the fs where the sub program reads from, thus it is + sock0[]'s read fd */ /*! problem: when fdi==WRFD(sock[0]) or fdo==RDFD(sock[0]) */ if (rw != XIO_WRONLY) { - if (XIO_GETRDFD(sock[0]/*!!*/) == fdi) { - if (Fcntl_l(fdi, F_SETFD, 0) < 0) { - Warn2("fcntl(%d, F_SETFD, 0): %s", fdi, strerror(errno)); - } - if (Dup2(XIO_GETRDFD(sock[0]), fdi) < 0) { - Error3("dup2(%d, %d): %s", - XIO_GETRDFD(sock[0]), fdi, strerror(errno)); - } - /*0 Info2("dup2(%d, %d)", XIO_GETRDFD(sock[0]), fdi);*/ - } else { - if (Dup2(XIO_GETRDFD(sock[0]), fdi) < 0) { - Error3("dup2(%d, %d): %s", - XIO_GETRDFD(sock[0]), fdi, strerror(errno)); - } - /*0 Info2("dup2(%d, %d)", XIO_GETRDFD(sock[0]), fdi);*/ - } - } - if (rw != XIO_RDONLY) { - if (XIO_GETWRFD(sock[0]) == fdo) { + if (XIO_GETWRFD(sock[0]/*!!*/) == fdo) { if (Fcntl_l(fdo, F_SETFD, 0) < 0) { Warn2("fcntl(%d, F_SETFD, 0): %s", fdo, strerror(errno)); } - if (Dup2(XIO_GETWRFD(sock[0]), fdo) < 0) { - Error3("dup2(%d, %d): %s)", - XIO_GETWRFD(sock[0]), fdo, strerror(errno)); - } - /*0 Info2("dup2(%d, %d)", XIO_GETWRFD(sock[0]), fdo);*/ } else { if (Dup2(XIO_GETWRFD(sock[0]), fdo) < 0) { - Error3("dup2(%d, %d): %s)", + Error3("dup2(%d, %d): %s", XIO_GETWRFD(sock[0]), fdo, strerror(errno)); } + } + /*0 Info2("dup2(%d, %d)", XIO_GETRDFD(sock[0]), fdi);*/ + } + if (rw != XIO_RDONLY) { + if (XIO_GETRDFD(sock[0]) == fdi) { + if (Fcntl_l(fdi, F_SETFD, 0) < 0) { + Warn2("fcntl(%d, F_SETFD, 0): %s", fdi, strerror(errno)); + } + } else { + if (Dup2(XIO_GETRDFD(sock[0]), fdi) < 0) { + Error3("dup2(%d, %d): %s)", + XIO_GETRDFD(sock[0]), fdi, strerror(errno)); + } /*0 Info2("dup2(%d, %d)", XIO_GETWRFD(sock[0]), fdo);*/ } } diff --git a/xioopen.c b/xioopen.c index 7f55227..dbb6568 100644 --- a/xioopen.c +++ b/xioopen.c @@ -352,12 +352,6 @@ static xiofile_t *xioallocfd(void) { /* fd->stream.para.exec.pid = 0; */ fd->stream.lineterm = LINETERM_RAW; - /*!! support n socks */ - if (!sock[0]) { - sock[0] = fd; - } else { - sock[1] = fd; - } return fd; } @@ -376,6 +370,12 @@ xiofile_t *xioopen(const char *addr, /* address specification */ if ((xfd = xioparse_dual(&addr)) == NULL) { return NULL; } + /*!! support n socks */ + if (!sock[0]) { + sock[0] = xfd; + } else { + sock[1] = xfd; + } if (xioopen_dual(xfd, xioflags) < 0) { /*!!! free something? */ return NULL;