shithub: 9pro

Download patch

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 */