summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2015-03-08 06:06:19 +0200
committerArnold D. Robbins <arnold@skeeve.com>2015-03-08 06:06:19 +0200
commitb108a3ba2ab12dd7274589c6fe09c882df02827c (patch)
treeacc493b1eb37c9e9a3144e388aa341b20fbb6a3d
parentb8ba9836e05eb96daeed9614f045f5b81a826730 (diff)
downloadgawk-b108a3ba2ab12dd7274589c6fe09c882df02827c.tar.gz
Make nonfatal override GAWK_SOCK_RETRIES. Document it.
-rw-r--r--ChangeLog8
-rw-r--r--doc/ChangeLog6
-rw-r--r--doc/gawktexi.in10
-rw-r--r--io.c43
4 files changed, 51 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 62777ab3..cc15ccbf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-03-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * io.c (devopen): Change the logic such that if nonfatal is true
+ for the socket, don't do retries. Also clean up the formatting
+ some. At strictopen, check if errno is ENOENT and if so, propagate
+ the error from getaddrinfo() up to the caller. Add explanatory
+ comments.
+
2015-02-28 Andrew J. Schorr <aschorr@telemetry-investments.com>
* io.c (pty_vs_pipe): Remove check for NULL PROCINFO_node, since
diff --git a/doc/ChangeLog b/doc/ChangeLog
index d8c42cb4..b58699a4 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-08 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Briefly describe that nonfatal I/O overrides
+ GAWK_SOCK_RETRIES, in the env var part and in the nonfatal I/O
+ part.
+
2015-03-01 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in: Change quotes to @dfn for pseudorandom.
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index 1b99b5bc..8612876e 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -4461,6 +4461,8 @@ wait for input before returning with an error.
Controls the number of times @command{gawk} attempts to
retry a two-way TCP/IP (socket) connection before giving up.
@xref{TCP/IP Networking}.
+Note that when nonfatal I/O is enabled (@pxref{Nonfatal}),
+@command{gawk} only tries to open a TCP/IP socket once.
@item POSIXLY_CORRECT
Causes @command{gawk} to switch to POSIX-compatibility
@@ -9996,6 +9998,14 @@ For standard output, you may use @code{PROCINFO["-", "NONFATAL"]}
or @code{PROCINFO["/dev/stdout", "NONFATAL"]}. For standard error, use
@code{PROCINFO["/dev/stderr", "NONFATAL"]}.
+When attempting to open a TCP/IP socket (@pxref{TCP/IP Networking}),
+@command{gawk} tries multiple times. The @env{GAWK_SOCK_RETRIES}
+environment variable (@pxref{Other Environment Variables}) allows you to
+override @command{gawk}'s builtin default number of attempts. However,
+once nonfatal I/O is enabled for a given socket, @command{gawk} only
+retries once, relying on @command{awk}-level code to notice that there
+was a problem.
+
@node Output Summary
@section Summary
diff --git a/io.c b/io.c
index 162fb4e8..55c5d3a5 100644
--- a/io.c
+++ b/io.c
@@ -1661,20 +1661,20 @@ devopen(const char *name, const char *mode)
goto strictopen;
} else if (inetfile(name, & isi)) {
#ifdef HAVE_SOCKETS
- cp = (char *) name;
-
- /* socketopen requires NUL-terminated strings */
- cp[isi.localport.offset+isi.localport.len] = '\0';
- cp[isi.remotehost.offset+isi.remotehost.len] = '\0';
- /* remoteport comes last, so already NUL-terminated */
-
- {
#define DEFAULT_RETRIES 20
static unsigned long def_retries = DEFAULT_RETRIES;
static bool first_time = true;
unsigned long retries = 0;
static long msleep = 1000;
bool hard_error = false;
+ bool non_fatal = is_non_fatal_redirect(name);
+
+ cp = (char *) name;
+
+ /* socketopen requires NUL-terminated strings */
+ cp[isi.localport.offset+isi.localport.len] = '\0';
+ cp[isi.remotehost.offset+isi.remotehost.len] = '\0';
+ /* remoteport comes last, so already NUL-terminated */
if (first_time) {
char *cp, *end;
@@ -1701,28 +1701,39 @@ devopen(const char *name, const char *mode)
msleep *= 1000;
}
}
- retries = def_retries;
+ /*
+ * PROCINFO["NONFATAL"] or PROCINFO[name, "NONFATAL"] overrrides
+ * GAWK_SOCK_RETRIES. The explicit code in the program carries
+ * a bigger stick than the environment variable does.
+ */
+ retries = non_fatal ? 1 : def_retries;
errno = 0;
do {
- openfd = socketopen(isi.family, isi.protocol, name+isi.localport.offset, name+isi.remoteport.offset, name+isi.remotehost.offset, & hard_error);
+ openfd = socketopen(isi.family, isi.protocol, name+isi.localport.offset,
+ name+isi.remoteport.offset, name+isi.remotehost.offset,
+ & hard_error);
retries--;
} while (openfd == INVALID_HANDLE && ! hard_error && retries > 0 && usleep(msleep) == 0);
save_errno = errno;
- }
- /* restore original name string */
- cp[isi.localport.offset+isi.localport.len] = '/';
- cp[isi.remotehost.offset+isi.remotehost.len] = '/';
+ /* restore original name string */
+ cp[isi.localport.offset+isi.localport.len] = '/';
+ cp[isi.remotehost.offset+isi.remotehost.len] = '/';
#else /* ! HAVE_SOCKETS */
- fatal(_("TCP/IP communications are not supported"));
+ fatal(_("TCP/IP communications are not supported"));
#endif /* HAVE_SOCKETS */
}
strictopen:
if (openfd == INVALID_HANDLE) {
openfd = open(name, flag, 0666);
- if (openfd == INVALID_HANDLE && save_errno)
+ /*
+ * ENOENT means there is no such name in the filesystem.
+ * Therefore it's ok to propagate up the error from
+ * getaddrinfo() that's in save_errno.
+ */
+ if (openfd == INVALID_HANDLE && errno == ENOENT && save_errno)
errno = save_errno;
}
#if defined(__EMX__) || defined(__MINGW32__)