diff --git a/CHANGES b/CHANGES index fc3d98f..a0d9d83 100644 --- a/CHANGES +++ b/CHANGES @@ -95,6 +95,11 @@ Testing: * do not use sort -V * renamed testaddrs() to testfeats(), and introduced new testaddrs() +New features: + GOPEN and UNIX-CLIENT addresses now support sockets of type SEQPACKET. + Test: GOPENUNIXSEQPACKET + Feature suggested by vi0oss. + ####################### V 1.7.3.4: Corrections: diff --git a/test.sh b/test.sh index 7a63352..c05ef34 100755 --- a/test.sh +++ b/test.sh @@ -3772,6 +3772,58 @@ fi # NUMCOND esac N=$((N+1)) +NAME=GOPENUNIXSEQPACKET +case "$TESTS" in +*%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%seqpacket%*|*%$NAME%*) +TEST="$NAME: GOPEN on UNIX seqpacket socket" +if ! eval $NUMCOND; then :; else + case "$UNAME" in + SunOS) SOCK_SEQPACKET=6 ;; + *) SOCK_SEQPACKET=5 ;; + esac +ts="$td/test$N.socket" +tf="$td/test$N.stdout" +te="$td/test$N.stderr" +tdiff="$td/test$N.diff" +da1="test$N $(date) $RANDOM" +#establish a listening unix socket in background +SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\",so-type=$SOCK_SEQPACKET PIPE" +#make a connection +CMD="$TRACE $SOCAT $opts - $ts" +$PRINTF "test $F_n $TEST... " $N +eval "$SRV 2>${te}s &" +pids=$! +waitfile "$ts" +echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1" +if [ $? -ne 0 ]; then + kill "$pids" 2>/dev/null + $PRINTF "$FAILED:\n" + echo "$SRV &" + cat "${te}s" + echo "$CMD" + cat "${te}1" + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then + kill "$pids" 2>/dev/null + $PRINTF "$FAILED:\n" + echo "$SRV &" + cat "${te}s" + echo "$CMD" + cat "${te}1" + cat "$tdiff" + numFAIL=$((numFAIL+1)) + listFAIL="$listFAIL $N" +else + $PRINTF "$OK\n" + if [ -n "$debug" ]; then cat $te; fi + numOK=$((numOK+1)) +fi # !(rc -ne 0) +wait +fi # NUMCOND +esac +N=$((N+1)) + NAME=GOPENUNIXDGRAM case "$TESTS" in diff --git a/xio-unix.c b/xio-unix.c index 0c1dead..0dfd93a 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -541,6 +541,8 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY; applyopts(-1, opts, PH_INIT); applyopts_offset(xfd, opts); + retropt_int(opts, OPT_SO_TYPE, &socktype); + retropt_int(opts, OPT_SO_PROTOTYPE, &protocol); applyopts(-1, opts, PH_EARLY); themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight); @@ -569,32 +571,56 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups, /* save options, because we might have to start again */ opts0 = copyopts(opts, GROUP_ALL); - /* xfd->dtype = DATA_STREAM; // is default */ - if ((result = + /* just a breakable block, helps to avoid goto */ + do { + /* xfd->dtype = DATA_STREAM; // is default */ + /* this function handles AF_UNIX with EPROTOTYPE specially for us */ + if ((result = xioopen_connect(xfd, needbind?&us:NULL, uslen, &them.soa, themlen, opts, pf, socktype?socktype:SOCK_STREAM, protocol, - false)) != 0) { - if (errno == EPROTOTYPE) { - if (needbind) { - Unlink(us.un.sun_path); - } + false)) == 0) + break; + if (errno != EPROTOTYPE || socktype != 0) + break; + if (needbind) + Unlink(us.un.sun_path); + dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; - dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; + socktype = SOCK_SEQPACKET; + if ((result = + xioopen_connect(xfd, + needbind?&us:NULL, uslen, + (struct sockaddr *)&them, themlen, + opts, pf, SOCK_SEQPACKET, protocol, + false)) == 0) + break; + if (errno != EPROTOTYPE) + break; + if (needbind) + Unlink(us.un.sun_path); + dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0; - xfd->peersa = them; - xfd->salen = sizeof(struct sockaddr_un); - if ((result = + xfd->peersa = them; + xfd->salen = sizeof(struct sockaddr_un); + if ((result = _xioopen_dgram_sendto(needbind?&us:NULL, uslen, opts, xioflags, xfd, groups, - pf, socktype?socktype:SOCK_DGRAM, protocol)) - != 0) { - return result; - } + pf, SOCK_DGRAM, protocol)) + == 0) { xfd->dtype = XIODATA_RECVFROM; + break; } + } while (0); + + if (result != 0) { + if (needbind) { + Unlink(us.un.sun_path); + } + return result; } + if ((result = _xio_openlate(xfd, opts)) < 0) { return result; }