Consider:

  $ nc -Nul 127.0.0.1 9911 &
  $ echo blah | nc -Nu 127.0.0.1 9911

That client blocks "forever".  This is because after EOF in stdin,
netcat still waits for a HUP from the remote end of the socket, but this
will only work for streams not for datagrams.  It would be nice if this
didn't block so that one could easily fire one-off datagram messages
from scripts, for example.

The tentative patch below adds an "A" flag to avoid reading from the
socket.  It should apply to "current".

Using it prevents the program from blocking indefinitely when polling
for a datagram socket for which the remote end does not reply and/or
simply closes.

TODO: Should still bind a client UNIX datagram socket when this option
is used?  (If no, this flag should conflict with "s".)

diff --git nc.1 nc.1
index 6bdfe4f..5eedccc 100644
--- nc.1
+++ nc.1
@@ -33,7 +33,7 @@
 .Nd arbitrary TCP and UDP connections and listens
 .Sh SYNOPSIS
 .Nm nc
-.Op Fl 46cDdFhklNnrStUuvz
+.Op Fl 46AcDdFhklNnrStUuvz
 .Op Fl C Ar certfile
 .Op Fl e Ar name
 .Op Fl H Ar hash
@@ -99,6 +99,10 @@ The options are as follows:
 Use IPv4 addresses only.
 .It Fl 6
 Use IPv6 addresses only.
+.It Fl A
+Do not attempt to read from the socket.  Useful in combination with
+.Fl u
+to send one-off datagram messages without waiting for a answer.
 .It Fl C Ar certfile
 Load the public key part of the TLS peer certificate from
 .Ar certfile ,
diff --git netcat.c netcat.c
index c04298f..0a0b671 100644
--- netcat.c
+++ netcat.c
@@ -74,6 +74,7 @@
 #define TLS_MUSTSTAPLE (1 << 4)
 
 /* Command Line Options */
+int    Aflag;                                  /* don't read from socket */
 int    dflag;                                  /* detached, no stdin */
 int    Fflag;                                  /* fdpass sock to stdout */
 unsigned int iflag;                            /* Interval Flag */
@@ -173,7 +174,7 @@ main(int argc, char *argv[])
        signal(SIGPIPE, SIG_IGN);
 
        while ((ch = getopt(argc, argv,
-           "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
+           "46AC:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z"))
            != -1) {
                switch (ch) {
                case '4':
@@ -195,6 +196,9 @@ main(int argc, char *argv[])
                        else
                                errx(1, "unsupported proxy protocol");
                        break;
+               case 'A':
+                       Aflag = 1;
+                       break;
                case 'C':
                        Cflag = optarg;
                        break;
@@ -1093,7 +1097,8 @@ readwrite(int net_fd, struct tls *tls_ctx)
        pfd[POLL_NETOUT].events = 0;
 
        /* network in */
-       pfd[POLL_NETIN].fd = net_fd;
+       /* don't read from socket if requested */
+       pfd[POLL_NETIN].fd = Aflag ? -1 : net_fd;
        pfd[POLL_NETIN].events = POLLIN;
 
        /* stdout */

Reply via email to