shithub: riscv

Download patch

ref: 42897a39aaa6e9448d000b7ee81faf71a731a585
parent: 86281ffaa7c9859dd0a92b35ca6215fe6e8f830c
author: Jacob Moody <moody@posixcafe.org>
date: Mon Mar 17 21:25:51 EDT 2025

devip: track connection initialization time as mtime

--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -49,6 +49,8 @@
 #define PROTO(x) 	( (((ulong)(x).path) >> Shiftproto) & Maskproto )
 #define QID(p, c, y) 	( ((p)<<(Shiftproto)) | ((c)<<Shiftconv) | (y) )
 
+#define DEVDOT -2
+
 static char network[] = "network";
 
 QLock	fslock;
@@ -79,16 +81,16 @@
 		return -1;
 	case Qctl:
 		devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp);
-		return 1;
+		goto done;
 	case Qdata:
 		devdir(c, q, "data", qlen(cv->rq), cv->owner, cv->perm, dp);
-		return 1;
+		goto done;
 	case Qerr:
 		devdir(c, q, "err", qlen(cv->eq), cv->owner, cv->perm, dp);
-		return 1;
+		goto done;
 	case Qlisten:
 		devdir(c, q, "listen", 0, cv->owner, cv->perm, dp);
-		return 1;
+		goto done;
 	case Qlocal:
 		p = "local";
 		break;
@@ -99,12 +101,14 @@
 		if(cv->p != ipfs[c->dev]->ipifc)
 			return -1;
 		devdir(c, q, "snoop", qlen(cv->sq), cv->owner, 0400, dp);
-		return 1;
+		goto done;
 	case Qstatus:
 		p = "status";
 		break;
 	}
 	devdir(c, q, p, 0, cv->owner, 0444, dp);
+done:
+	dp->mtime = cv->ctime;
 	return 1;
 }
 
@@ -184,7 +188,7 @@
 
 	switch(TYPE(c->qid)) {
 	case Qtopdir:
-		if(s == DEVDOTDOT){
+		if(s == DEVDOTDOT || s == DEVDOT){
 			mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR);
 			snprint(up->genbuf, sizeof up->genbuf, "#I%lud", c->dev);
 			devdir(c, q, up->genbuf, 0, network, 0555, dp);
@@ -191,6 +195,7 @@
 			return 1;
 		}
 		if(s < f->np) {
+	Protodir:
 			if(f->p[s]->connect == nil)
 				return 0;	/* protocol with no user interface */
 			mkqid(&q, QID(s, 0, Qprotodir), 0, QTDIR);
@@ -213,11 +218,17 @@
 			devdir(c, q, up->genbuf, 0, network, 0555, dp);
 			return 1;
 		}
+		if(s == DEVDOT){
+			s = PROTO(c->qid);
+			goto Protodir;
+		}
 		if(s < f->p[PROTO(c->qid)]->ac) {
+	Convdir:
 			cv = f->p[PROTO(c->qid)]->conv[s];
 			snprint(up->genbuf, sizeof up->genbuf, "%d", s);
 			mkqid(&q, QID(PROTO(c->qid), s, Qconvdir), 0, QTDIR);
 			devdir(c, q, up->genbuf, 0, cv->owner, 0555, dp);
+			dp->mtime = cv->ctime;
 			return 1;
 		}
 		s -= f->p[PROTO(c->qid)]->ac;
@@ -232,6 +243,10 @@
 			devdir(c, q, f->p[s]->name, 0, network, 0555, dp);
 			return 1;
 		}
+		if(s == DEVDOT){
+			s = CONV(c->qid);
+			goto Convdir;
+		}
 		return ip3gen(c, s+Qconvbase, dp);
 	case Qctl:
 	case Qdata:
@@ -324,6 +339,16 @@
 static int
 ipstat(Chan* c, uchar* db, int n)
 {
+	Dir d;
+
+	if(c->qid.type == QTDIR){
+		ipgen(c, nil, nil, 0, DEVDOT, &d);
+		n = convD2M(&d, db, n);
+		if(n == 0)
+			error(Ebadarg);
+		return n;
+	}
+
 	return devstat(c, db, n, nil, 0, ipgen);
 }
 
@@ -1396,6 +1421,7 @@
 	c->ignoreadvice = 0;
 	c->ttl = MAXTTL;
 	c->tos = 0;
+	c->ctime = seconds();
 	qreopen(c->rq);
 	qreopen(c->wq);
 	qreopen(c->eq);
--- a/sys/src/9/ip/ip.h
+++ b/sys/src/9/ip/ip.h
@@ -270,6 +270,7 @@
 	int	inuse;			/* opens of listen/data/ctl */
 	int	length;
 	int	state;
+	ulong	ctime;
 
 	/* udp specific */
 	int	headers;		/* data src/dst headers in udp */
--