aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch')
-rw-r--r--meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch62
1 files changed, 62 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch b/meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch
new file mode 100644
index 00000000000..b5ac62f6169
--- /dev/null
+++ b/meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch
@@ -0,0 +1,62 @@
+From 956d4b00a101f61b4cfaafa0856b646646536492 Mon Sep 17 00:00:00 2001
+From: Mark Asselstine <asselsm@gmail.com>
+Date: Mon, 7 Dec 2015 21:27:35 -0500
+Subject: [PATCH] Exit when the file associated with an FD is destroyed
+
+In many scenarios the receipt of an EOF will coincide with the
+teardown of the file which the FD is associated with by the
+application on the other side of the file pipe. If a timeout (-t) is
+used socat continues to poll for new data (read) and send any new data
+(write) until the timeout. This can lead to input/output errors as the
+FD exists still but the file it was openned on is gone, and no check
+is done on writes.
+
+To get around this a check is added after the EOF is received that the
+file still exists, and if not we proceed to exit immediately. This
+will avoid i/o errors and will also cause a quicker return as we don't
+have to wait for the timeout.
+
+Signed-off-by: Mark Asselstine <asselsm@gmail.com>
+
+Upstream-Status: Submitted [socat@dest-unreach.org]
+
+Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
+
+---
+ socat.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/socat.c b/socat.c
+index b619a3d..de4a14b 100644
+--- a/socat.c
++++ b/socat.c
+@@ -773,6 +773,7 @@ int _socat(void) {
+ int polling = 0; /* handling ignoreeof */
+ int wasaction = 1; /* last poll was active, do NOT sleep before next */
+ struct timeval total_timeout; /* the actual total timeout timer */
++ struct stat file_stat;
+
+ #if WITH_FILAN
+ if (socat_opts.debug) {
+@@ -1123,6 +1124,10 @@ int _socat(void) {
+ xioshutdown(sock2, SHUT_WR);
+ XIO_RDSTREAM(sock1)->eof = 3;
+ XIO_RDSTREAM(sock1)->ignoreeof = false;
++ if (fstat(XIO_GETRDFD(sock1), &file_stat) == -1 || file_stat.st_nlink == 0) {
++ Notice1("socket 1 (fd %d) is gone", XIO_GETRDFD(sock1));
++ break;
++ }
+ }
+ } else if (polling && XIO_RDSTREAM(sock1)->ignoreeof) {
+ polling = 0;
+@@ -1146,6 +1151,10 @@ int _socat(void) {
+ xioshutdown(sock1, SHUT_WR);
+ XIO_RDSTREAM(sock2)->eof = 3;
+ XIO_RDSTREAM(sock2)->ignoreeof = false;
++ if (fstat(XIO_GETRDFD(sock2), &file_stat) == -1 || file_stat.st_nlink == 0) {
++ Notice1("socket 2 (fd %d) is gone", XIO_GETRDFD(sock2));
++ break;
++ }
+ }
+ } else if (polling && XIO_RDSTREAM(sock2)->ignoreeof) {
+ polling = 0;