commit 8ee287bc78fe5b9923ba4d25006c9b1b1b1f2e9e
parent 60db6ca7c869d45f8c2ebb9f5993dfe610fb9b6a
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Fri, 3 Feb 2006 13:10:26 +0200
extended libixp to close all connections by qid, this allows getting rid of requests accessing paths which get remove'ed to prevent invalid accesses
Diffstat:
3 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/cmd/wmiibar.c b/cmd/wmiibar.c
@@ -495,6 +495,7 @@ xremove(IXPConn *c)
{
IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
unsigned short i;
+ Qid qitem, qid;
if(!m) {
errstr = Enofid;
@@ -503,6 +504,17 @@ xremove(IXPConn *c)
i = qpath_item(m->qid.path);
if((qpath_type(m->qid.path) == Ditem) && i && (i < nitem)) {
Item *it = item[i];
+ qitem = m->qid;
+ /* clunk */
+ cext_array_detach((void **)c->map, m, &c->mapsz);
+ free(m);
+ /* close all connections which might have outstanding requests to this item */
+ if(!mkqid(&qitem, "data", &qid))
+ ixp_server_close_conns_qid(&srv, &qid);
+ if(!mkqid(&qitem, "color", &qid))
+ ixp_server_close_conns_qid(&srv, &qid);
+ ixp_server_close_conns_qid(&srv, &qitem);
+ /* now detach the item */
detach_item(it);
free(it);
c->fcall->id = RREMOVE;
diff --git a/libixp/ixp.h b/libixp/ixp.h
@@ -281,6 +281,7 @@ unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall *fcall);
/* server.c */
char *ixp_server_loop(IXPServer *s);
IXPMap *ixp_server_fid2map(IXPConn *c, unsigned int fid);
+void ixp_server_close_conns_qid(IXPServer *s, Qid *qid);
/* socket.c */
int ixp_connect_sock(char *address);
diff --git a/libixp/server.c b/libixp/server.c
@@ -71,3 +71,28 @@ ixp_server_fid2map(IXPConn *c, unsigned int fid)
return c->map[i];
return nil;
}
+
+static int
+xcomp_qid(Qid *q1, Qid *q2)
+{
+ return !((q1->type == q2->type) &&
+ (q1->version == q2->version) &&
+ (q1->path == q2->path) &&
+ (q1->dtype == q2->dtype));
+}
+
+void
+ixp_server_close_conns_qid(IXPServer *s, Qid *qid)
+{
+ size_t i, j;
+ for(i = 0; (i < s->connsz) && s->conn[i]; i++) {
+ IXPConn *c = s->conn[i];
+ if(!c->close)
+ continue;
+ for(j = 0; (j < c->mapsz) && c->map[j]; j++)
+ if(!xcomp_qid(qid, &c->map[j]->qid)) {
+ c->close(s, c);
+ break;
+ }
+ }
+}