From a1bc6dcbf82ede62a02d6e8877f9ac7f95b75b28 Mon Sep 17 00:00:00 2001 From: TJIC Date: Fri, 22 Aug 2014 17:33:27 -0400 Subject: [PATCH] libuv 0.11 working --- v/cttp.c | 49 ++++++++++++++++++++++++------- v/http.c | 30 ++++++++++++++----- v/raft.c | 9 +++--- v/term.c | 26 +++++++++++++---- v/unix.c | 89 +++++++++++++++++++++++++++++++++++--------------------- 5 files changed, 142 insertions(+), 61 deletions(-) diff --git a/v/cttp.c b/v/cttp.c index cbb5c5244..2251aa0b3 100644 --- a/v/cttp.c +++ b/v/cttp.c @@ -1146,17 +1146,31 @@ _cttp_ccon_cryp_pull(u2_ccon* coc_u) _cttp_ccon_kick_write_cryp(coc_u); } +/* + * `nread` (siz_w) is > 0 if there is data available, 0 if libuv is done reading for + * now, or < 0 on error. + * + * The callee is responsible for closing the stream when an error happens + * by calling uv_close(). Trying to read from the stream again is undefined. + * + * The callee is responsible for freeing the buffer, libuv does not reuse it. + * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on + * error. + */ + static void _cttp_ccon_kick_read_cryp_cb(uv_stream_t* tcp_u, - ssize_t siz_i, - const uv_buf_t buf_u) + ssize_t siz_w, + const uv_buf_t * buf_u) { u2_ccon *coc_u = _cttp_ccon_wax((uv_tcp_t*)tcp_u); u2_lo_open(); { - if ( siz_i < 0 ) { - // always a failure in libuv 11 + if ( siz_w == UV_EOF ) { + _cttp_ccon_fail(coc_u, u2_no); + } else if ( siz_w < 0 ) { + uL(fprintf(uH, "cttp: read 2: %s\n", uv_strerror(siz_w))); _cttp_ccon_fail(coc_u, u2_yes); } else { @@ -1166,12 +1180,12 @@ _cttp_ccon_kick_read_cryp_cb(uv_stream_t* tcp_u, uL(fprintf(uH, "http: response to no request\n")); } else { - BIO_write(coc_u->ssl.rio_u, (c3_c*)buf_u.base, siz_i); + BIO_write(coc_u->ssl.rio_u, (c3_c*)buf_u->base, siz_w); _cttp_ccon_cryp_pull(coc_u); } } - if ( buf_u.base ) { - free(buf_u.base); + if ( buf_u->base ) { + free(buf_u->base); } } u2_lo_shut(u2_yes); @@ -1179,21 +1193,34 @@ _cttp_ccon_kick_read_cryp_cb(uv_stream_t* tcp_u, /* _cttp_ccon_read_clyr_cb() */ +/* + * `nread` (siz_w) is > 0 if there is data available, 0 if libuv is done reading for + * now, or < 0 on error. + * + * The callee is responsible for closing the stream when an error happens + * by calling uv_close(). Trying to read from the stream again is undefined. + * + * The callee is responsible for freeing the buffer, libuv does not reuse it. + * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on + * error. + */ static void _cttp_ccon_kick_read_clyr_cb(uv_stream_t* tcp_u, - ssize_t siz_i, + ssize_t siz_w, const uv_buf_t * buf_u) { u2_ccon *coc_u = _cttp_ccon_wax((uv_tcp_t*)tcp_u); u2_lo_open(); { - if ( siz_i < 0 ) { - // always a failure in libuv 11 + if ( siz_w == UV_EOF ) { + _cttp_ccon_fail(coc_u, u2_no); + } else if ( siz_w < 0 ) { + uL(fprintf(uH, "cttp: read 1: %s\n", uv_strerror(siz_w))); _cttp_ccon_fail(coc_u, u2_yes); } else { - _cttp_ccon_pars_shov(coc_u, buf_u->base, siz_i); + _cttp_ccon_pars_shov(coc_u, buf_u->base, siz_w); } if ( buf_u->base ) { free(buf_u->base); diff --git a/v/http.c b/v/http.c index 194eb5fdb..503a04e2b 100644 --- a/v/http.c +++ b/v/http.c @@ -565,18 +565,30 @@ _http_req_new(u2_hcon* hon_u) /* _http_conn_read_cb(): server read callback. */ +/* + * `nread` (siz_w) is > 0 if there is data available, 0 if libuv is done reading for + * now, or < 0 on error. + * + * The callee is responsible for closing the stream when an error happens + * by calling uv_close(). Trying to read from the stream again is undefined. + * + * The callee is responsible for freeing the buffer, libuv does not reuse it. + * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on + * error. + */ static void _http_conn_read_cb(uv_stream_t* tcp_u, - ssize_t siz_i, + ssize_t siz_w, const uv_buf_t * buf_u) { u2_hcon* hon_u = (u2_hcon*)(void*) tcp_u; u2_lo_open(); { - if ( siz_i < 0 ) { - // always an error in libuv 11 - uL(fprintf(uH, "http: read: ERROR\n")); + if ( siz_w == UV_EOF ) { + _http_conn_dead(hon_u); + } else if ( siz_w < 0 ) { + uL(fprintf(uH, "http: read: %s\n", uv_strerror(siz_w))); _http_conn_dead(hon_u); } else { @@ -584,10 +596,10 @@ _http_conn_read_cb(uv_stream_t* tcp_u, hon_u->ruc_u = _http_req_new(hon_u); } - if ( siz_i != http_parser_execute(hon_u->ruc_u->par_u, + if ( siz_w != http_parser_execute(hon_u->ruc_u->par_u, &_http_settings, (c3_c*)buf_u->base, - siz_i) ) + siz_w) ) { uL(fprintf(uH, "http: parse error\n")); _http_conn_dead(hon_u); @@ -609,8 +621,10 @@ _http_conn_new(u2_http *htp_u) uv_tcp_init(u2L, &hon_u->wax_u); - if ( 0 != uv_accept((uv_stream_t*)&htp_u->wax_u, - (uv_stream_t*)&hon_u->wax_u) ) + c3_w ret_w; + ret_w = uv_accept((uv_stream_t*)&htp_u->wax_u, + (uv_stream_t*)&hon_u->wax_u); + if (ret_w == UV_EOF) { uL(fprintf(uH, "http: accept: ERROR\n")); diff --git a/v/raft.c b/v/raft.c index 03468026b..75577ad13 100644 --- a/v/raft.c +++ b/v/raft.c @@ -81,7 +81,7 @@ _raft_readname(const c3_c* str_c, c3_w siz_w) c3_w nam_w; nam_u->str_c = c3_malloc(siz_w + 1); - strncpy(nam_u->str_c, str_c, siz_w); + strncpy(nam_u->str_c, str_c, siz_w + 1); nam_u->str_c[siz_w] = '\0'; if ( 0 == (col_c = strchr(nam_u->str_c, ':')) ) { @@ -92,7 +92,8 @@ _raft_readname(const c3_c* str_c, c3_w siz_w) else { nam_w = col_c - nam_u->str_c + 1; nam_u->nam_c = c3_malloc(nam_w); - strncpy(nam_u->nam_c, nam_u->str_c, nam_w); + strncpy(nam_u->nam_c, nam_u->str_c, nam_w + 1); + *(nam_u->nam_c + nam_w) = 0; nam_u->por_c = strdup(col_c + 1); } return nam_u; @@ -502,7 +503,7 @@ _raft_rmsg_read(const u2_rbuf* buf_u, u2_rmsg* msg_u) return -1; } msg_u->rest.nam_c = c3_malloc(4 * msg_u->rest.nam_w); - strncpy(msg_u->rest.nam_c, (const char*)(buf_u->buf_y + red_i), 4 * msg_u->rest.nam_w); // changed from uv_strlcpy + strncpy(msg_u->rest.nam_c, (const char*)(buf_u->buf_y + red_i), 4 * msg_u->rest.nam_w + 1); red_i += 4 * msg_u->rest.nam_w; break; } @@ -1152,7 +1153,7 @@ _raft_write_rest(u2_rcon* ron_u, c3_d lai_d, c3_w lat_w, u2_rmsg* msg_u) msg_u->rest.lat_w = lat_w; msg_u->rest.nam_w = 1 + strlen(raf_u->str_c) / 4; msg_u->rest.nam_c = calloc(1, 4 * msg_u->rest.nam_w); - strncpy(msg_u->rest.nam_c, raf_u->str_c, 4 * msg_u->rest.nam_w); // changed from strlcpy + strncpy(msg_u->rest.nam_c, raf_u->str_c, 4 * msg_u->rest.nam_w + 1); msg_u->len_d += 4 + msg_u->rest.nam_w; } diff --git a/v/term.c b/v/term.c index d01b0e141..fbc82e818 100644 --- a/v/term.c +++ b/v/term.c @@ -848,9 +848,10 @@ _term_read_tn_cb(uv_stream_t* tcp_u, u2_lo_open(); { - if ( siz_i < 0 ) { - - uL(fprintf(uH, "term: read: ERROR\n")); + if ( siz_i == UV_EOF ) { + // nothing + } else if ( siz_i < 0 ) { + uL(fprintf(uH, "term teln: read: %s\n", uv_strerror(siz_i))); uv_close((uv_handle_t*) tcp_u, _tel_close_cb); goto err; } @@ -866,13 +867,28 @@ _term_read_tn_cb(uv_stream_t* tcp_u, /* _term_suck(): process a chunk of input */ + +/* + * `nread` (siz_w) is > 0 if there is data available, 0 if libuv is done reading for + * now, or < 0 on error. + * + * The callee is responsible for closing the stream when an error happens + * by calling uv_close(). Trying to read from the stream again is undefined. + * + * The callee is responsible for freeing the buffer, libuv does not reuse it. + * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on + * error. + */ + static inline void _term_suck(u2_utty* uty_u, const c3_y* buf, ssize_t siz_i) { u2_lo_open(); { - if ( siz_i < 0 ) { - uL(fprintf(uH, "term %d: read: ERROR\n", uty_u->tid_l)); + if ( siz_i == UV_EOF ) { + // nothing + } else if ( siz_i < 0 ) { + uL(fprintf(uH, "term %d: read: %s\n", uty_u->tid_l, uv_strerror(siz_i))); } else { c3_i i; diff --git a/v/unix.c b/v/unix.c index 8e48759c2..9df72d5bf 100644 --- a/v/unix.c +++ b/v/unix.c @@ -181,9 +181,19 @@ _unix_fs_event_cb(uv_fs_event_t* was_u, c3_i evt_i, c3_i sas_i) { - u2_unod* nod_u = (void*)was_u; + + // note that we're doing something tricky and weird here. + // + // * libuv passes around a pointer to a uv_fs_event_t + // * we define a struct that STARTS with a uv_fs_event_t and then has + // more fields after it + // * this is what we pass into libuv up top + // * this is what we get out of libuv down below + // * thus a cast is cool + u2_unod* nod_u = (u2_unod*) was_u; #ifdef SYNCLOG + c3_w slot = u2_Host.unx_u.lot_w++ % 1024; free(u2_Host.unx_u.sylo[slot].pax_c); u2_Host.unx_u.sylo[slot].pax_c = 0; @@ -193,7 +203,7 @@ _unix_fs_event_cb(uv_fs_event_t* was_u, u2_Host.unx_u.sylo[slot].pax_c = strdup(nod_u->pax_c); #endif - // uL(fprintf(uH, "fs: %s in %s\n", pax_c, nod_u->pax_c)); + uL(fprintf(uH, "fs: %s in %s\n", pax_c, nod_u->pax_c)); { while ( nod_u ) { nod_u->dry = u2_no; @@ -210,24 +220,8 @@ _unix_file_watch(u2_ufil* fil_u, c3_c* pax_c, mpz_t mod_mp) { - uv_fs_event_t * eventhandle_u = (uv_fs_event_t * ) malloc(sizeof(uv_fs_event_t)) ; - c3_w ret_w = uv_fs_event_init(u2L, eventhandle_u ); - if (0 != ret_w){ - uL(fprintf(uH, "event init: %s\n", strerror(ret_w))); - c3_assert(0); - } - - ret_w = uv_fs_event_start(eventhandle_u, - _unix_fs_event_cb, - pax_c, - 0); - if (0 != ret_w){ - uL(fprintf(uH, "event start: %s\n", strerror(ret_w))); - c3_assert(0); - } - - - // uL(fprintf(uH, "file: got: %s (handle %d)\n", pax_c, fil_u->was_u.type)); + // (1) build data structure + // fil_u->non = u2_no; fil_u->dry = u2_no; fil_u->pax_c = pax_c; @@ -236,14 +230,37 @@ _unix_file_watch(u2_ufil* fil_u, c3_c* fas_c = strrchr(pax_c, '/'); fil_u->dot_c = dot_c ? (fas_c ? ((dot_c > fas_c) ? dot_c : 0) - : dot_c) - : 0; + : dot_c) + : 0; } fil_u->par_u = dir_u; mpz_init_set(fil_u->mod_mp, mod_mp); fil_u->nex_u = 0; c3_assert(!fil_u->dot_c || (fil_u->dot_c > fil_u->pax_c)); + + + // (2) stuff data structure into libuv + // + c3_w ret_w = uv_fs_event_init(u2L, // loop + &fil_u->was_u // uv_fs_event_t + ); + if (0 != ret_w){ + uL(fprintf(uH, "event init: %s\n", strerror(ret_w))); + c3_assert(0); + } + + // note that we're doing something tricky here; see comment in _unix_fs_event_cb + // + ret_w = uv_fs_event_start(&fil_u->was_u, // uv_fs_event_t + _unix_fs_event_cb, // callback + pax_c, // dir as strings + 0); // flags + if (0 != ret_w){ + uL(fprintf(uH, "event start: %s\n", strerror(ret_w))); + c3_assert(0); + } + } /* _unix_file_form(): form a filename path downward. @@ -283,14 +300,28 @@ _unix_file_form(u2_udir* dir_u, static void _unix_dir_watch(u2_udir* dir_u, u2_udir* par_u, c3_c* pax_c) { - uv_fs_event_t * eventhandle_u = (uv_fs_event_t * ) malloc(sizeof(uv_fs_event_t)) ; - c3_w ret_w = uv_fs_event_init(u2L, eventhandle_u ); + // (1) build data structure + // + dir_u->yes = u2_yes; + dir_u->dry = u2_no; + dir_u->pax_c = pax_c; + dir_u->par_u = par_u; + dir_u->dis_u = 0; + dir_u->fil_u = 0; + dir_u->nex_u = 0; + + + // (2) stuff data structure into libuv + // + c3_w ret_w = uv_fs_event_init(u2L, &dir_u->was_u ); if (0 != ret_w){ uL(fprintf(uH, "event init: %s\n", uv_strerror(ret_w))); c3_assert(0); } - ret_w = uv_fs_event_start(eventhandle_u, + // note that we're doing something tricky here; see comment in _unix_fs_event_cb + // + ret_w = uv_fs_event_start(&dir_u->was_u, _unix_fs_event_cb, pax_c, 0); @@ -299,14 +330,6 @@ _unix_dir_watch(u2_udir* dir_u, u2_udir* par_u, c3_c* pax_c) c3_assert(0); } - - dir_u->yes = u2_yes; - dir_u->dry = u2_no; - dir_u->pax_c = pax_c; - dir_u->par_u = par_u; - dir_u->dis_u = 0; - dir_u->fil_u = 0; - dir_u->nex_u = 0; } /* _unix_dir_forge: instantiate directory tracker (and make directory).