ref: 84e2e4682e915b10d89bad9712f0e6628ddc888d
parent: aa6a69e2103f6367db8fe547786fec3f23987538
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Dec 24 15:37:57 EST 2019
assume write/read might have to be called more than once; ignore SIGPIPE in favor of EPIPE errno
--- a/9pex.c
+++ b/9pex.c
@@ -151,10 +151,15 @@
static int
wrsend(void)
{
+ uint32_t n;
+ int w;
+
if (wrend == 0)
return 0;
- if (write(out, wrbuf, wrend) != wrend) {
- perror("write");
+ for (n = 0; n < wrend && (w = write(out, wrbuf+n, wrend-n)) > 0; n += w);
+ if (w <= 0) {
+ if (errno != EPIPE) /* remote end closed */
+ perror("write");
return -1;
}
if (debug >= 2)
@@ -531,12 +536,15 @@
static uint8_t *
ctxread(C9ctx *c, uint32_t size, int *err)
{
- int n;
+ uint32_t n;
+ int r;
used(c);
+ r = 0;
*err = 0;
- if ((n = read(in, rdbuf, size)) != (int)size) {
- if (n == 0)
+ for (n = 0; n < size && (r = read(in, rdbuf, size)) > 0; n += r);
+ if (r <= 0) {
+ if (r == 0)
eof = 1;
else
*err = 1;
@@ -867,6 +875,8 @@
wrbufsz = ctx.msize;
wrbuf = calloc(1, wrbufsz);
wroff = wrend = 0;
+
+ signal(SIGPIPE, SIG_IGN);
err = NULL;
rdonly = block = 1; /* at first we wait until the client sends in data */