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