forked from cory/tildefriends
libuv 1.43.0
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3735 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
1
deps/libuv/test/benchmark-list.h
vendored
1
deps/libuv/test/benchmark-list.h
vendored
@ -81,7 +81,6 @@ HELPER_DECLARE (tcp_pump_server)
|
||||
HELPER_DECLARE (pipe_pump_server)
|
||||
HELPER_DECLARE (tcp4_echo_server)
|
||||
HELPER_DECLARE (pipe_echo_server)
|
||||
HELPER_DECLARE (dns_server)
|
||||
|
||||
TASK_LIST_START
|
||||
BENCHMARK_ENTRY (sizes)
|
||||
|
340
deps/libuv/test/dns-server.c
vendored
340
deps/libuv/test/dns-server.c
vendored
@ -1,340 +0,0 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
uv_write_t req;
|
||||
uv_buf_t buf;
|
||||
} write_req_t;
|
||||
|
||||
|
||||
/* used to track multiple DNS requests received */
|
||||
typedef struct {
|
||||
char* prevbuf_ptr;
|
||||
int prevbuf_pos;
|
||||
int prevbuf_rem;
|
||||
} dnsstate;
|
||||
|
||||
|
||||
/* modify handle to append dnsstate */
|
||||
typedef struct {
|
||||
uv_tcp_t handle;
|
||||
dnsstate state;
|
||||
} dnshandle;
|
||||
|
||||
|
||||
static uv_loop_t* loop;
|
||||
|
||||
|
||||
static uv_tcp_t server;
|
||||
|
||||
|
||||
static void after_write(uv_write_t* req, int status);
|
||||
static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf);
|
||||
static void on_close(uv_handle_t* peer);
|
||||
static void on_connection(uv_stream_t*, int status);
|
||||
|
||||
#define WRITE_BUF_LEN (64*1024)
|
||||
#define DNSREC_LEN (4)
|
||||
|
||||
#define LEN_OFFSET 0
|
||||
#define QUERYID_OFFSET 2
|
||||
|
||||
static unsigned char DNSRsp[] = {
|
||||
0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static unsigned char qrecord[] = {
|
||||
5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1
|
||||
};
|
||||
|
||||
static unsigned char arecord[] = {
|
||||
0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1
|
||||
};
|
||||
|
||||
|
||||
static void after_write(uv_write_t* req, int status) {
|
||||
write_req_t* wr;
|
||||
|
||||
if (status) {
|
||||
fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
wr = (write_req_t*) req;
|
||||
|
||||
/* Free the read/write buffer and the request */
|
||||
free(wr->buf.base);
|
||||
free(wr);
|
||||
}
|
||||
|
||||
|
||||
static void after_shutdown(uv_shutdown_t* req, int status) {
|
||||
uv_close((uv_handle_t*) req->handle, on_close);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void addrsp(write_req_t* wr, char* hdr) {
|
||||
char * dnsrsp;
|
||||
short int rsplen;
|
||||
short int* reclen;
|
||||
|
||||
rsplen = sizeof(DNSRsp) + sizeof(qrecord) + sizeof(arecord);
|
||||
|
||||
ASSERT (rsplen + wr->buf.len < WRITE_BUF_LEN);
|
||||
|
||||
dnsrsp = wr->buf.base + wr->buf.len;
|
||||
|
||||
/* copy stock response */
|
||||
memcpy(dnsrsp, DNSRsp, sizeof(DNSRsp));
|
||||
memcpy(dnsrsp + sizeof(DNSRsp), qrecord, sizeof(qrecord));
|
||||
memcpy(dnsrsp + sizeof(DNSRsp) + sizeof(qrecord), arecord, sizeof(arecord));
|
||||
|
||||
/* overwrite with network order length and id from request header */
|
||||
reclen = (short int*)dnsrsp;
|
||||
*reclen = htons(rsplen-2);
|
||||
dnsrsp[QUERYID_OFFSET] = hdr[QUERYID_OFFSET];
|
||||
dnsrsp[QUERYID_OFFSET+1] = hdr[QUERYID_OFFSET+1];
|
||||
|
||||
wr->buf.len += rsplen;
|
||||
}
|
||||
|
||||
static void process_req(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf) {
|
||||
write_req_t* wr;
|
||||
dnshandle* dns = (dnshandle*)handle;
|
||||
char hdrbuf[DNSREC_LEN];
|
||||
int hdrbuf_remaining = DNSREC_LEN;
|
||||
int rec_remaining = 0;
|
||||
int readbuf_remaining;
|
||||
char* dnsreq;
|
||||
char* hdrstart;
|
||||
int usingprev = 0;
|
||||
|
||||
wr = (write_req_t*) malloc(sizeof *wr);
|
||||
wr->buf.base = (char*)malloc(WRITE_BUF_LEN);
|
||||
wr->buf.len = 0;
|
||||
|
||||
if (dns->state.prevbuf_ptr != NULL) {
|
||||
dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos;
|
||||
readbuf_remaining = dns->state.prevbuf_rem;
|
||||
usingprev = 1;
|
||||
} else {
|
||||
dnsreq = buf->base;
|
||||
readbuf_remaining = nread;
|
||||
}
|
||||
hdrstart = dnsreq;
|
||||
|
||||
while (dnsreq != NULL) {
|
||||
/* something to process */
|
||||
while (readbuf_remaining > 0) {
|
||||
/* something to process in current buffer */
|
||||
if (hdrbuf_remaining > 0) {
|
||||
/* process len and id */
|
||||
if (readbuf_remaining < hdrbuf_remaining) {
|
||||
/* too little to get request header. save for next buffer */
|
||||
memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining],
|
||||
dnsreq,
|
||||
readbuf_remaining);
|
||||
hdrbuf_remaining = DNSREC_LEN - readbuf_remaining;
|
||||
break;
|
||||
} else {
|
||||
/* save header */
|
||||
memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining],
|
||||
dnsreq,
|
||||
hdrbuf_remaining);
|
||||
dnsreq += hdrbuf_remaining;
|
||||
readbuf_remaining -= hdrbuf_remaining;
|
||||
hdrbuf_remaining = 0;
|
||||
|
||||
/* get record length */
|
||||
rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1];
|
||||
rec_remaining -= (DNSREC_LEN - 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (rec_remaining <= readbuf_remaining) {
|
||||
/* prepare reply */
|
||||
addrsp(wr, hdrbuf);
|
||||
|
||||
/* move to next record */
|
||||
dnsreq += rec_remaining;
|
||||
hdrstart = dnsreq;
|
||||
readbuf_remaining -= rec_remaining;
|
||||
rec_remaining = 0;
|
||||
hdrbuf_remaining = DNSREC_LEN;
|
||||
} else {
|
||||
/* otherwise this buffer is done. */
|
||||
rec_remaining -= readbuf_remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we had to use bytes from prev buffer, start processing the current
|
||||
* one.
|
||||
*/
|
||||
if (usingprev == 1) {
|
||||
/* free previous buffer */
|
||||
free(dns->state.prevbuf_ptr);
|
||||
dnsreq = buf->base;
|
||||
readbuf_remaining = nread;
|
||||
usingprev = 0;
|
||||
} else {
|
||||
dnsreq = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* send write buffer */
|
||||
if (wr->buf.len > 0) {
|
||||
if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
}
|
||||
|
||||
if (readbuf_remaining > 0) {
|
||||
/* save start of record position, so we can continue on next read */
|
||||
dns->state.prevbuf_ptr = buf->base;
|
||||
dns->state.prevbuf_pos = hdrstart - buf->base;
|
||||
dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos;
|
||||
} else {
|
||||
/* nothing left in this buffer */
|
||||
dns->state.prevbuf_ptr = NULL;
|
||||
dns->state.prevbuf_pos = 0;
|
||||
dns->state.prevbuf_rem = 0;
|
||||
free(buf->base);
|
||||
}
|
||||
}
|
||||
|
||||
static void after_read(uv_stream_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* buf) {
|
||||
uv_shutdown_t* req;
|
||||
|
||||
if (nread < 0) {
|
||||
/* Error or EOF */
|
||||
ASSERT(nread == UV_EOF);
|
||||
|
||||
if (buf->base) {
|
||||
free(buf->base);
|
||||
}
|
||||
|
||||
req = malloc(sizeof *req);
|
||||
uv_shutdown(req, handle, after_shutdown);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nread == 0) {
|
||||
/* Everything OK, but nothing read. */
|
||||
free(buf->base);
|
||||
return;
|
||||
}
|
||||
/* process requests and send responses */
|
||||
process_req(handle, nread, buf);
|
||||
}
|
||||
|
||||
|
||||
static void on_close(uv_handle_t* peer) {
|
||||
free(peer);
|
||||
}
|
||||
|
||||
|
||||
static void buf_alloc(uv_handle_t* handle,
|
||||
size_t suggested_size,
|
||||
uv_buf_t* buf) {
|
||||
buf->base = malloc(suggested_size);
|
||||
buf->len = suggested_size;
|
||||
}
|
||||
|
||||
|
||||
static void on_connection(uv_stream_t* server, int status) {
|
||||
dnshandle* handle;
|
||||
int r;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
handle = (dnshandle*) malloc(sizeof *handle);
|
||||
ASSERT_NOT_NULL(handle);
|
||||
|
||||
/* initialize read buffer state */
|
||||
handle->state.prevbuf_ptr = 0;
|
||||
handle->state.prevbuf_pos = 0;
|
||||
handle->state.prevbuf_rem = 0;
|
||||
|
||||
r = uv_tcp_init(loop, (uv_tcp_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_accept(server, (uv_stream_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static int dns_start(int port) {
|
||||
struct sockaddr_in addr;
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr));
|
||||
|
||||
r = uv_tcp_init(loop, &server);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Socket creation error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Bind error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_listen((uv_stream_t*)&server, 128, on_connection);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Listen error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HELPER_IMPL(dns_server) {
|
||||
loop = uv_default_loop();
|
||||
|
||||
if (dns_start(TEST_PORT_2))
|
||||
return 1;
|
||||
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
return 0;
|
||||
}
|
2
deps/libuv/test/task.h
vendored
2
deps/libuv/test/task.h
vendored
@ -277,7 +277,7 @@ const char* fmt(double d);
|
||||
/* Reserved test exit codes. */
|
||||
enum test_status {
|
||||
TEST_OK = 0,
|
||||
TEST_SKIP
|
||||
TEST_SKIP = 7
|
||||
};
|
||||
|
||||
#define RETURN_OK() \
|
||||
|
3
deps/libuv/test/test-fs-copyfile.c
vendored
3
deps/libuv/test/test-fs-copyfile.c
vendored
@ -96,9 +96,6 @@ static void touch_file(const char* name, unsigned int size) {
|
||||
|
||||
|
||||
TEST_IMPL(fs_copyfile) {
|
||||
#if defined(__ASAN__)
|
||||
RETURN_SKIP("Test does not currently work in ASAN");
|
||||
#endif
|
||||
const char src[] = "test_file_src";
|
||||
uv_loop_t* loop;
|
||||
uv_fs_t req;
|
||||
|
52
deps/libuv/test/test-fs-event.c
vendored
52
deps/libuv/test/test-fs-event.c
vendored
@ -380,7 +380,7 @@ static void timer_cb_file(uv_timer_t* handle) {
|
||||
|
||||
static void timer_cb_touch(uv_timer_t* timer) {
|
||||
uv_close((uv_handle_t*)timer, NULL);
|
||||
touch_file("watch_file");
|
||||
touch_file((char*) timer->data);
|
||||
timer_cb_touch_called++;
|
||||
}
|
||||
|
||||
@ -673,9 +673,6 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
|
||||
TEST_IMPL(fs_event_watch_file_twice) {
|
||||
#if defined(NO_FS_EVENTS)
|
||||
RETURN_SKIP(NO_FS_EVENTS);
|
||||
#endif
|
||||
#if defined(__ASAN__)
|
||||
RETURN_SKIP("Test does not currently work in ASAN");
|
||||
#endif
|
||||
const char path[] = "test/fixtures/empty_file";
|
||||
uv_fs_event_t watchers[2];
|
||||
@ -730,6 +727,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
|
||||
r = uv_timer_init(loop, &timer);
|
||||
ASSERT(r == 0);
|
||||
|
||||
timer.data = "watch_file";
|
||||
r = uv_timer_start(&timer, timer_cb_touch, 1100, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
@ -1174,3 +1172,49 @@ TEST_IMPL(fs_event_watch_invalid_path) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fs_event_cb_stop_calls;
|
||||
|
||||
static void fs_event_cb_stop(uv_fs_event_t* handle, const char* path,
|
||||
int events, int status) {
|
||||
uv_fs_event_stop(handle);
|
||||
fs_event_cb_stop_calls++;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_event_stop_in_cb) {
|
||||
uv_fs_event_t fs;
|
||||
uv_timer_t timer;
|
||||
char path[] = "fs_event_stop_in_cb.txt";
|
||||
|
||||
#if defined(NO_FS_EVENTS)
|
||||
RETURN_SKIP(NO_FS_EVENTS);
|
||||
#endif
|
||||
|
||||
remove(path);
|
||||
create_file(path);
|
||||
|
||||
ASSERT_EQ(0, uv_fs_event_init(uv_default_loop(), &fs));
|
||||
ASSERT_EQ(0, uv_fs_event_start(&fs, fs_event_cb_stop, path, 0));
|
||||
|
||||
/* Note: timer_cb_touch() closes the handle. */
|
||||
timer.data = path;
|
||||
ASSERT_EQ(0, uv_timer_init(uv_default_loop(), &timer));
|
||||
ASSERT_EQ(0, uv_timer_start(&timer, timer_cb_touch, 100, 0));
|
||||
|
||||
ASSERT_EQ(0, fs_event_cb_stop_calls);
|
||||
ASSERT_EQ(0, timer_cb_touch_called);
|
||||
|
||||
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||
|
||||
ASSERT_EQ(1, fs_event_cb_stop_calls);
|
||||
ASSERT_EQ(1, timer_cb_touch_called);
|
||||
|
||||
uv_close((uv_handle_t*) &fs, NULL);
|
||||
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||
ASSERT_EQ(1, fs_event_cb_stop_calls);
|
||||
|
||||
remove(path);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
38
deps/libuv/test/test-fs-open-flags.c
vendored
38
deps/libuv/test/test-fs-open-flags.c
vendored
@ -276,21 +276,21 @@ static void fs_open_flags(int add_flags) {
|
||||
/* r */
|
||||
flags = add_flags | UV_FS_O_RDONLY;
|
||||
openFail(absent_file, UV_ENOENT);
|
||||
writeFail(empty_file, UV_EPERM);
|
||||
writeFail(empty_file, UV_EBADF);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeFail(dummy_file, UV_EPERM);
|
||||
writeFail(dummy_file, UV_EBADF);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EPERM);
|
||||
writeFail(empty_dir, UV_EBADF);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* rs */
|
||||
flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC;
|
||||
openFail(absent_file, UV_ENOENT);
|
||||
writeFail(empty_file, UV_EPERM);
|
||||
writeFail(empty_file, UV_EBADF);
|
||||
readExpect(empty_file, "", 0);
|
||||
writeFail(dummy_file, UV_EPERM);
|
||||
writeFail(dummy_file, UV_EBADF);
|
||||
readExpect(dummy_file, "a", 1);
|
||||
writeFail(empty_dir, UV_EPERM);
|
||||
writeFail(empty_dir, UV_EBADF);
|
||||
readFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* r+ */
|
||||
@ -316,18 +316,18 @@ static void fs_open_flags(int add_flags) {
|
||||
/* w */
|
||||
flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
readFail(absent_file, UV_EBADF);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readFail(empty_file, UV_EPERM);
|
||||
readFail(empty_file, UV_EBADF);
|
||||
writeExpect(dummy_file, "bc", 2);
|
||||
readFail(dummy_file, UV_EPERM);
|
||||
readFail(dummy_file, UV_EBADF);
|
||||
openFail(empty_dir, UV_EISDIR);
|
||||
|
||||
/* wx */
|
||||
flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY |
|
||||
UV_FS_O_EXCL;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
readFail(absent_file, UV_EBADF);
|
||||
openFail(empty_file, UV_EEXIST);
|
||||
openFail(dummy_file, UV_EEXIST);
|
||||
openFail(empty_dir, UV_EEXIST);
|
||||
@ -354,19 +354,19 @@ static void fs_open_flags(int add_flags) {
|
||||
/* a */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
readFail(absent_file, UV_EBADF);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readFail(empty_file, UV_EPERM);
|
||||
readFail(empty_file, UV_EBADF);
|
||||
writeExpect(dummy_file, "abc", 3);
|
||||
readFail(dummy_file, UV_EPERM);
|
||||
readFail(dummy_file, UV_EBADF);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EPERM);
|
||||
readFail(empty_dir, UV_EBADF);
|
||||
|
||||
/* ax */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY |
|
||||
UV_FS_O_EXCL;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
readFail(absent_file, UV_EBADF);
|
||||
openFail(empty_file, UV_EEXIST);
|
||||
openFail(dummy_file, UV_EEXIST);
|
||||
openFail(empty_dir, UV_EEXIST);
|
||||
@ -375,13 +375,13 @@ static void fs_open_flags(int add_flags) {
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY |
|
||||
UV_FS_O_SYNC;
|
||||
writeExpect(absent_file, "bc", 2);
|
||||
readFail(absent_file, UV_EPERM);
|
||||
readFail(absent_file, UV_EBADF);
|
||||
writeExpect(empty_file, "bc", 2);
|
||||
readFail(empty_file, UV_EPERM);
|
||||
readFail(empty_file, UV_EBADF);
|
||||
writeExpect(dummy_file, "abc", 3);
|
||||
readFail(dummy_file, UV_EPERM);
|
||||
readFail(dummy_file, UV_EBADF);
|
||||
writeFail(empty_dir, UV_EISDIR);
|
||||
readFail(empty_dir, UV_EPERM);
|
||||
readFail(empty_dir, UV_EBADF);
|
||||
|
||||
/* a+ */
|
||||
flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR;
|
||||
|
3
deps/libuv/test/test-fs-readdir.c
vendored
3
deps/libuv/test/test-fs-readdir.c
vendored
@ -230,9 +230,6 @@ static void file_opendir_cb(uv_fs_t* req) {
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_readdir_file) {
|
||||
#if defined(__ASAN__)
|
||||
RETURN_SKIP("Test does not currently work in ASAN");
|
||||
#endif
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
|
8
deps/libuv/test/test-fs.c
vendored
8
deps/libuv/test/test-fs.c
vendored
@ -844,7 +844,7 @@ static void check_utime(const char* path,
|
||||
} else {
|
||||
double st_atim;
|
||||
double st_mtim;
|
||||
#ifndef __APPLE__
|
||||
#if !defined(__APPLE__) && !defined(__SUNPRO_C)
|
||||
/* TODO(vtjnash): would it be better to normalize this? */
|
||||
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
|
||||
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
|
||||
@ -2897,9 +2897,6 @@ TEST_IMPL(fs_scandir_non_existent_dir) {
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_scandir_file) {
|
||||
#if defined(__ASAN__)
|
||||
RETURN_SKIP("Test does not currently work in ASAN");
|
||||
#endif
|
||||
const char* path;
|
||||
int r;
|
||||
|
||||
@ -3146,9 +3143,6 @@ static void fs_read_bufs(int add_flags) {
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
}
|
||||
TEST_IMPL(fs_read_bufs) {
|
||||
#if defined(__ASAN__)
|
||||
RETURN_SKIP("Test does not currently work in ASAN");
|
||||
#endif
|
||||
fs_read_bufs(0);
|
||||
fs_read_bufs(UV_FS_O_FILEMAP);
|
||||
|
||||
|
65
deps/libuv/test/test-ip-name.c
vendored
Normal file
65
deps/libuv/test/test-ip-name.c
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright The libuv project and contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
union TestAddr {
|
||||
struct sockaddr addr;
|
||||
struct sockaddr_in addr4;
|
||||
struct sockaddr_in6 addr6;
|
||||
};
|
||||
|
||||
|
||||
TEST_IMPL(ip_name) {
|
||||
char dst[INET6_ADDRSTRLEN];
|
||||
union TestAddr test_addr;
|
||||
struct sockaddr* addr = &test_addr.addr;
|
||||
struct sockaddr_in* addr4 = &test_addr.addr4;
|
||||
struct sockaddr_in6* addr6 = &test_addr.addr6;
|
||||
|
||||
/* test ip4_name */
|
||||
ASSERT_EQ(0, uv_ip4_addr("192.168.0.1", TEST_PORT, addr4));
|
||||
ASSERT_EQ(0, uv_ip4_name(addr4, dst, INET_ADDRSTRLEN));
|
||||
ASSERT_EQ(0, strcmp("192.168.0.1", dst));
|
||||
|
||||
ASSERT_EQ(0, uv_ip_name(addr, dst, INET_ADDRSTRLEN));
|
||||
ASSERT_EQ(0, strcmp("192.168.0.1", dst));
|
||||
|
||||
/* test ip6_name */
|
||||
ASSERT_EQ(0, uv_ip6_addr("fe80::2acf:daff:fedd:342a", TEST_PORT, addr6));
|
||||
ASSERT_EQ(0, uv_ip6_name(addr6, dst, INET6_ADDRSTRLEN));
|
||||
ASSERT_EQ(0, strcmp("fe80::2acf:daff:fedd:342a", dst));
|
||||
|
||||
ASSERT_EQ(0, uv_ip_name(addr, dst, INET6_ADDRSTRLEN));
|
||||
ASSERT_EQ(0, strcmp("fe80::2acf:daff:fedd:342a", dst));
|
||||
|
||||
/* test other sa_family */
|
||||
addr->sa_family = AF_UNIX;
|
||||
/* size is not a concern here */
|
||||
ASSERT_EQ(UV_EAFNOSUPPORT, uv_ip_name(addr, dst, INET6_ADDRSTRLEN));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
6
deps/libuv/test/test-ip6-addr.c
vendored
6
deps/libuv/test/test-ip6-addr.c
vendored
@ -161,11 +161,11 @@ TEST_IMPL(ip6_pton) {
|
||||
#undef GOOD_ADDR_LIST
|
||||
#undef BAD_ADDR_LIST
|
||||
|
||||
#ifdef SIN6_LEN
|
||||
TEST_IMPL(ip6_sin6_len) {
|
||||
struct sockaddr_in6 s;
|
||||
ASSERT(uv_ip6_addr("::", 0, &s) < 0);
|
||||
ASSERT_EQ(0, uv_ip6_addr("::", 0, &s));
|
||||
#ifdef SIN6_LEN
|
||||
ASSERT(s.sin6_len == sizeof(s));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
14
deps/libuv/test/test-list.h
vendored
14
deps/libuv/test/test-list.h
vendored
@ -78,6 +78,7 @@ TEST_DECLARE (tty_pty)
|
||||
TEST_DECLARE (stdio_over_pipes)
|
||||
TEST_DECLARE (stdio_emulate_iocp)
|
||||
TEST_DECLARE (ip6_pton)
|
||||
TEST_DECLARE (ip6_sin6_len)
|
||||
TEST_DECLARE (connect_unspecified)
|
||||
TEST_DECLARE (ipc_heavy_traffic_deadlock_bug)
|
||||
TEST_DECLARE (ipc_listen_before_write)
|
||||
@ -159,6 +160,7 @@ TEST_DECLARE (udp_alloc_cb_fail)
|
||||
TEST_DECLARE (udp_bind)
|
||||
TEST_DECLARE (udp_bind_reuseaddr)
|
||||
TEST_DECLARE (udp_connect)
|
||||
TEST_DECLARE (udp_connect6)
|
||||
TEST_DECLARE (udp_create_early)
|
||||
TEST_DECLARE (udp_create_early_bad_bind)
|
||||
TEST_DECLARE (udp_create_early_bad_domain)
|
||||
@ -390,6 +392,7 @@ TEST_DECLARE (fs_event_close_in_callback)
|
||||
TEST_DECLARE (fs_event_start_and_close)
|
||||
TEST_DECLARE (fs_event_error_reporting)
|
||||
TEST_DECLARE (fs_event_getpath)
|
||||
TEST_DECLARE (fs_event_stop_in_cb)
|
||||
TEST_DECLARE (fs_scandir_empty_dir)
|
||||
TEST_DECLARE (fs_scandir_non_existent_dir)
|
||||
TEST_DECLARE (fs_scandir_file)
|
||||
@ -458,6 +461,7 @@ TEST_DECLARE (poll_multiple_handles)
|
||||
|
||||
TEST_DECLARE (ip4_addr)
|
||||
TEST_DECLARE (ip6_addr_link_local)
|
||||
TEST_DECLARE (ip_name)
|
||||
|
||||
TEST_DECLARE (poll_close_doesnt_corrupt_stack)
|
||||
TEST_DECLARE (poll_closesocket)
|
||||
@ -507,7 +511,7 @@ TEST_DECLARE (getters_setters)
|
||||
|
||||
TEST_DECLARE (not_writable_after_shutdown)
|
||||
TEST_DECLARE (not_readable_nor_writable_on_read_error)
|
||||
TEST_DECLARE (not_readable_on_eof)
|
||||
TEST_DECLARE (readable_on_eof)
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST_DECLARE (fork_timer)
|
||||
@ -610,6 +614,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (stdio_over_pipes)
|
||||
TEST_ENTRY (stdio_emulate_iocp)
|
||||
TEST_ENTRY (ip6_pton)
|
||||
TEST_ENTRY (ip6_sin6_len)
|
||||
TEST_ENTRY (connect_unspecified)
|
||||
TEST_ENTRY (ipc_heavy_traffic_deadlock_bug)
|
||||
TEST_ENTRY (ipc_listen_before_write)
|
||||
@ -733,6 +738,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (udp_bind)
|
||||
TEST_ENTRY (udp_bind_reuseaddr)
|
||||
TEST_ENTRY (udp_connect)
|
||||
TEST_ENTRY (udp_connect6)
|
||||
TEST_ENTRY (udp_create_early)
|
||||
TEST_ENTRY (udp_create_early_bad_bind)
|
||||
TEST_ENTRY (udp_create_early_bad_domain)
|
||||
@ -1050,6 +1056,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_event_start_and_close)
|
||||
TEST_ENTRY_CUSTOM (fs_event_error_reporting, 0, 0, 60000)
|
||||
TEST_ENTRY (fs_event_getpath)
|
||||
TEST_ENTRY (fs_event_stop_in_cb)
|
||||
TEST_ENTRY (fs_scandir_empty_dir)
|
||||
TEST_ENTRY (fs_scandir_non_existent_dir)
|
||||
TEST_ENTRY (fs_scandir_file)
|
||||
@ -1102,6 +1109,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (dlerror)
|
||||
TEST_ENTRY (ip4_addr)
|
||||
TEST_ENTRY (ip6_addr_link_local)
|
||||
TEST_ENTRY (ip_name)
|
||||
|
||||
TEST_ENTRY (queue_foreach_delete)
|
||||
|
||||
@ -1141,8 +1149,8 @@ TASK_LIST_START
|
||||
TEST_HELPER (not_writable_after_shutdown, tcp4_echo_server)
|
||||
TEST_ENTRY (not_readable_nor_writable_on_read_error)
|
||||
TEST_HELPER (not_readable_nor_writable_on_read_error, tcp4_echo_server)
|
||||
TEST_ENTRY (not_readable_on_eof)
|
||||
TEST_HELPER (not_readable_on_eof, tcp4_echo_server)
|
||||
TEST_ENTRY (readable_on_eof)
|
||||
TEST_HELPER (readable_on_eof, tcp4_echo_server)
|
||||
|
||||
TEST_ENTRY (metrics_idle_time)
|
||||
TEST_ENTRY (metrics_idle_time_thread)
|
||||
|
3
deps/libuv/test/test-ping-pong.c
vendored
3
deps/libuv/test/test-ping-pong.c
vendored
@ -84,6 +84,7 @@ static void pinger_on_close(uv_handle_t* handle) {
|
||||
|
||||
static void pinger_after_write(uv_write_t* req, int status) {
|
||||
ASSERT_EQ(status, 0);
|
||||
free(req->data);
|
||||
free(req);
|
||||
}
|
||||
|
||||
@ -110,6 +111,7 @@ static void pinger_write_ping(pinger_t* pinger) {
|
||||
|
||||
req = malloc(sizeof(*req));
|
||||
ASSERT_NOT_NULL(req);
|
||||
req->data = NULL;
|
||||
ASSERT_EQ(0, uv_write(req, stream, bufs, nbufs, pinger_after_write));
|
||||
|
||||
puts("PING");
|
||||
@ -185,6 +187,7 @@ static void ponger_read_cb(uv_stream_t* stream,
|
||||
writebuf = uv_buf_init(buf->base, nread);
|
||||
req = malloc(sizeof(*req));
|
||||
ASSERT_NOT_NULL(req);
|
||||
req->data = buf->base;
|
||||
ASSERT_EQ(0, uv_write(req, stream, &writebuf, 1, pinger_after_write));
|
||||
}
|
||||
|
||||
|
3
deps/libuv/test/test-pipe-connect-error.c
vendored
3
deps/libuv/test/test-pipe-connect-error.c
vendored
@ -76,9 +76,6 @@ TEST_IMPL(pipe_connect_bad_name) {
|
||||
|
||||
|
||||
TEST_IMPL(pipe_connect_to_file) {
|
||||
#if defined(__ASAN__)
|
||||
RETURN_SKIP("Test does not currently work in ASAN");
|
||||
#endif
|
||||
const char* path = "test/fixtures/empty_file";
|
||||
uv_pipe_t client;
|
||||
uv_connect_t req;
|
||||
|
@ -35,7 +35,7 @@ static int close_cb_called;
|
||||
|
||||
static void write_cb(uv_write_t* req, int status) {
|
||||
write_cb_called++;
|
||||
ASSERT(status == 0);
|
||||
ASSERT_EQ(status, 0);
|
||||
}
|
||||
|
||||
static void alloc_cb(uv_handle_t* handle,
|
||||
@ -51,12 +51,20 @@ static void close_cb(uv_handle_t* handle) {
|
||||
}
|
||||
|
||||
static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
||||
read_cb_called++;
|
||||
int r;
|
||||
|
||||
ASSERT(nread == UV_EOF);
|
||||
ASSERT(0 == uv_is_readable(handle));
|
||||
ASSERT_EQ(nread, UV_EOF);
|
||||
ASSERT_EQ(uv_is_readable(handle), 1);
|
||||
ASSERT_EQ(uv_is_writable(handle), 1);
|
||||
|
||||
uv_close((uv_handle_t*) handle, close_cb);
|
||||
if (++read_cb_called == 3) {
|
||||
uv_close((uv_handle_t*) handle, close_cb);
|
||||
ASSERT_EQ(uv_is_readable(handle), 0);
|
||||
ASSERT_EQ(uv_is_writable(handle), 0);
|
||||
} else {
|
||||
r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb);
|
||||
ASSERT_EQ(r, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void connect_cb(uv_connect_t* req, int status) {
|
||||
@ -64,10 +72,9 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
uv_buf_t close_me;
|
||||
|
||||
connect_cb_called++;
|
||||
ASSERT(status == 0);
|
||||
ASSERT_EQ(status, 0);
|
||||
|
||||
r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
read_cb((uv_stream_t*) &tcp_client, UV_EOF, NULL);
|
||||
|
||||
close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd));
|
||||
|
||||
@ -77,26 +84,27 @@ static void connect_cb(uv_connect_t* req, int status) {
|
||||
1,
|
||||
write_cb);
|
||||
|
||||
ASSERT(r == 0);
|
||||
ASSERT_EQ(r, 0);
|
||||
}
|
||||
|
||||
TEST_IMPL(not_readable_on_eof) {
|
||||
TEST_IMPL(readable_on_eof) {
|
||||
struct sockaddr_in sa;
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
ASSERT(0 == uv_tcp_init(&loop, &tcp_client));
|
||||
ASSERT_EQ(uv_ip4_addr("127.0.0.1", TEST_PORT, &sa), 0);
|
||||
ASSERT_EQ(uv_loop_init(&loop), 0);
|
||||
ASSERT_EQ(uv_tcp_init(&loop, &tcp_client), 0);
|
||||
|
||||
ASSERT(0 == uv_tcp_connect(&connect_req,
|
||||
&tcp_client,
|
||||
(const struct sockaddr*) &sa,
|
||||
connect_cb));
|
||||
ASSERT_EQ(uv_tcp_connect(&connect_req,
|
||||
&tcp_client,
|
||||
(const struct sockaddr*) &sa,
|
||||
connect_cb),
|
||||
0);
|
||||
|
||||
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
|
||||
ASSERT_EQ(uv_run(&loop, UV_RUN_DEFAULT), 0);
|
||||
|
||||
ASSERT(connect_cb_called == 1);
|
||||
ASSERT(read_cb_called == 1);
|
||||
ASSERT(write_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
ASSERT_EQ(connect_cb_called, 1);
|
||||
ASSERT_EQ(read_cb_called, 3);
|
||||
ASSERT_EQ(write_cb_called, 1);
|
||||
ASSERT_EQ(close_cb_called, 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
2
deps/libuv/test/test-tcp-connect-timeout.c
vendored
2
deps/libuv/test/test-tcp-connect-timeout.c
vendored
@ -111,7 +111,7 @@ static int is_supported_system(void) {
|
||||
if (cnt != 3) {
|
||||
return 0;
|
||||
}
|
||||
/* relase >= 10.0.16299 */
|
||||
/* release >= 10.0.16299 */
|
||||
for (cnt = 0; cnt < 3; ++cnt) {
|
||||
if (semver[cnt] > min_semver[cnt])
|
||||
return 1;
|
||||
|
6
deps/libuv/test/test-thread-equal.c
vendored
6
deps/libuv/test/test-thread-equal.c
vendored
@ -28,6 +28,9 @@ uv_thread_t subthreads[2];
|
||||
static void check_thread(void* arg) {
|
||||
uv_thread_t *thread_id = arg;
|
||||
uv_thread_t self_id = uv_thread_self();
|
||||
#ifdef _WIN32
|
||||
ASSERT_NOT_NULL(self_id);
|
||||
#endif
|
||||
ASSERT(uv_thread_equal(&main_thread_id, &self_id) == 0);
|
||||
*thread_id = uv_thread_self();
|
||||
}
|
||||
@ -35,6 +38,9 @@ static void check_thread(void* arg) {
|
||||
TEST_IMPL(thread_equal) {
|
||||
uv_thread_t threads[2];
|
||||
main_thread_id = uv_thread_self();
|
||||
#ifdef _WIN32
|
||||
ASSERT_NOT_NULL(main_thread_id);
|
||||
#endif
|
||||
ASSERT(0 != uv_thread_equal(&main_thread_id, &main_thread_id));
|
||||
ASSERT(0 == uv_thread_create(threads + 0, check_thread, subthreads + 0));
|
||||
ASSERT(0 == uv_thread_create(threads + 1, check_thread, subthreads + 1));
|
||||
|
@ -271,7 +271,7 @@ static void make_expect_screen_erase(struct captured_screen* cs,
|
||||
static void make_expect_screen_write(struct captured_screen* cs,
|
||||
COORD cursor_position,
|
||||
const char* text) {
|
||||
/* postion of cursor */
|
||||
/* position of cursor */
|
||||
char* start;
|
||||
start = cs->text + cs->si.width * (cursor_position.Y - 1) +
|
||||
cursor_position.X - 1;
|
||||
@ -1070,6 +1070,11 @@ TEST_IMPL(tty_set_style) {
|
||||
WORD attr;
|
||||
int i, length;
|
||||
|
||||
#if _MSC_VER >= 1920 && _MSC_VER <= 1929
|
||||
RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. "
|
||||
"See: https://github.com/libuv/libuv/issues/3304");
|
||||
#endif
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
initialize_tty(&tty_out);
|
||||
@ -1261,7 +1266,7 @@ TEST_IMPL(tty_save_restore_cursor_position) {
|
||||
cursor_pos.Y = si.height / 4;
|
||||
set_cursor_position(&tty_out, cursor_pos);
|
||||
|
||||
/* restore the cursor postion */
|
||||
/* restore the cursor position */
|
||||
snprintf(buffer, sizeof(buffer), "%su", CSI);
|
||||
write_console(&tty_out, buffer);
|
||||
get_cursor_position(&tty_out, &cursor_pos);
|
||||
@ -1280,7 +1285,7 @@ TEST_IMPL(tty_save_restore_cursor_position) {
|
||||
cursor_pos.Y = si.height / 4;
|
||||
set_cursor_position(&tty_out, cursor_pos);
|
||||
|
||||
/* restore the cursor postion */
|
||||
/* restore the cursor position */
|
||||
snprintf(buffer, sizeof(buffer), "%s8", ESC);
|
||||
write_console(&tty_out, buffer);
|
||||
get_cursor_position(&tty_out, &cursor_pos);
|
||||
@ -1348,6 +1353,11 @@ TEST_IMPL(tty_escape_sequence_processing) {
|
||||
struct captured_screen actual = {0}, expect = {0};
|
||||
int dir;
|
||||
|
||||
#if _MSC_VER >= 1920 && _MSC_VER <= 1929
|
||||
RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. "
|
||||
"See: https://github.com/libuv/libuv/issues/3304");
|
||||
#endif
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
initialize_tty(&tty_out);
|
||||
|
2
deps/libuv/test/test-udp-connect.c
vendored
2
deps/libuv/test/test-udp-connect.c
vendored
@ -124,7 +124,7 @@ TEST_IMPL(udp_connect) {
|
||||
|
||||
buf = uv_buf_init("EXIT", 4);
|
||||
|
||||
/* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */
|
||||
/* connect() to INADDR_ANY fails on Windows with WSAEADDRNOTAVAIL */
|
||||
ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &tmp_addr));
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr);
|
||||
#ifdef _WIN32
|
||||
|
200
deps/libuv/test/test-udp-connect6.c
vendored
Normal file
200
deps/libuv/test/test-udp-connect6.c
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
/* Copyright libuv project and contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CHECK_HANDLE(handle) \
|
||||
ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
|
||||
|
||||
static uv_udp_t server;
|
||||
static uv_udp_t client;
|
||||
static uv_buf_t buf;
|
||||
static struct sockaddr_in6 lo_addr;
|
||||
|
||||
static int cl_send_cb_called;
|
||||
static int sv_recv_cb_called;
|
||||
|
||||
static int close_cb_called;
|
||||
|
||||
|
||||
static void alloc_cb(uv_handle_t* handle,
|
||||
size_t suggested_size,
|
||||
uv_buf_t* buf) {
|
||||
static char slab[65536];
|
||||
CHECK_HANDLE(handle);
|
||||
ASSERT_LE(suggested_size, sizeof(slab));
|
||||
buf->base = slab;
|
||||
buf->len = sizeof(slab);
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
CHECK_HANDLE(handle);
|
||||
ASSERT(uv_is_closing(handle));
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void cl_send_cb(uv_udp_send_t* req, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT_NOT_NULL(req);
|
||||
ASSERT_EQ(status, 0);
|
||||
CHECK_HANDLE(req->handle);
|
||||
if (++cl_send_cb_called == 1) {
|
||||
uv_udp_connect(&client, NULL);
|
||||
r = uv_udp_send(req, &client, &buf, 1, NULL, cl_send_cb);
|
||||
ASSERT_EQ(r, UV_EDESTADDRREQ);
|
||||
r = uv_udp_send(req,
|
||||
&client,
|
||||
&buf,
|
||||
1,
|
||||
(const struct sockaddr*) &lo_addr,
|
||||
cl_send_cb);
|
||||
ASSERT_EQ(r, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void sv_recv_cb(uv_udp_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* rcvbuf,
|
||||
const struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
if (nread > 0) {
|
||||
ASSERT_EQ(nread, 4);
|
||||
ASSERT_NOT_NULL(addr);
|
||||
ASSERT_EQ(memcmp("EXIT", rcvbuf->base, nread), 0);
|
||||
if (++sv_recv_cb_called == 4) {
|
||||
uv_close((uv_handle_t*) &server, close_cb);
|
||||
uv_close((uv_handle_t*) &client, close_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(udp_connect6) {
|
||||
#if defined(__PASE__)
|
||||
RETURN_SKIP(
|
||||
"IBMi PASE's UDP connection can not be disconnected with AF_UNSPEC.");
|
||||
#endif
|
||||
uv_udp_send_t req;
|
||||
struct sockaddr_in6 ext_addr;
|
||||
struct sockaddr_in6 tmp_addr;
|
||||
int r;
|
||||
int addrlen;
|
||||
|
||||
if (!can_ipv6())
|
||||
RETURN_SKIP("IPv6 not supported");
|
||||
|
||||
ASSERT_EQ(0, uv_ip6_addr("::", TEST_PORT, &lo_addr));
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &server);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
r = uv_udp_bind(&server, (const struct sockaddr*) &lo_addr, 0);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &client);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
buf = uv_buf_init("EXIT", 4);
|
||||
|
||||
/* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */
|
||||
ASSERT_EQ(0, uv_ip6_addr("::", TEST_PORT, &tmp_addr));
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr);
|
||||
#ifdef _WIN32
|
||||
ASSERT_EQ(r, UV_EADDRNOTAVAIL);
|
||||
#else
|
||||
ASSERT_EQ(r, 0);
|
||||
r = uv_udp_connect(&client, NULL);
|
||||
ASSERT_EQ(r, 0);
|
||||
#endif
|
||||
|
||||
ASSERT_EQ(0, uv_ip6_addr("2001:4860:4860::8888", TEST_PORT, &ext_addr));
|
||||
ASSERT_EQ(0, uv_ip6_addr("::1", TEST_PORT, &lo_addr));
|
||||
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT_EQ(r, 0);
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &ext_addr);
|
||||
ASSERT_EQ(r, UV_EISCONN);
|
||||
|
||||
addrlen = sizeof(tmp_addr);
|
||||
r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
/* To send messages in connected UDP sockets addr must be NULL */
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT_EQ(r, UV_EISCONN);
|
||||
r = uv_udp_try_send(&client, &buf, 1, NULL);
|
||||
ASSERT_EQ(r, 4);
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &ext_addr);
|
||||
ASSERT_EQ(r, UV_EISCONN);
|
||||
|
||||
r = uv_udp_connect(&client, NULL);
|
||||
ASSERT_EQ(r, 0);
|
||||
r = uv_udp_connect(&client, NULL);
|
||||
ASSERT_EQ(r, UV_ENOTCONN);
|
||||
|
||||
addrlen = sizeof(tmp_addr);
|
||||
r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen);
|
||||
ASSERT_EQ(r, UV_ENOTCONN);
|
||||
|
||||
/* To send messages in disconnected UDP sockets addr must be set */
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT_EQ(r, 4);
|
||||
r = uv_udp_try_send(&client, &buf, 1, NULL);
|
||||
ASSERT_EQ(r, UV_EDESTADDRREQ);
|
||||
|
||||
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT_EQ(r, 0);
|
||||
r = uv_udp_send(&req,
|
||||
&client,
|
||||
&buf,
|
||||
1,
|
||||
(const struct sockaddr*) &lo_addr,
|
||||
cl_send_cb);
|
||||
ASSERT_EQ(r, UV_EISCONN);
|
||||
r = uv_udp_send(&req, &client, &buf, 1, NULL, cl_send_cb);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT_EQ(close_cb_called, 2);
|
||||
ASSERT_EQ(sv_recv_cb_called, 4);
|
||||
ASSERT_EQ(cl_send_cb_called, 2);
|
||||
|
||||
ASSERT_EQ(client.send_queue_size, 0);
|
||||
ASSERT_EQ(server.send_queue_size, 0);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user