shithub: 9pro

Download patch

ref: 00f366402fbdfb5800697dad6ee083b893dafac4
parent: 84e2e4682e915b10d89bad9712f0e6628ddc888d
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Dec 24 16:26:14 EST 2019

proper signal handling

--- a/9pex.c
+++ b/9pex.c
@@ -74,6 +74,10 @@
 	[Twstat-Tversion] = "Twstat",
 };
 
+static char *modes[] = {
+	"read", "write", "rdwr", "exec",
+};
+
 static char *Enoauth = "authentication not required";
 static char *Eunknownfid = "unknown fid";
 static char *Enowstat = "wstat prohibited";
@@ -136,8 +140,15 @@
 	FD_SET(out, &e);
 	memset(&t, 0, sizeof(t));
 	t.tv_usec = 1000;
-	if ((n = select(max(in, out) + 1, &r, &w, &e, block ? NULL : &t)) < 0 || FD_ISSET(in, &e) || FD_ISSET(out, &e))
-		return -1;
+	for (;;) {
+		errno = 0;
+		if ((n = select(max(in, out) + 1, &r, &w, &e, block ? NULL : &t)) < 0 || FD_ISSET(in, &e) || FD_ISSET(out, &e)) {
+			if (errno == EINTR)
+				continue;
+			return -1;
+		}
+		break;
+	}
 
 	fl = 0;
 	if (FD_ISSET(in, &r))
@@ -156,11 +167,15 @@
 
 	if (wrend == 0)
 		return 0;
-	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;
+	for (n = 0; n < wrend; n += w) {
+		errno = 0;
+		if ((w = write(out, wrbuf+n, wrend-n)) <= 0) {
+			if (errno == EINTR)
+				continue;
+			if (errno != EPIPE) /* remote end closed */
+				perror("write");
+			return -1;
+		}
 	}
 	if (debug >= 2)
 		trace("<- %d bytes, %d left\n", wrend, wroff-wrend);
@@ -542,13 +557,17 @@
 	used(c);
 	r = 0;
 	*err = 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;
-		return NULL;
+	for (n = 0; n < size; n += r) {
+		errno = 0;
+		if ((r = read(in, rdbuf, size)) <= 0) {
+			if (r == EINTR)
+				continue;
+			if (r == 0)
+				eof = 1;
+			else
+				*err = 1;
+			return NULL;
+		}
 	}
 
 	return rdbuf;
@@ -800,6 +819,37 @@
 	}
 }
 
+static void
+sigdebug(int s)
+{
+	Fid *f;
+	int i, n;
+
+	used(s);
+	n = 0;
+	for (i = 0; i < numfids; i++) {
+		f = fids[i];
+		if (f == NULL)
+			continue;
+
+		fprintf(stderr, "fid %u ", f->fid);
+
+		if (f->dir != NULL)
+			fprintf(stderr, "open mode=dir ");
+		else if (f->fd >= 0)
+			fprintf(stderr, "open mode=%s%s%s ", modes[(f->mode & 0xf)], (f->mode & C9trunc) ? ",trunc" : "", (f->mode & C9rclose) ? ",rclose" : "");
+
+		fprintf(stderr, "qid=[path=%"PRIu64" type=0x%02x version=%"PRIu32"] iounit=%d ", f->qid.path, f->qid.type, f->qid.version, f->iounit);
+		fprintf(stderr, " %s %s\n", f->path, f->name);
+		n++;
+	}
+
+	fprintf(stderr, "fids\t%d\n", n);
+	fprintf(stderr, "tags\t%d\n", numtags);
+	fprintf(stderr, "uids\t%d\n", numuids);
+	fprintf(stderr, "gids\t%d\n", numgids);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -807,6 +857,7 @@
 	char *err;
 	Fid *f;
 	struct parg_state ps;
+	struct sigaction sa;
 	int can, i, c, rdonly, block;
 
 	parg_init(&ps);
@@ -876,7 +927,16 @@
 	wrbuf = calloc(1, wrbufsz);
 	wroff = wrend = 0;
 
-	signal(SIGPIPE, SIG_IGN);
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = SIG_IGN;
+	sa.sa_flags = SA_RESTART;
+	sigaction(SIGPIPE, &sa, NULL);
+
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = sigdebug;
+	sa.sa_flags = SA_RESTART;
+	sigfillset(&sa.sa_mask);
+	sigaction(SIGUSR1, &sa, NULL);
 
 	err = NULL;
 	rdonly = block = 1; /* at first we wait until the client sends in data */