Skip to content

Commit ee24ce9

Browse files
committed
unix: return actual error from uv_try_write()
So far, for some (?) errors, `uv_try_write()` returns `EAGAIN` regardless of the actual error, so `ECONNRESET` and `EPIPE` errors can be swallowed here. This commit changes `uv_try_write()` so that it prefers to return the actual error it has seen. PR-URL: #2321 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Santiago Gimeno <[email protected]>
1 parent 9a10058 commit ee24ce9

6 files changed

Lines changed: 115 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ set(uv_test_sources
137137
test/test-tcp-read-stop.c
138138
test/test-tcp-shutdown-after-write.c
139139
test/test-tcp-try-write.c
140+
test/test-tcp-try-write-error.c
140141
test/test-tcp-unexpected-read.c
141142
test/test-tcp-write-after-connect.c
142143
test/test-tcp-write-fail.c

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
272272
test/test-tcp-writealot.c \
273273
test/test-tcp-write-fail.c \
274274
test/test-tcp-try-write.c \
275+
test/test-tcp-try-write-error.c \
275276
test/test-tcp-write-queue-order.c \
276277
test/test-thread-equal.c \
277278
test/test-thread.c \

src/unix/stream.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1541,7 +1541,7 @@ int uv_try_write(uv_stream_t* stream,
15411541
}
15421542

15431543
if (written == 0 && req_size != 0)
1544-
return UV_EAGAIN;
1544+
return req.error < 0 ? req.error : UV_EAGAIN;
15451545
else
15461546
return written;
15471547
}

test/test-list.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ TEST_DECLARE (tcp_write_after_connect)
9191
TEST_DECLARE (tcp_writealot)
9292
TEST_DECLARE (tcp_write_fail)
9393
TEST_DECLARE (tcp_try_write)
94+
TEST_DECLARE (tcp_try_write_error)
9495
TEST_DECLARE (tcp_write_queue_order)
9596
TEST_DECLARE (tcp_open)
9697
TEST_DECLARE (tcp_open_twice)
@@ -582,6 +583,7 @@ TASK_LIST_START
582583
TEST_HELPER (tcp_write_fail, tcp4_echo_server)
583584

584585
TEST_ENTRY (tcp_try_write)
586+
TEST_ENTRY (tcp_try_write_error)
585587

586588
TEST_ENTRY (tcp_write_queue_order)
587589

test/test-tcp-try-write-error.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* Copyright libuv contributors. All rights reserved.
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to
5+
* deal in the Software without restriction, including without limitation the
6+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
* sell copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19+
* IN THE SOFTWARE.
20+
*/
21+
22+
#include "uv.h"
23+
#include "task.h"
24+
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
#include <string.h>
28+
29+
static uv_tcp_t server;
30+
static uv_tcp_t client;
31+
static uv_tcp_t incoming;
32+
static int connect_cb_called;
33+
static int close_cb_called;
34+
static int connection_cb_called;
35+
36+
37+
static void close_cb(uv_handle_t* handle) {
38+
close_cb_called++;
39+
}
40+
41+
static void incoming_close_cb(uv_handle_t* handle) {
42+
uv_buf_t buf;
43+
int r = 1;
44+
45+
close_cb_called++;
46+
47+
buf = uv_buf_init("meow", 4);
48+
while (r > 0)
49+
r = uv_try_write((uv_stream_t*) &client, &buf, 1);
50+
fprintf(stderr, "uv_try_write error: %d %s\n", r, uv_strerror(r));
51+
ASSERT(r == UV_EPIPE || r == UV_ECONNABORTED);
52+
ASSERT(client.write_queue_size == 0);
53+
}
54+
55+
56+
static void connect_cb(uv_connect_t* req, int status) {
57+
ASSERT(status == 0);
58+
connect_cb_called++;
59+
}
60+
61+
62+
static void connection_cb(uv_stream_t* tcp, int status) {
63+
ASSERT(status == 0);
64+
65+
ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
66+
ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
67+
68+
connection_cb_called++;
69+
uv_close((uv_handle_t*) &incoming, incoming_close_cb);
70+
uv_close((uv_handle_t*) tcp, close_cb);
71+
}
72+
73+
74+
static void start_server(void) {
75+
struct sockaddr_in addr;
76+
77+
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
78+
79+
ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
80+
ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));
81+
ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
82+
}
83+
84+
85+
TEST_IMPL(tcp_try_write_error) {
86+
uv_connect_t connect_req;
87+
struct sockaddr_in addr;
88+
89+
start_server();
90+
91+
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
92+
93+
ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
94+
ASSERT(0 == uv_tcp_connect(&connect_req,
95+
&client,
96+
(struct sockaddr*) &addr,
97+
connect_cb));
98+
99+
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
100+
uv_close((uv_handle_t*) &client, close_cb);
101+
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
102+
103+
ASSERT(connect_cb_called == 1);
104+
ASSERT(close_cb_called == 3);
105+
ASSERT(connection_cb_called == 1);
106+
107+
MAKE_VALGRIND_HAPPY();
108+
return 0;
109+
}

test/test.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
'test-tcp-writealot.c',
121121
'test-tcp-write-fail.c',
122122
'test-tcp-try-write.c',
123+
'test-tcp-try-write-error.c',
123124
'test-tcp-unexpected-read.c',
124125
'test-tcp-oob.c',
125126
'test-tcp-read-stop.c',

0 commit comments

Comments
 (0)