From 97e7a141236417c11edb8255f82aa7eb70eb8e89 Mon Sep 17 00:00:00 2001 From: Joe Bryan Date: Thu, 17 Nov 2022 23:44:12 -0500 Subject: [PATCH] u3: restages #6062 for release --- pkg/urbit/Makefile | 3 +- pkg/urbit/c/defs.c | 96 +++++++++++++++++ pkg/urbit/compat/mingw/compat.c | 57 ++++++++++ pkg/urbit/compat/mingw/compat.h | 2 + pkg/urbit/include/c/defs.h | 29 ++++++ pkg/urbit/include/vere/vere.h | 5 - pkg/urbit/noun/events.c | 178 ++++++++++---------------------- pkg/urbit/noun/manage.c | 6 +- pkg/urbit/noun/urth.c | 50 +-------- pkg/urbit/vere/io/http.c | 37 ++++--- pkg/urbit/vere/io/term.c | 54 ++-------- pkg/urbit/vere/io/unix.c | 55 +++++----- pkg/urbit/vere/king.c | 82 +++++---------- pkg/urbit/vere/lord.c | 2 +- 14 files changed, 329 insertions(+), 327 deletions(-) create mode 100644 pkg/urbit/c/defs.c diff --git a/pkg/urbit/Makefile b/pkg/urbit/Makefile index 6b934bc790..f867312754 100644 --- a/pkg/urbit/Makefile +++ b/pkg/urbit/Makefile @@ -2,6 +2,7 @@ include config.mk compat_mks := $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.mk)) include $(compat_mks) +c = $(wildcard c/*.c) jets = jets/tree.c $(wildcard jets/*/*.c) noun = $(wildcard noun/*.c) ur = $(wildcard ur/*.c) @@ -13,7 +14,7 @@ bench = $(wildcard bench/*.c) compat := $(foreach dir,$(compat),$(wildcard compat/$(dir)/*.c)) -common = $(jets) $(noun) $(ur) $(vere) $(compat) +common = $(c) $(jets) $(noun) $(ur) $(vere) $(compat) headers = $(shell find include -type f) common_objs = $(shell echo $(common) | sed 's/\.c/.o/g') diff --git a/pkg/urbit/c/defs.c b/pkg/urbit/c/defs.c new file mode 100644 index 0000000000..93a1d9b893 --- /dev/null +++ b/pkg/urbit/c/defs.c @@ -0,0 +1,96 @@ +/// @file defs.c + +#include "c/defs.h" + +/* c3_pread(): full positioned read(), up to eof, retrying errors. +*/ +ssize_t +c3_pread(c3_i fid_i, void* buf_v, size_t len_i, off_t off_i) +{ + c3_w max_w = 128; + c3_w try_w = 0; + size_t rem_i = len_i; + ssize_t ret_i; + + do { + if ( (0 > (ret_i = pread(fid_i, buf_v, rem_i, off_i))) + && ( (++try_w == max_w) + || ( (EINTR != errno) + && (EAGAIN != errno) + && (EWOULDBLOCK != errno) ))) + { + return -1; + } + else if ( 0 == ret_i ) { + break; + } + else { + buf_v = (void*)((c3_c*)buf_v + ret_i); + rem_i -= ret_i; + off_i += ret_i; + } + + } + while ( rem_i ); + + return len_i - rem_i; +} + +/* c3_pwrite(): full positioned write(), retrying errors. +*/ +ssize_t +c3_pwrite(c3_i fid_i, const void* buf_v, size_t len_i, off_t off_i) +{ + c3_w max_w = 128; + c3_w try_w = 0; + size_t rem_i = len_i; + ssize_t ret_i; + + do { + if ( (0 > (ret_i = pwrite(fid_i, buf_v, rem_i, off_i))) + && ( (++try_w == max_w) + || ( (EINTR != errno) + && (EAGAIN != errno) + && (EWOULDBLOCK != errno) ))) + { + return -1; + } + else { + buf_v = (void*)((c3_c*)buf_v + ret_i); + rem_i -= ret_i; + off_i += ret_i; + } + } + while ( rem_i ); + + return len_i; +} + +/* c3_write(): full write(), retrying errors. +*/ +ssize_t +c3_write(c3_i fid_i, const void* buf_v, size_t len_i) +{ + c3_w max_w = 128; + c3_w try_w = 0; + size_t rem_i = len_i; + ssize_t ret_i; + + do { + if ( (0 > (ret_i = write(fid_i, buf_v, rem_i))) + && ( (++try_w == max_w) + || ( (EINTR != errno) + && (EAGAIN != errno) + && (EWOULDBLOCK != errno) ))) + { + return -1; + } + else { + buf_v = (void*)((c3_c*)buf_v + ret_i); + rem_i -= ret_i; + } + } + while ( rem_i ); + + return len_i; +} diff --git a/pkg/urbit/compat/mingw/compat.c b/pkg/urbit/compat/mingw/compat.c index ebef5041fe..1bd1421285 100644 --- a/pkg/urbit/compat/mingw/compat.c +++ b/pkg/urbit/compat/mingw/compat.c @@ -144,6 +144,63 @@ int link(const char *path1, const char *path2) return -1; } +ssize_t pread(int fd, void *buf, size_t count, off_t offset) +{ + DWORD len = 0; + + OVERLAPPED overlapped = {0}; + + overlapped.OffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((offset >> 32) & 0xFFFFFFFFL); + overlapped.Offset = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)offset : (DWORD)(offset & 0xFFFFFFFFL); + + HANDLE h = (HANDLE)_get_osfhandle(fd); + + if ( INVALID_HANDLE_VALUE == h ) { + errno = EBADF; + return -1; + } + + if ( !ReadFile(h, buf, count, &len, &overlapped) ) { + DWORD err = GetLastError(); + + if ( ERROR_HANDLE_EOF != err ) { + errno = err_win_to_posix(err); + return -1; + } + } + + return (ssize_t)len; +} + +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) +{ + DWORD len = 0; + + OVERLAPPED overlapped = {0}; + + overlapped.OffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((offset >> 32) & 0xFFFFFFFFL); + overlapped.Offset = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)offset : (DWORD)(offset & 0xFFFFFFFFL); + + HANDLE h = (HANDLE)_get_osfhandle(fd); + + if ( INVALID_HANDLE_VALUE == h ) { + errno = EBADF; + return -1; + } + + if ( !WriteFile(h, buf, count, &len, &overlapped) ) { + errno = err_win_to_posix(GetLastError()); + return -1; + } + + return (ssize_t)len; +} + + // from msys2 mingw-packages-dev patches // ----------------------------------------------------------------------- diff --git a/pkg/urbit/compat/mingw/compat.h b/pkg/urbit/compat/mingw/compat.h index 56c35e90ae..80809f54b3 100644 --- a/pkg/urbit/compat/mingw/compat.h +++ b/pkg/urbit/compat/mingw/compat.h @@ -4,6 +4,8 @@ #define mkdir(A, B) mkdir(A) int link(const char *path1, const char *path2); +ssize_t pread(int fd, void *buf, size_t count, off_t offset); +ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); char *realpath(const char *path, char *resolved_path); int fdatasync(int fd); int utimes(const char *path, const struct timeval times[2]); diff --git a/pkg/urbit/include/c/defs.h b/pkg/urbit/include/c/defs.h index b649a8866d..a667b85a25 100644 --- a/pkg/urbit/include/c/defs.h +++ b/pkg/urbit/include/c/defs.h @@ -1,6 +1,11 @@ #ifndef C3_DEFS_H #define C3_DEFS_H +#include "c/portable.h" +#include "c/types.h" + +#include + /** Loobeans - inverse booleans to match nock. **/ # define c3y 0 @@ -157,4 +162,28 @@ # define c3_fopen(a, b) ({ \ fopen(a, b);}) + /** i/o wrappers + *** + *** these handle partial success and retry ephemeral errors + *** up to hardcoded max try count, either reading/writing fully + *** (up to EOF on read) or returning on error. + *** + *** a wrapper for read() is not provided, as file cursor position + *** is undefined on error. use pread() or loop yourself. + **/ + /* c3_pread(): full positioned read(), up to eof, retrying errors. + */ + ssize_t + c3_pread(c3_i fid_i, void* buf_v, size_t len_i, off_t off_i); + + /* c3_pwrite(): full positioned write(), retrying errors. + */ + ssize_t + c3_pwrite(c3_i fid_i, const void* buf_v, size_t len_i, off_t off_i); + + /* c3_write(): full write(), retrying errors. + */ + ssize_t + c3_write(c3_i fid_i, const void* buf_v, size_t len_i); + #endif /* ifndef C3_DEFS_H */ diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index d02771343f..f02bf4a46d 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -1461,11 +1461,6 @@ void u3_daemon_init(); - /* u3_write_fd(): retry interrupts, continue partial writes, assert errors. - */ - void - u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_i); - c3_w u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); diff --git a/pkg/urbit/noun/events.c b/pkg/urbit/noun/events.c index ceec1bd411..c1d53eebb7 100644 --- a/pkg/urbit/noun/events.c +++ b/pkg/urbit/noun/events.c @@ -354,17 +354,11 @@ _ce_image_open(u3e_image* img_u) static void _ce_patch_write_control(u3_ce_patch* pat_u) { - ssize_t ret_i; - c3_w len_w = sizeof(u3e_control) + - (pat_u->con_u->pgs_w * sizeof(u3e_line)); + c3_w len_w = sizeof(u3e_control) + + (pat_u->con_u->pgs_w * sizeof(u3e_line)); - if ( len_w != (ret_i = write(pat_u->ctl_i, pat_u->con_u, len_w)) ) { - if ( 0 < ret_i ) { - fprintf(stderr, "loom: patch ctl partial write: %zu\r\n", (size_t)ret_i); - } - else { - fprintf(stderr, "loom: patch ctl write: %s\r\n", strerror(errno)); - } + if ( 0 > c3_pwrite(pat_u->ctl_i, pat_u->con_u, len_w, 0) ) { + fprintf(stderr, "loom: patch write: %s\r\n", strerror(errno)); c3_assert(0); } } @@ -388,8 +382,9 @@ _ce_patch_read_control(u3_ce_patch* pat_u) } pat_u->con_u = c3_malloc(len_w); - if ( (len_w != read(pat_u->ctl_i, pat_u->con_u, len_w)) || - (len_w != sizeof(u3e_control) + + + if ( (len_w != c3_pread(pat_u->ctl_i, pat_u->con_u, len_w, 0)) + || (len_w != sizeof(u3e_control) + (pat_u->con_u->pgs_w * sizeof(u3e_line))) ) { c3_free(pat_u->con_u); @@ -450,8 +445,10 @@ _ce_patch_delete(void) static c3_o _ce_patch_verify(u3_ce_patch* pat_u) { - ssize_t ret_i; - c3_w i_w; + c3_w i_w, pag_w, mug_w; + c3_w mem_w[pag_wiz_i]; + size_t off_i, siz_i = pag_siz_i; + ssize_t ret_i; if ( u3e_version != pat_u->con_u->ver_y ) { fprintf(stderr, "loom: patch version mismatch: have %u, need %u\r\n", @@ -461,15 +458,11 @@ _ce_patch_verify(u3_ce_patch* pat_u) } for ( i_w = 0; i_w < pat_u->con_u->pgs_w; i_w++ ) { - c3_w pag_w = pat_u->con_u->mem_u[i_w].pag_w; - c3_w mug_w = pat_u->con_u->mem_u[i_w].mug_w; - c3_w mem_w[1 << u3a_page]; + pag_w = pat_u->con_u->mem_u[i_w].pag_w; + mug_w = pat_u->con_u->mem_u[i_w].mug_w; + off_i = i_w << (u3a_page + 2); - if ( -1 == lseek(pat_u->mem_i, (i_w << (u3a_page + 2)), SEEK_SET) ) { - fprintf(stderr, "loom: patch seek: %s\r\n", strerror(errno)); - return c3n; - } - if ( pag_siz_i != (ret_i = read(pat_u->mem_i, mem_w, pag_siz_i)) ) { + if ( siz_i != (ret_i = c3_pread(pat_u->mem_i, mem_w, siz_i, off_i)) ) { if ( 0 < ret_i ) { fprintf(stderr, "loom: patch partial read: %zu\r\n", (size_t)ret_i); } @@ -562,21 +555,10 @@ _ce_patch_write_page(u3_ce_patch* pat_u, c3_w pgc_w, c3_w* mem_w) { - ssize_t ret_i; + size_t off_i = pgc_w << (u3a_page + 2); - if ( -1 == lseek(pat_u->mem_i, pgc_w * pag_siz_i, SEEK_SET) ) { - fprintf(stderr, "loom: patch page seek: %s\r\n", strerror(errno)); - c3_assert(0); - } - - if ( pag_siz_i != (ret_i = write(pat_u->mem_i, mem_w, pag_siz_i)) ) { - if ( 0 < ret_i ) { - fprintf(stderr, "loom: patch page partial write: %zu\r\n", - (size_t)ret_i); - } - else { - fprintf(stderr, "loom: patch page write: %s\r\n", strerror(errno)); - } + if ( 0 > c3_pwrite(pat_u->mem_i, mem_w, pag_siz_i, off_i) ) { + fprintf(stderr, "loom: patch write: %s\r\n", strerror(errno)); c3_assert(0); } } @@ -753,31 +735,20 @@ _ce_image_resize(u3e_image* img_u, c3_w pgs_w) static void _ce_patch_apply(u3_ce_patch* pat_u) { - ssize_t ret_i; - c3_w i_w; + c3_w i_w, pag_w, off_w, mem_w[pag_wiz_i]; + c3_i fid_i; + size_t rof_i, wof_i, siz_i = pag_siz_i; + ssize_t ret_i; // resize images // _ce_image_resize(&u3P.nor_u, pat_u->con_u->nor_w); _ce_image_resize(&u3P.sou_u, pat_u->con_u->sou_w); - // seek to begining of patch and images - // - if ( (-1 == lseek(pat_u->mem_i, 0, SEEK_SET)) - || (-1 == lseek(u3P.nor_u.fid_i, 0, SEEK_SET)) - || (-1 == lseek(u3P.sou_u.fid_i, 0, SEEK_SET)) ) - { - fprintf(stderr, "loom: patch apply seek 0: %s\r\n", strerror(errno)); - c3_assert(0); - } - // write patch pages into the appropriate image // for ( i_w = 0; i_w < pat_u->con_u->pgs_w; i_w++ ) { - c3_w pag_w = pat_u->con_u->mem_u[i_w].pag_w; - c3_w mem_w[pag_wiz_i]; - c3_i fid_i; - c3_w off_w; + pag_w = pat_u->con_u->mem_u[i_w].pag_w; if ( pag_w < pat_u->con_u->nor_w ) { fid_i = u3P.nor_u.fid_i; @@ -788,7 +759,10 @@ _ce_patch_apply(u3_ce_patch* pat_u) off_w = (u3P.pag_w - (pag_w + 1)); } - if ( pag_siz_i != (ret_i = read(pat_u->mem_i, mem_w, pag_siz_i)) ) { + rof_i = (size_t)i_w << (u3a_page + 2); + wof_i = (size_t)off_w << (u3a_page + 2); + + if ( siz_i != (ret_i = c3_pread(pat_u->mem_i, mem_w, siz_i, rof_i))) { if ( 0 < ret_i ) { fprintf(stderr, "loom: patch apply partial read: %zu\r\n", (size_t)ret_i); @@ -798,21 +772,10 @@ _ce_patch_apply(u3_ce_patch* pat_u) } c3_assert(0); } - else { - if ( -1 == lseek(fid_i, (off_w << (u3a_page + 2)), SEEK_SET) ) { - fprintf(stderr, "loom: patch apply seek: %s\r\n", strerror(errno)); - c3_assert(0); - } - if ( pag_siz_i != (ret_i = write(fid_i, mem_w, pag_siz_i)) ) { - if ( 0 < ret_i ) { - fprintf(stderr, "loom: patch apply partial write: %zu\r\n", - (size_t)ret_i); - } - else { - fprintf(stderr, "loom: patch apply write: %s\r\n", strerror(errno)); - } - c3_assert(0); - } + + if ( 0 > c3_pwrite(fid_i, mem_w, siz_i, wof_i) ) { + fprintf(stderr, "loom: patch apply write: %s\r\n", strerror(errno)); + c3_assert(0); } #if 0 u3l_log("apply: %d, %x\n", pag_w, u3r_mug_words(mem_w, pag_wiz_i)); @@ -827,22 +790,18 @@ _ce_image_blit(u3e_image* img_u, c3_w* ptr_w, c3_ws stp_ws) { + c3_w i_w; + size_t off_i, siz_i = pag_siz_i; + ssize_t ret_i; + if ( 0 == img_u->pgs_w ) { return; } - ssize_t ret_i; - c3_w i_w; - c3_w siz_w = pag_siz_i; - - if ( -1 == lseek(img_u->fid_i, 0, SEEK_SET) ) { - fprintf(stderr, "loom: image (%s) blit seek 0: %s\r\n", - img_u->nam_c, strerror(errno)); - c3_assert(0); - } - for ( i_w = 0; i_w < img_u->pgs_w; i_w++ ) { - if ( siz_w != (ret_i = read(img_u->fid_i, ptr_w, siz_w)) ) { + off_i = (size_t)i_w << (u3a_page + 2); + + if ( siz_i != (ret_i = c3_pread(img_u->fid_i, ptr_w, siz_i, off_i)) ) { if ( 0 < ret_i ) { fprintf(stderr, "loom: image (%s) blit partial read: %zu\r\n", img_u->nam_c, (size_t)ret_i); @@ -854,7 +813,7 @@ _ce_image_blit(u3e_image* img_u, c3_assert(0); } - if ( 0 != mprotect(ptr_w, siz_w, PROT_READ) ) { + if ( 0 != mprotect(ptr_w, siz_i, PROT_READ) ) { fprintf(stderr, "loom: live mprotect: %s\r\n", strerror(errno)); c3_assert(0); } @@ -876,19 +835,15 @@ _ce_image_fine(u3e_image* img_u, c3_w* ptr_w, c3_ws stp_ws) { - ssize_t ret_i; - c3_w i_w; - c3_w buf_w[pag_wiz_i]; - - if ( -1 == lseek(img_u->fid_i, 0, SEEK_SET) ) { - fprintf(stderr, "loom: image fine seek 0: %s\r\n", strerror(errno)); - c3_assert(0); - } + c3_w i_w, mem_w, fil_w; + c3_w buf_w[pag_wiz_i]; + size_t off_i, siz_i = pag_siz_i; + ssize_t ret_i; for ( i_w=0; i_w < img_u->pgs_w; i_w++ ) { - c3_w mem_w, fil_w; + off_i = (size_t)i_w << (u3a_page + 2); - if ( pag_siz_i != (ret_i = read(img_u->fid_i, buf_w, pag_siz_i)) ) { + if ( siz_i != (ret_i = c3_pread(img_u->fid_i, buf_w, siz_i, off_i)) ) { if ( 0 < ret_i ) { fprintf(stderr, "loom: image (%s) fine partial read: %zu\r\n", img_u->nam_c, (size_t)ret_i); @@ -899,6 +854,7 @@ _ce_image_fine(u3e_image* img_u, } c3_assert(0); } + mem_w = u3r_mug_words(ptr_w, pag_wiz_i); fil_w = u3r_mug_words(buf_w, pag_wiz_i); @@ -924,31 +880,21 @@ _ce_image_fine(u3e_image* img_u, static c3_o _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u) { + c3_w i_w; + c3_w mem_w[pag_wiz_i]; + size_t off_i, siz_i = pag_siz_i; ssize_t ret_i; - c3_w i_w; // resize images // _ce_image_resize(tou_u, fom_u->pgs_w); - // seek to begining of patch and images - // - if ( (-1 == lseek(fom_u->fid_i, 0, SEEK_SET)) - || (-1 == lseek(tou_u->fid_i, 0, SEEK_SET)) ) - { - fprintf(stderr, "loom: image (%s) copy seek: %s\r\n", - fom_u->nam_c, - strerror(errno)); - return c3n; - } - // copy pages into destination image // for ( i_w = 0; i_w < fom_u->pgs_w; i_w++ ) { - c3_w mem_w[pag_wiz_i]; - c3_w off_w = i_w; + off_i = (size_t)i_w << (u3a_page + 2); - if ( pag_siz_i != (ret_i = read(fom_u->fid_i, mem_w, pag_siz_i)) ) { + if ( siz_i != (ret_i = c3_pread(fom_u->fid_i, mem_w, siz_i, off_i)) ) { if ( 0 < ret_i ) { fprintf(stderr, "loom: image (%s) copy partial read: %zu\r\n", fom_u->nam_c, (size_t)ret_i); @@ -959,23 +905,11 @@ _ce_image_copy(u3e_image* fom_u, u3e_image* tou_u) } return c3n; } - else { - if ( -1 == lseek(tou_u->fid_i, (off_w << (u3a_page + 2)), SEEK_SET) ) { - fprintf(stderr, "loom: image (%s) copy seek: %s\r\n", - tou_u->nam_c, strerror(errno)); - return c3n; - } - if ( pag_siz_i != (ret_i = write(tou_u->fid_i, mem_w, pag_siz_i)) ) { - if ( 0 < ret_i ) { - fprintf(stderr, "loom: image (%s) copy partial write: %zu\r\n", - tou_u->nam_c, (size_t)ret_i); - } - else { - fprintf(stderr, "loom: image (%s) copy write: %s\r\n", - tou_u->nam_c, strerror(errno)); - } - return c3n; - } + + if ( 0 > c3_pwrite(tou_u->fid_i, mem_w, siz_i, off_i) ) { + fprintf(stderr, "loom: image (%s) copy write: %s\r\n", + tou_u->nam_c, strerror(errno)); + return c3n; } } diff --git a/pkg/urbit/noun/manage.c b/pkg/urbit/noun/manage.c index aa33b03287..12d4d0fe92 100644 --- a/pkg/urbit/noun/manage.c +++ b/pkg/urbit/noun/manage.c @@ -435,7 +435,7 @@ u3m_file(c3_c* pas_c) { struct stat buf_b; c3_i fid_i = c3_open(pas_c, O_RDONLY, 0644); - c3_w fln_w, red_w; + c3_w fln_w; c3_y* pad_y; if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) { @@ -445,10 +445,10 @@ u3m_file(c3_c* pas_c) fln_w = buf_b.st_size; pad_y = c3_malloc(buf_b.st_size); - red_w = read(fid_i, pad_y, fln_w); + ssize_t red_i = c3_pread(fid_i, pad_y, fln_w, 0); close(fid_i); - if ( fln_w != red_w ) { + if ( red_i != fln_w ) { c3_free(pad_y); return u3m_bail(c3__fail); } diff --git a/pkg/urbit/noun/urth.c b/pkg/urbit/noun/urth.c index 30ab448173..0b8f022944 100644 --- a/pkg/urbit/noun/urth.c +++ b/pkg/urbit/noun/urth.c @@ -564,56 +564,14 @@ _cu_rock_save(c3_c* dir_c, c3_d eve_d, c3_d len_d, c3_y* byt_y) // write jam-buffer into [fid_i] // - // XX deduplicate with _write() wrapper in term.c - // - { - ssize_t ret_i; - - while ( len_d > 0 ) { - c3_w lop_w = 0; - // retry interrupt/async errors - // - do { - // abort pathological retry loop - // - if ( 100 == ++lop_w ) { - fprintf(stderr, "rock: write loop: %s\r\n", strerror(errno)); - close(fid_i); - // XX unlink file? - // - return c3n; - } - - ret_i = write(fid_i, byt_y, len_d); - } - while ( (ret_i < 0) - && ( (errno == EINTR) - || (errno == EAGAIN) - || (errno == EWOULDBLOCK) )); - - // assert on true errors - // - // NB: can't call u3l_log here or we would re-enter _write() - // - if ( ret_i < 0 ) { - fprintf(stderr, "rock: write failed %s\r\n", strerror(errno)); - close(fid_i); - // XX unlink file? - // - return c3n; - } - // continue partial writes - // - else { - len_d -= ret_i; - byt_y += ret_i; - } - } + ssize_t rit_i = c3_pwrite(fid_i, byt_y, len_d, 0); + if ( rit_i < 0 ) { + fprintf(stderr, "rock: write failed: %s\r\n", strerror(errno)); } close(fid_i); - return c3y; + return rit_i < 0 ? c3n : c3y; } /* u3u_cram(): globably deduplicate memory, and write a rock to disk. diff --git a/pkg/urbit/vere/io/http.c b/pkg/urbit/vere/io/http.c index fa7d778f2c..a564c46ce4 100644 --- a/pkg/urbit/vere/io/http.c +++ b/pkg/urbit/vere/io/http.c @@ -1677,24 +1677,30 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u) static void _http_write_ports_file(u3_httd* htd_u, c3_c *pax_c) { - c3_c* nam_c = ".http.ports"; - c3_w len_w = 1 + strlen(pax_c) + 1 + strlen(nam_c); - - c3_c* paf_c = c3_malloc(len_w); - snprintf(paf_c, len_w, "%s/%s", pax_c, nam_c); - - c3_i por_i = c3_open(paf_c, O_WRONLY | O_CREAT | O_TRUNC, 0666); - c3_free(paf_c); - u3_http* htp_u = htd_u->htp_u; u3_pier* pir_u = htd_u->car_u.pir_u; + size_t off_i = 0; + c3_i por_i; + + { + c3_c* nam_c = ".http.ports"; + c3_w len_w = 1 + strlen(pax_c) + 1 + strlen(nam_c); + c3_c* paf_c = c3_malloc(len_w); + snprintf(paf_c, len_w, "%s/%s", pax_c, nam_c); + por_i = c3_open(paf_c, O_WRONLY | O_CREAT | O_TRUNC, 0666); + c3_free(paf_c); + } - c3_c temp[32]; while ( 0 != htp_u ) { if ( 0 < htp_u->por_s ) { - u3_write_fd(por_i, temp, snprintf(temp, 32, "%u %s %s\n", htp_u->por_s, - (c3y == htp_u->sec) ? "secure" : "insecure", - (c3y == htp_u->lop) ? "loopback" : "public")); + c3_c tmp_c[32]; + c3_i len_i = snprintf(tmp_c, 32, "%u %s %s\n", + htp_u->por_s, + (c3y == htp_u->sec) ? "secure" : "insecure", + (c3y == htp_u->lop) ? "loopback" : "public"); + c3_assert( 0 < len_i); + c3_assert( c3_pwrite(por_i, tmp_c, len_i, off_i) == len_i ); + off_i += len_i; } htp_u = htp_u->nex_u; @@ -1710,13 +1716,12 @@ static void _http_release_ports_file(c3_c *pax_c) { c3_c* nam_c = ".http.ports"; - c3_w len_w = 1 + strlen(pax_c) + 1 + strlen(nam_c); + c3_w len_w = 1 + strlen(pax_c) + 1 + strlen(nam_c); c3_c* paf_c = c3_malloc(len_w); c3_i wit_i; wit_i = snprintf(paf_c, len_w, "%s/%s", pax_c, nam_c); - c3_assert(wit_i > 0); - c3_assert(len_w == (c3_w)wit_i + 1); + c3_assert( len_w == (c3_w)wit_i + 1 ); c3_unlink(paf_c); c3_free(paf_c); diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 9994fcfcb3..d13bbb9ae6 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -17,48 +17,6 @@ static void _term_read_cb(uv_stream_t* tcp_u, ssize_t siz_i, const uv_buf_t* buf_u); -/* u3_write_fd(): retry interrupts, continue partial writes, assert errors. -*/ -void -u3_write_fd(c3_i fid_i, const void* buf_v, size_t len_i) -{ - ssize_t ret_i; - - while ( len_i > 0 ) { - c3_w lop_w = 0; - // retry interrupt/async errors - // - do { - // abort pathological retry loop - // - if ( 100 == ++lop_w ) { - fprintf(stderr, "term: write loop: %s\r\n", strerror(errno)); - return; - } - ret_i = write(fid_i, buf_v, len_i); - } - while ( (ret_i < 0) - && ( (errno == EINTR) - || (errno == EAGAIN) - || (errno == EWOULDBLOCK) )); - - // assert on true errors - // - // NB: can't call u3l_log here or we would re-enter u3_write_fd() - // - if ( ret_i < 0 ) { - fprintf(stderr, "term: write failed %s\r\n", strerror(errno)); - c3_assert(0); - } - // continue partial writes - // - else { - len_i -= ret_i; - buf_v += ret_i; - } - } -} - /* _term_msc_out_host(): unix microseconds from current host time. */ static c3_d @@ -255,7 +213,7 @@ u3_term_log_exit(void) if ( c3n == uty_u->sto_f(uty_u) ) { c3_assert(!"exit-tcsetattr"); } - u3_write_fd(uty_u->fid_i, "\r\n", 2); + c3_assert(c3_write(uty_u->fid_i, "\r\n", 2) == 2); } } @@ -864,7 +822,7 @@ _term_spin_step(u3_utty* uty_u) c3_w i_w; for ( i_w = bac_w; i_w < sol_w; i_w++ ) { - if ( lef_u.len != write(fid_i, lef_u.base, lef_u.len) ) { + if ( c3_write(fid_i, lef_u.base, lef_u.len) < 0 ) { return; } } @@ -874,7 +832,7 @@ _term_spin_step(u3_utty* uty_u) { c3_w len_w = cur_c - buf_c; - if ( len_w != write(fid_i, buf_c, len_w) ) { + if ( c3_write(fid_i, buf_c, len_w) < 0 ) { return; } } @@ -882,7 +840,7 @@ _term_spin_step(u3_utty* uty_u) // Cursor stays on spinner. // while ( sol_w-- ) { - if ( lef_u.len != write(fid_i, lef_u.base, lef_u.len) ) { + if ( c3_write(fid_i, lef_u.base, lef_u.len) < 0 ) { return; } } @@ -1382,10 +1340,10 @@ u3_term_io_hija(void) if ( c3y != uty_u->hij_f(uty_u) ) { c3_assert(!"hija-tcsetattr"); } - u3_write_fd(uty_u->fid_i, "\r", 1); + c3_assert(c3_write(uty_u->fid_i, "\r", 1) == 1); { uv_buf_t* buf_u = &uty_u->ufo_u.out.el_u; - u3_write_fd(uty_u->fid_i, buf_u->base, buf_u->len); + c3_assert(c3_write(uty_u->fid_i, buf_u->base, buf_u->len) == buf_u->len); } } } diff --git a/pkg/urbit/vere/io/unix.c b/pkg/urbit/vere/io/unix.c index f9e175b5d2..ba0145d710 100644 --- a/pkg/urbit/vere/io/unix.c +++ b/pkg/urbit/vere/io/unix.c @@ -342,11 +342,11 @@ u3_unix_save(c3_c* pax_c, u3_atom pad) pad_y = c3_malloc(fln_w); u3r_bytes(0, fln_w, pad_y, pad); u3z(pad); - rit_w = write(fid_i, pad_y, fln_w); + ssize_t rit_i = c3_pwrite(fid_i, pad_y, fln_w, 0); close(fid_i); c3_free(pad_y); - if ( rit_w != fln_w ) { + if ( rit_i < 0 ) { u3l_log("%s: %s\n", ful_c, strerror(errno)); c3_free(ful_c); u3m_bail(c3__fail); @@ -427,7 +427,7 @@ static c3_w _unix_write_file_hard(c3_c* pax_c, u3_noun mim) { c3_i fid_i = c3_open(pax_c, O_WRONLY | O_CREAT | O_TRUNC, 0666); - c3_w len_w, rit_w, siz_w, mug_w = 0; + c3_w len_w, siz_w, mug_w = 0; c3_y* dat_y; u3_noun dat = u3t(u3t(mim)); @@ -446,11 +446,10 @@ _unix_write_file_hard(c3_c* pax_c, u3_noun mim) u3r_bytes(0, len_w, dat_y, dat); u3z(mim); - rit_w = write(fid_i, dat_y, siz_w); + ssize_t rit_i = c3_pwrite(fid_i, dat_y, siz_w, 0); - if ( rit_w != siz_w ) { - u3l_log("error writing %s: %s\r\n", - pax_c, strerror(errno)); + if ( rit_i < 0 ) { + u3l_log("error writing %s: %s\r\n", pax_c, strerror(errno)); mug_w = 0; } else { @@ -470,7 +469,7 @@ _unix_write_file_soft(u3_ufil* fil_u, u3_noun mim) { struct stat buf_u; c3_i fid_i = c3_open(fil_u->pax_c, O_RDONLY, 0644); - c3_ws len_ws, red_ws; + c3_ws len_ws; c3_w old_w; c3_y* old_y; @@ -489,21 +488,21 @@ _unix_write_file_soft(u3_ufil* fil_u, u3_noun mim) len_ws = buf_u.st_size; old_y = c3_malloc(len_ws); - red_ws = read(fid_i, old_y, len_ws); + ssize_t red_i = c3_pread(fid_i, old_y, len_ws, 0); if ( close(fid_i) < 0 ) { u3l_log("error closing file (soft) %s: %s\r\n", fil_u->pax_c, strerror(errno)); } - if ( len_ws != red_ws ) { - if ( red_ws < 0 ) { + if ( red_i != len_ws ) { + if ( red_i < 0 ) { u3l_log("error reading file (soft) %s: %s\r\n", - fil_u->pax_c, strerror(errno)); + fil_u->pax_c, strerror(-red_i)); } else { - u3l_log("wrong # of bytes read in file %s: %d %d\r\n", - fil_u->pax_c, len_ws, red_ws); + u3l_log("wrong # of bytes read in file %s: %u %zu\r\n", + fil_u->pax_c, len_ws, red_i); } c3_free(old_y); u3z(mim); @@ -893,7 +892,7 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u) struct stat buf_u; c3_i fid_i = c3_open(fil_u->pax_c, O_RDONLY, 0644); - c3_ws len_ws, red_ws; + c3_ws len_ws; c3_y* dat_y; if ( fid_i < 0 || fstat(fid_i, &buf_u) < 0 ) { @@ -910,21 +909,21 @@ _unix_update_file(u3_unix* unx_u, u3_ufil* fil_u) len_ws = buf_u.st_size; dat_y = c3_malloc(len_ws); - red_ws = read(fid_i, dat_y, len_ws); + ssize_t red_i = c3_pread(fid_i, dat_y, len_ws, 0); if ( close(fid_i) < 0 ) { u3l_log("error closing file %s: %s\r\n", fil_u->pax_c, strerror(errno)); } - if ( len_ws != red_ws ) { - if ( red_ws < 0 ) { + if ( red_i != len_ws ) { + if ( red_i < 0 ) { u3l_log("error reading file %s: %s\r\n", - fil_u->pax_c, strerror(errno)); + fil_u->pax_c, strerror(-red_i)); } else { - u3l_log("wrong # of bytes read in file %s: %d %d\r\n", - fil_u->pax_c, len_ws, red_ws); + u3l_log("wrong # of bytes read in file %s: %u %zu\r\n", + fil_u->pax_c, len_ws, red_i); } c3_free(dat_y); return u3_nul; @@ -1159,7 +1158,7 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c) { struct stat buf_u; c3_i fid_i = c3_open(pax_c, O_RDONLY, 0644); - c3_ws len_ws, red_ws; + c3_ws len_ws; c3_y* dat_y; if ( fid_i < 0 || fstat(fid_i, &buf_u) < 0 ) { @@ -1176,21 +1175,21 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c) len_ws = buf_u.st_size; dat_y = c3_malloc(len_ws); - red_ws = read(fid_i, dat_y, len_ws); + ssize_t red_i = c3_pread(fid_i, dat_y, len_ws, 0); if ( close(fid_i) < 0 ) { u3l_log("error closing initial file %s: %s\r\n", pax_c, strerror(errno)); } - if ( len_ws != red_ws ) { - if ( red_ws < 0 ) { + if ( red_i != len_ws ) { + if ( red_i < 0 ) { u3l_log("error reading initial file %s: %s\r\n", - pax_c, strerror(errno)); + pax_c, strerror(-red_i)); } else { - u3l_log("wrong # of bytes read in initial file %s: %d %d\r\n", - pax_c, len_ws, red_ws); + u3l_log("wrong # of bytes read in initial file %s: %u %zu\r\n", + pax_c, len_ws, red_i); } c3_free(dat_y); return u3_nul; diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/king.c index 44a8cd502a..b18d7b441b 100644 --- a/pkg/urbit/vere/king.c +++ b/pkg/urbit/vere/king.c @@ -307,7 +307,7 @@ _king_get_pace(void) { struct stat buf_u; c3_c* pat_c; - c3_w red_w, len_w; + c3_w len_w; c3_i ret_i, fid_i; ret_i = asprintf(&pat_c, "%s/.bin/pace", u3_Host.dir_c); @@ -324,10 +324,10 @@ _king_get_pace(void) len_w = buf_u.st_size; pat_c = c3_malloc(len_w + 1); - red_w = read(fid_i, pat_c, len_w); + ssize_t red_i = c3_pread(fid_i, pat_c, len_w, 0); close(fid_i); - if ( len_w != red_w ) { + if ( red_i != len_w ) { c3_free(pat_c); u3l_log("unable to read pace file, " "falling back to default (\"live\")\n"); @@ -1038,9 +1038,6 @@ _king_make_pace(c3_c* pac_c) return 0; } -static c3_i -_king_write_raw(c3_i fid_i, c3_y* buf_y, size_t len_i); - /* _king_init_pace(): save pace file if not present */ static c3_i @@ -1064,8 +1061,11 @@ _king_init_pace(c3_c* pac_c) } } - if ( _king_write_raw(fid_i, (c3_y*)pac_c, strlen(pac_c)) ) { - u3l_log("dock: init pace (%s): write %s\n", pac_c, strerror(errno)); + size_t len_i = strlen(pac_c); + ssize_t wit_i = c3_pwrite(fid_i, pac_c, len_i, 0); + if ( wit_i != len_i ) { + u3l_log("dock: init pace (%s) write failed: %s\n", + pac_c, strerror(errno)); close(fid_i); c3_free(bin_c); return -1; @@ -1239,62 +1239,24 @@ _king_do_upgrade(c3_c* pac_c, c3_c* ver_c) // XX print restart instructions } -/* _king_read_raw: read (up to) [len_i] from [fid_i] to [buf_y] -*/ -static ssize_t -_king_read_raw(c3_i fid_i, c3_y* buf_y, size_t len_i) -{ - ssize_t ret_i; - - do { - ret_i = read(fid_i, buf_y, len_i); - } - while ( (ret_i < 0) && (errno == EINTR) ); - - return ret_i; -} - -/* _king_read_raw: write [len_i] from [buf_y] to [fid_i]. -*/ -static c3_i -_king_write_raw(c3_i fid_i, c3_y* buf_y, size_t len_i) -{ - ssize_t ret_i; - - while ( len_i ) { - - do { - ret_i = write(fid_i, buf_y, len_i); - } - while ( (ret_i < 0) && (errno == EINTR) ); - - if ( ret_i < 0 ) { - return -1; - } - else { - len_i -= ret_i; - buf_y += ret_i; - } - } - - return 0; -} - static c3_i _king_copy_raw(c3_i src_i, c3_i dst_i, c3_y* buf_y, size_t pag_i) { - ssize_t red_i; + size_t off_i = 0; + ssize_t ret_i; do { - if ( 0 > (red_i = _king_read_raw(src_i, buf_y, pag_i)) ) { - return -1; + if ( 0 > (ret_i = c3_pread(src_i, buf_y, pag_i, off_i)) ) { + return ret_i; } - if ( _king_write_raw(dst_i, buf_y, (size_t)red_i) ) { - return -1; + if ( 0 > (ret_i = c3_pwrite(dst_i, buf_y, (size_t)ret_i, off_i)) ) { + return ret_i; } + + off_i += (size_t)ret_i; } - while ( red_i ); + while ( ret_i ); return 0; } @@ -1337,6 +1299,8 @@ _king_copy_file(c3_c* src_c, c3_c* dst_c) goto done1; } + // XX O_TRUNC? + // if ( -1 == (dst_i = open(dst_c, O_RDWR | O_CREAT, 0755)) ) { err_i = errno; ret_i = -1; @@ -1403,8 +1367,12 @@ _king_copy_file(c3_c* src_c, c3_c* dst_c) { size_t pag_i = 1 << 14;; c3_y* buf_y = c3_malloc(pag_i); - ret_i = _king_copy_raw(src_i, dst_i, buf_y, pag_i); - err_i = errno; + + if ( 0 > (ret_i = _king_copy_raw(src_i, dst_i, buf_y, pag_i)) ) { + err_i = errno; + ret_i = -1; + } + c3_free(buf_y); } diff --git a/pkg/urbit/vere/lord.c b/pkg/urbit/vere/lord.c index 2051908485..d519455307 100644 --- a/pkg/urbit/vere/lord.c +++ b/pkg/urbit/vere/lord.c @@ -1051,7 +1051,7 @@ _lord_on_serf_err_cb(uv_stream_t* pyp_u, // serf used to write to 2 directly // this can't be any worse than that // - u3_write_fd(2, buf_u->base, siz_i); + c3_assert(c3_write(STDERR_FILENO, buf_u->base, siz_i) == siz_i); } else { uv_read_stop(pyp_u);