📄 socket.c
字号:
CALL(begin(&sock, serve_sstring, &hello)); CALL(read_expect(sock, STR, strlen(STR))); CALL(expect_close(sock)); CALL(good_close(sock)); return await_server();}/* Test a simple peek. */static int single_peek(void){ ne_socket *sock; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); CALL(peek_expect(sock, STR, strlen(STR))); return finish(sock, 0);}/* Test lots of 1-byte reads. */static int small_reads(void){ ne_socket *sock; char *pnt; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); /* read the string byte-by-byte. */ for (pnt = hello.data; *pnt; pnt++) { CALL(read_expect(sock, pnt, 1)); } return finish(sock, 1);}/* peek or read, expecting to get given string. */#define READ(str) CALL(read_expect(sock, str, strlen(str)))#define PEEK(str) CALL(peek_expect(sock, str, strlen(str)))/* Stress out the read buffer handling a little. */static int read_and_peek(void){ ne_socket *sock; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); PEEK("Hello"); PEEK("Hell"); PEEK(STR); READ("He"); PEEK("llo, "); READ("l"); PEEK("lo, World."); READ("lo, Worl"); PEEK("d."); PEEK("d"); READ("d."); return finish(sock, 1);}/* Read more bytes than were written. */static int larger_read(void){ ne_socket *sock; ssize_t nb; DECL(hello, STR); CALL(begin(&sock, serve_sstring, &hello)); nb = ne_sock_read(sock, buffer, hello.len + 10); ONV(nb != (ssize_t)hello.len, ("read gave too many bytes (%" NE_FMT_SSIZE_T ")", nb)); ONN("read gave wrong data", memcmp(buffer, hello.data, hello.len)); return finish(sock, 1);}static int line_expect(ne_socket *sock, const char *line){ ssize_t ret = ne_sock_readline(sock, buffer, BUFSIZ); size_t len = strlen(line); ONV(ret == NE_SOCK_CLOSED, ("socket closed, expecting `%s'", line)); ONV(ret < 0, ("socket error `%s', expecting `%s'", ne_sock_error(sock), line)); ONV((size_t)ret != len, ("readline got %" NE_FMT_SSIZE_T ", expecting `%s'", ret, line)); ONV(strcmp(line, buffer), ("readline mismatch: `%s' not `%s'", buffer, line)); return OK;}#define LINE(x) CALL(line_expect(sock, x))#define STR2 "Goodbye, cruel world."static int line_simple(void){ ne_socket *sock; DECL(oneline, STR "\n" STR2 "\n"); CALL(begin(&sock, serve_sstring, &oneline)); LINE(STR "\n"); LINE(STR2 "\n"); return finish(sock, 1);}static int line_closure(void){ ne_socket *sock; ssize_t ret; DECL(oneline, STR "\n" "foobar"); CALL(begin(&sock, serve_sstring, &oneline)); LINE(STR "\n"); ret = ne_sock_readline(sock, buffer, BUFSIZ); ONV(ret != NE_SOCK_CLOSED, ("readline got %" NE_FMT_SSIZE_T " not EOF", ret)); return finish(sock, 0);} /* check that empty lines are handled correctly. */static int line_empty(void){ ne_socket *sock; DECL(oneline, "\n\na\n\n"); CALL(begin(&sock, serve_sstring, &oneline)); LINE("\n"); LINE("\n"); LINE("a\n"); LINE("\n"); return finish(sock, 1);}static int line_toolong(void){ ne_socket *sock; ssize_t ret; DECL(oneline, "AAAAAA\n"); CALL(begin(&sock, serve_sstring, &oneline)); ret = ne_sock_readline(sock, buffer, 5); ONV(ret != NE_SOCK_ERROR, ("readline should fail on long line: %" NE_FMT_SSIZE_T, ret)); return finish(sock, 0);}/* readline()s mingled with other operations: buffering tests. */static int line_mingle(void){ ne_socket *sock; DECL(oneline, "alpha\nbeta\ndelta\ngamma\n"); CALL(begin(&sock, serve_sstring, &oneline)); READ("a"); LINE("lpha\n"); READ("beta"); LINE("\n"); PEEK("d"); PEEK("delt"); LINE("delta\n"); READ("gam"); LINE("ma\n"); return finish(sock, 1);}/* readline which needs multiple read() calls. */static int line_chunked(void){ ne_socket *sock; DECL(oneline, "this is a line\n"); CALL(begin(&sock, serve_sstring_slowly, &oneline)); LINE("this is a line\n"); return finish(sock, 1);}static time_t to_start, to_finish;static int to_begin(ne_socket **sock){ CALL(begin(sock, sleepy_server, NULL)); ne_sock_read_timeout(*sock, 1); to_start = time(NULL); return OK;}static int to_end(ne_socket *sock){ to_finish = time(NULL); reap_server(); /* hopefully it's hung. */ ONN("timeout ignored, or very slow machine", to_finish - to_start > 3); ONN("close failed", ne_sock_close(sock)); return OK;} #define TO_BEGIN ne_socket *sock; CALL(to_begin(&sock))#define TO_OP(x) do { int to_ret = (x); \ONV(to_ret != NE_SOCK_TIMEOUT, ("operation did not timeout: %d", to_ret)); \} while (0)#define TO_FINISH return to_end(sock)static int peek_timeout(void){ TO_BEGIN; TO_OP(ne_sock_peek(sock, buffer, 1)); TO_FINISH;}static int read_timeout(void){ TO_BEGIN; TO_OP(ne_sock_read(sock, buffer, 1)); TO_FINISH;}static int readline_timeout(void){ TO_BEGIN; TO_OP(ne_sock_readline(sock, buffer, 1)); TO_FINISH;}static int fullread_timeout(void){ TO_BEGIN; TO_OP(ne_sock_fullread(sock, buffer, 1)); TO_FINISH;} static int serve_expect(ne_socket *sock, void *ud){ struct string *str = ud; ssize_t ret; while (str->len && (ret = ne_sock_read(sock, buffer, sizeof(buffer))) > 0) { NE_DEBUG(NE_DBG_SOCKET, "Got %" NE_FMT_SSIZE_T " bytes.\n", ret); ONV(memcmp(str->data, buffer, ret), ("unexpected data: [%.*s] not [%.*s]", (int)ret, buffer, (int)ret, str->data)); str->data += ret; str->len -= ret; NE_DEBUG(NE_DBG_SOCKET, "%" NE_FMT_SIZE_T " bytes left.\n", str->len); } NE_DEBUG(NE_DBG_SOCKET, "All data read.\n"); return OK;}static int full_write(ne_socket *sock, const char *data, size_t len){ int ret = ne_sock_fullwrite(sock, data, len); ONV(ret, ("write failed (%d): %s", ret, ne_sock_error(sock))); return OK;}#define WRITEL(str) CALL(full_write(sock, str, strlen(str))); \minisleep()static int small_writes(void){ ne_socket *sock; DECL(str, "This\nIs\nSome\nText.\n"); CALL(begin(&sock, serve_expect, &str)); WRITEL("This\n"); WRITEL("Is\n"); WRITEL("Some\n"); WRITEL("Text.\n"); return finish(sock, 1);}static int large_writes(void){#define LARGE_SIZE (123456) struct string str; ne_socket *sock; ssize_t n; str.data = ne_malloc(LARGE_SIZE); str.len = LARGE_SIZE; for (n = 0; n < LARGE_SIZE; n++) str.data[n] = 41 + n % 130; CALL(begin(&sock, serve_expect, &str)); CALL(full_write(sock, str.data, str.len)); ne_free(str.data); return finish(sock, 1); }/* echoes back lines. */static int echo_server(ne_socket *sock, void *ud){ ssize_t ret; while ((ret = ne_sock_readline(sock, buffer, sizeof(buffer))) > 0) { NE_DEBUG(NE_DBG_SOCKET, "Line: %s", buffer); ONN("write failed", ne_sock_fullwrite(sock, buffer, ret)); NE_DEBUG(NE_DBG_SOCKET, "Wrote line.\n"); } ONN("readline failed", ret != NE_SOCK_CLOSED); return 0;}static int echo_expect(ne_socket *sock, const char *line){ CALL(full_write(sock, line, strlen(line))); return line_expect(sock, line);}#define ECHO(line) CALL(echo_expect(sock, line))static int echo_lines(void){ ne_socket *sock; CALL(begin(&sock, echo_server, NULL)); ECHO("hello,\n"); ECHO("\n"); ECHO("world\n"); return finish(sock, 0);}#ifdef SOCKET_SSL/* harder to simulate closure cases for an SSL connection, since it * may be doing multiple read()s or write()s per ne_sock_* call. */static int ssl_closure(void){ ne_socket *sock; ssize_t ret; CALL(begin(&sock, serve_close, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); do { ret = ne_sock_fullwrite(sock, "a", 1); } while (ret == 0); ONV(ret != NE_SOCK_RESET && ret != NE_SOCK_CLOSED, ("write got %" NE_FMT_SSIZE_T " not reset or closure", ret)); return good_close(sock);}static int serve_truncate(ne_socket *sock, void *userdata){ exit(0);}/* when an EOF is received without a clean shutdown (close_notify message). */static int ssl_truncate(void){ ne_socket *sock; int ret; CALL(begin(&sock, serve_truncate, NULL)); ret = ne_sock_read(sock, buffer, 1); ONV(ret != NE_SOCK_TRUNC, ("socket got error %d not truncation: `%s'", ret, ne_sock_error(sock))); return finish(sock, 0);}#else/* thanks to W Richard Stevens for the precise repro case for getting * an RST on demand. */static int write_reset(void){ ne_socket *sock; int ret; CALL(begin(&sock, serve_close, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_fullwrite(sock, "a", 1); if (ret == 0) { ne_sock_close(sock); return SKIP; } ONV(ret != NE_SOCK_RESET, ("write got %d not reset", ret)); return good_close(sock);}static int read_reset(void){ ne_socket *sock; ssize_t ret; CALL(begin(&sock, serve_close, NULL)); CALL(full_write(sock, "a", 1)); CALL(await_server()); ret = ne_sock_read(sock, buffer, 1); if (ret == NE_SOCK_CLOSED) { ne_sock_close(sock); return SKIP; } ONV(ret != NE_SOCK_RESET, ("read got %" NE_FMT_SSIZE_T " not reset", ret)); return good_close(sock);} #endifne_test tests[] = { T(multi_init), T_LEAKY(resolve), T(resolve_numeric),#ifdef SOCKET_SSL T_LEAKY(init_ssl),#endif T(addr_make_v4), T(addr_make_v6), T(addr_compare), T(just_connect), T(addr_connect), T(read_close), T(peek_close), T(single_read), T(single_peek), T(small_reads), T(read_and_peek), T(larger_read), T(line_simple), T(line_closure), T(line_empty), T(line_toolong), T(line_mingle), T(line_chunked), T(small_writes), T(large_writes), T(echo_lines),#ifdef SOCKET_SSL T(ssl_closure), T(ssl_truncate),#else T(write_reset), T(read_reset),#endif T(read_timeout), T(peek_timeout), T(readline_timeout), T(fullread_timeout), T(NULL)};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -