summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/socat/files/Exit-when-the-file-associated-with-an-FD-is-destroye.patch
blob: b5ac62f6169b627616452923eed1e5d935345ba5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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;