net: Report listen files with incalls as readable
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 Feb 2017 19:49:40 +0000 (14:49 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 2 Mar 2017 18:01:29 +0000 (13:01 -0500)
When a conversation has inbound calls, userspace can now see that by doing
a stat on the listen file (e.g. /net/tcp/1/listen).  This is necessary for
libraries that use stat() to detect the 'level' of an event.  select() and
epoll() both do this (select() for its own behavior, epoll() to synthesize
events).

And you can now see whether or not there are incalls in 'pip.'  If you
happen to see it, either you got lucky or there's probably a bug.  Which is
probably why you're running 'pip' in the first place.  =)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/net/devip.c

index 0bc5093..63d5289 100644 (file)
@@ -157,7 +157,9 @@ static int ip3gen(struct chan *c, int i, struct dir *dp)
                        return founddevdir(c, q, "err", qlen(cv->eq),
                                                           cv->owner, perm, dp);
                case Qlisten:
-                       return founddevdir(c, q, "listen", 0, cv->owner, cv->perm, dp);
+                       perm = cv->perm;
+                       perm |= cv->incall ? DMREADABLE : 0;
+                       return founddevdir(c, q, "listen", 0, cv->owner, perm, dp);
                case Qlocal:
                        p = "local";
                        break;
@@ -653,9 +655,10 @@ static char *ipchaninfo(struct chan *ch, char *ret, size_t ret_l)
                case Qlisten:
                        proto = f->p[PROTO(ch->qid)];
                        conv = proto->conv[CONV(ch->qid)];
-                       snprintf(ret, ret_l, "Qlisten, %s proto %s, conv idx %d",
+                       snprintf(ret, ret_l,
+                                "Qlisten, %s proto %s, conv idx %d, has %sincalls",
                                 SLIST_EMPTY(&conv->listen_taps) ? "untapped" : "tapped",
-                                proto->name, conv->x);
+                                proto->name, conv->x, conv->incall ? "" : "no ");
                        break;
                case Qlog:
                        ret = "Qlog";