wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 39fc05f71c38b66e8a9f2446e4fe7d7cca821e83
parent 8e56284c24c1012ee8056b9dc31ffa9ac8d61285
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Sun, 29 Jan 2006 14:41:16 +0200

added attach/detach for array management, removed IXPConn->aux, instead added Mapping and pending Fcalls to IXPConn


Diffstat:
cmd/wm/client.c | 47+++++++----------------------------------------
cmd/wm/column.c | 54++++++++++++++----------------------------------------
cmd/wm/event.c | 2+-
cmd/wm/page.c | 38++++----------------------------------
cmd/wm/wm.c | 6+++---
cmd/wm/wm.h | 4----
cmd/wmiibar2.c | 275++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
libcext/Makefile | 2+-
libcext/array.c | 43+++++++++++++++++++++++++++++++++++++++++++
libcext/cext.h | 4++++
libixp2/ixp.h | 55++++++++++++++++---------------------------------------
libixp2/server.c | 159+++++++------------------------------------------------------------------------
12 files changed, 262 insertions(+), 427 deletions(-)

diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -21,41 +21,6 @@ Action client_acttbl[] = { {0, 0} }; -Client ** -attach_client_to_array(Client *c, Client **array, size_t *size) -{ - size_t i; - if(!array) { - *size = 2; - array = cext_emallocz(sizeof(Client *) * (*size)); - } - for(i = 0; (i < (*size)) && array[i]; i++); - if(i >= (*size)) { - Client **tmp = array; - (*size) *= 2; - array = cext_emallocz(sizeof(Client *) * (*size)); - for(i = 0; tmp[i]; i++) - array[i] = tmp[i]; - free(tmp); - } - array[i] = c; - return array; -} - -void -detach_client_from_array(Client *c, Client **array) -{ - size_t i; - if(!array) - return; - for(i = 0; array[i] && array[i] != c; i++); - if(!array[i]) - return; /* not found */ - for(; array[i + 1]; i++) - array[i] = array[i + 1]; - array[i] = nil; -} - Client * alloc_client(Window w, XWindowAttributes *wa) { @@ -130,7 +95,7 @@ alloc_client(Window w, XWindowAttributes *wa) c->frame.gc = XCreateGC(dpy, c->frame.win, 0, 0); XSync(dpy, False); - client = attach_client_to_array(c, client, &clientsz); + client = (Client **)cext_array_attach((void **)client, c, sizeof(Client *), &clientsz); return c; } @@ -312,7 +277,7 @@ destroy_client(Client * c) XFreeGC(dpy, c->frame.gc); XDestroyWindow(dpy, c->frame.win); ixp_remove_file(ixps, c->file[C_PREFIX]); - detach_client_from_array(c, detached); + cext_array_detach((void **)detached, c, &detachedsz); free(c); } @@ -443,7 +408,8 @@ attach_client(Client *c) if(p->is_column) attach_column(c); else - p->floating = attach_client_to_array(c, p->floating, &p->floatingsz); + p->floating = (Client **)cext_array_attach((void **)p->floating, c, + sizeof(Client *), &p->floatingsz); map_client(c); XMapWindow(dpy, c->frame.win); focus_client(c); @@ -458,10 +424,11 @@ detach_client(Client *c, Bool unmap) if(c->column) detach_column(c); else { - detach_client_from_array(c, c->page->floating); + cext_array_detach((void **)c->page->floating, c, &c->page->floatingsz); if(!c->destroyed) { if(!unmap) { - detached = attach_client_to_array(c, detached, &detachedsz); + detached = (Client **)cext_array_attach((void **)detached, c, + sizeof(Client *), &detachedsz); unmap_client(c); } c->rect.x = c->frame.rect.x; diff --git a/cmd/wm/column.c b/cmd/wm/column.c @@ -8,37 +8,6 @@ #include "wm.h" -static Column ** -attach_column_to_array(Column *col, Column **array, size_t *size) -{ - size_t i; - if(!array) { - *size = 2; - array = cext_emallocz(sizeof(Column *) * (*size)); - } - for(i = 0; (i < (*size)) && array[i]; i++); - if(i >= (*size)) { - Column **tmp = array; - (*size) *= 2; - array = cext_emallocz(sizeof(Column *) * (*size)); - for(i = 0; tmp[i]; i++) - array[i] = tmp[i]; - free(tmp); - } - array[i] = col; - return array; -} - -static void -detach_column_from_array(Column *col, Column **array) -{ - size_t i; - for(i = 0; array[i] != col; i++); - for(; array[i + 1]; i++) - array[i] = array[i + 1]; - array[i] = nil; -} - void arrange_column(Page *p, Column *col) { @@ -79,12 +48,14 @@ attach_column(Client *c) if(!col) { col = cext_emallocz(sizeof(Column)); col->rect = p->rect_column; - p->column = attach_column_to_array(col, p->column, &p->columnsz); + p->column = (Column **)cext_array_attach((void **)p->column, col, + sizeof(Column *), &p->columnsz); p->sel_column = 0; } c->column = col; - col->client = attach_client_to_array(c, col->client, &col->clientsz); + col->client = (Client **)cext_array_attach((void **)col->client, c, + sizeof(Client *), &col->clientsz); arrange_column(p, col); } @@ -113,9 +84,9 @@ detach_column(Client *c) Page *p = c->page; Column *col = c->column; - detach_client_from_array(c, col->client); + cext_array_detach((void **)col->client, c, &col->clientsz); if(!col->client[0]) { - detach_column_from_array(col, p->column); + cext_array_detach((void **)p->column, col, &p->columnsz); free(col); update_column_width(p); } @@ -204,8 +175,9 @@ drop_moving(Client *c, XRectangle *new, XPoint * pt) if(tgt != src) { if(src->clientsz <= 1 || !src->client[1]) return; - detach_client_from_array(c, src->client); - tgt->client = attach_client_to_array(c, tgt->client, &tgt->clientsz); + cext_array_detach((void **)src->client, c, &src->clientsz); + tgt->client = (Client **)cext_array_attach((void **)tgt->client, c, + sizeof(Client *), &tgt->clientsz); arrange_column(p, src); arrange_column(p, tgt); } else { @@ -292,10 +264,12 @@ new_column(Page *p) col = cext_emallocz(sizeof(Column)); col->rect = p->rect_column; - p->column = attach_column_to_array(col, p->column, &p->columnsz); + p->column = (Column **)cext_array_attach((void **)p->column, col, + sizeof(Column *), &p->columnsz); p->sel_column = i; - detach_client_from_array(c, old->client); - col->client = attach_client_to_array(c, col->client, &col->clientsz); + cext_array_detach((void **)old->client, c, &old->clientsz); + col->client = (Client **)cext_array_attach((void **)col->client, c, + sizeof(Client *), &col->clientsz); c->column = col; update_column_width(p); focus_client(c); diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -212,7 +212,7 @@ handle_maprequest(XEvent * e) /* attach heuristic support */ if(aqueuesz && aqueue[0]) { focus_page(0); - detach_page_from_array(aqueue[0], aqueue); + cext_array_detach((void **)aqueue, aqueue[0], &aqueuesz); } /* there're client which send map requests twice */ diff --git a/cmd/wm/page.c b/cmd/wm/page.c @@ -28,37 +28,6 @@ Action page_acttbl[] = { {0, 0} }; -Page ** -attach_page_to_array(Page *p, Page **array, size_t *size) -{ - size_t i; - if(!array) { - *size = 2; - array = cext_emallocz(sizeof(Page *) * (*size)); - } - for(i = 0; (i < (*size)) && array[i]; i++); - if(i >= (*size)) { - Page **tmp = array; - (*size) *= 2; - array = cext_emallocz(sizeof(Page *) * (*size)); - for(i = 0; tmp[i]; i++) - array[i] = tmp[i]; - free(tmp); - } - array[i] = p; - return array; -} - -void -detach_page_from_array(Page *p, Page **array) -{ - size_t i; - for(i = 0; array[i] != p; i++); - for(; array[i + 1]; i++) - array[i] = array[i + 1]; - array[i] = nil; -} - Page * alloc_page() { @@ -84,7 +53,7 @@ alloc_page() invoke_wm_event(def[WM_EVENT_PAGE_UPDATE]); id++; p->rect_column = rect; - page = attach_page_to_array(p, page, &pagesz); + page = (Page **)cext_array_attach((void **)page, p, sizeof(Page *), &pagesz); for(np = 0; (np < pagesz) && page[np]; np++); focus_page(p); XChangeProperty(dpy, root, net_atoms[NET_NUMBER_OF_DESKTOPS], XA_CARDINAL, @@ -103,7 +72,7 @@ destroy_page(Page *p) if(aqueue[i] == p) naqueue++; for(i = 0; i < naqueue; i++) - detach_page_from_array(p, aqueue); + cext_array_detach((void **)aqueue, p, &aqueuesz); for(i = 0; (i < clientsz) && client[i]; i++) if(client[i]->page == p) @@ -205,7 +174,8 @@ handle_after_write_page(IXPServer *s, File *file) static void xexec(void *obj, char *arg) { - aqueue = attach_page_to_array(obj, aqueue, &aqueuesz); + aqueue = (Page **)cext_array_attach((void **)aqueue, obj, + sizeof(Page *), &aqueuesz); wmii_spawn(dpy, arg); } diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -367,7 +367,7 @@ detached_client(void *obj, char *arg) if((n = handle_kpress(&ev.xkey)) != -1) { if(n < nc) { c = detached[n]; - detach_client_from_array(c, detached); + cext_array_detach((void **)detached, c, &detachedsz); attach_client(c); } } @@ -380,7 +380,7 @@ detached_client(void *obj, char *arg) unmap_client(detached[i]); if((ev.xbutton.button == Button1) && (c = win_to_client(ev.xbutton.window))) { - detach_client_from_array(c, detached); + cext_array_detach((void **)detached, c, &detachedsz); attach_client(c); } XUngrabKeyboard(dpy, CurrentTime); @@ -403,7 +403,7 @@ xattach_client(void *obj, char *arg) { Client *c = detached ? detached[0] : nil; if(c) { - detach_client_from_array(c, detached); + cext_array_detach((void **)detached, c, &detachedsz); attach_client(c); } } diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -172,8 +172,6 @@ unsigned int valid_mask, num_lock_mask; /* client.c */ -Client **attach_client_to_array(Client *c, Client **array, size_t *size); -void detach_client_from_array(Client *c, Client **array); Client *alloc_client(Window w, XWindowAttributes *wa); void destroy_client(Client * c); void configure_client(Client * c); @@ -209,8 +207,6 @@ Align xy_to_align(XRectangle * rect, int x, int y); void drop_move(Client *c, XRectangle *new, XPoint *pt); /* page.c */ -Page **attach_page_to_array(Page *p, Page **array, size_t *size); -void detach_page_from_array(Page *p, Page **array); Page *alloc_page(); void destroy_page(Page *p); void focus_page(Page *p); diff --git a/cmd/wmiibar2.c b/cmd/wmiibar2.c @@ -259,85 +259,87 @@ mkqid(Qid *dir, char *wname, Qid *new) } static int -xversion(IXPReq *r) +xversion(IXPConn *c) { - if(strncmp(r->fcall->version, IXP_VERSION, strlen(IXP_VERSION))) { + if(strncmp(c->fcall->version, IXP_VERSION, strlen(IXP_VERSION))) { errstr = E9pversion; return -1; - } else if(r->fcall->maxmsg > IXP_MAX_MSG) - r->fcall->maxmsg = IXP_MAX_MSG; - r->fcall->id = RVERSION; + } else if(c->fcall->maxmsg > IXP_MAX_MSG) + c->fcall->maxmsg = IXP_MAX_MSG; + c->fcall->id = RVERSION; return 0; } static int -xattach(IXPReq *r) +xattach(IXPConn *c) { IXPMap *new = cext_emallocz(sizeof(IXPMap)); new->qid = root_qid; - new->fid = r->fcall->fid; - r->map = ixp_server_attach_map(new, r->map, &r->mapsz); - r->fcall->id = RATTACH; - r->fcall->qid = root_qid; + new->fid = c->fcall->fid; + c->map = (IXPMap **)cext_array_attach((void **)c->map, new, + sizeof(IXPMap *), &c->mapsz); + c->fcall->id = RATTACH; + c->fcall->qid = root_qid; return 0; } static int -xwalk(IXPReq *r) +xwalk(IXPConn *c) { unsigned short nwqid = 0; Qid dir = root_qid; IXPMap *m; - if(!(m = ixp_server_fid2map(r, r->fcall->fid))) { + if(!(m = ixp_server_fid2map(c, c->fcall->fid))) { errstr = Enofid; return -1; } - if(r->fcall->fid != r->fcall->newfid - && (ixp_server_fid2map(r, r->fcall->newfid))) { + if(c->fcall->fid != c->fcall->newfid + && (ixp_server_fid2map(c, c->fcall->newfid))) { errstr = Enofid; return -1; } - if(r->fcall->nwname) { + if(c->fcall->nwname) { dir = m->qid; - for(nwqid = 0; (nwqid < r->fcall->nwname) - && !mkqid(&dir, r->fcall->wname[nwqid], &r->fcall->wqid[nwqid]); nwqid++) - dir = r->fcall->wqid[nwqid]; + for(nwqid = 0; (nwqid < c->fcall->nwname) + && !mkqid(&dir, c->fcall->wname[nwqid], &c->fcall->wqid[nwqid]); nwqid++) + dir = c->fcall->wqid[nwqid]; if(!nwqid) { errstr = Enofile; return -1; } } /* a fid will only be valid, if the walk was complete */ - if(nwqid == r->fcall->nwname) { - if(r->fcall->fid != r->fcall->newfid) { + if(nwqid == c->fcall->nwname) { + if(c->fcall->fid != c->fcall->newfid) { m = cext_emallocz(sizeof(IXPMap)); - r->map = ixp_server_attach_map(m, r->map, &r->mapsz); + c->map = (IXPMap **)cext_array_attach((void **)c->map, m, + sizeof(IXPMap *), &c->mapsz); } m->qid = dir; - m->fid = r->fcall->newfid; + m->fid = c->fcall->newfid; } - r->fcall->id = RWALK; - r->fcall->nwqid = nwqid; + c->fcall->id = RWALK; + c->fcall->nwqid = nwqid; return 0; } static int -xopen(IXPReq *r) +xopen(IXPConn *c) { - IXPMap *m = ixp_server_fid2map(r, r->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); if(!m) { errstr = Enofid; return -1; } - if(!(r->fcall->mode | IXP_OREAD) && !(r->fcall->mode | IXP_OWRITE)) { + if(!(c->fcall->mode | IXP_OREAD) && !(c->fcall->mode | IXP_OWRITE)) { errstr = Enomode; return -1; } - r->fcall->id = ROPEN; - r->fcall->qid = m->qid; - r->fcall->iounit = r->fcall->maxmsg + c->fcall->id = ROPEN; + c->fcall->qid = m->qid; + c->fcall->iounit = c->fcall->maxmsg - (sizeof(unsigned char) + sizeof(unsigned short) + 2 * sizeof(unsigned int)); return 0; } @@ -405,9 +407,9 @@ type_to_stat(Stat *stat, char *name, unsigned short i) } static int -xremove(IXPReq *r) +xremove(IXPConn *c) { - IXPMap *m = ixp_server_fid2map(r, r->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); unsigned short i; if(!m) { @@ -419,7 +421,7 @@ xremove(IXPReq *r) Item *it = item[i]; detach_item(it); free(it); - r->fcall->id = RREMOVE; + c->fcall->id = RREMOVE; return 0; } errstr = Enoperm; @@ -427,11 +429,11 @@ xremove(IXPReq *r) } static int -xread(IXPReq *r) +xread(IXPConn *c) { Stat stat; - IXPMap *m = ixp_server_fid2map(r, r->fcall->fid); - unsigned char *p = r->fcall->data; + IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); + unsigned char *p = c->fcall->data; unsigned short i; unsigned int len; char buf[32]; @@ -441,30 +443,30 @@ xread(IXPReq *r) return -1; } i = qpath_item(m->qid.path); - r->fcall->count = 0; /* EOF by default */ - r->fcall->id = RREAD; - if(r->fcall->offset) + c->fcall->count = 0; /* EOF by default */ + c->fcall->id = RREAD; + if(c->fcall->offset) return 0; switch (qpath_type(m->qid.path)) { case Droot: - r->fcall->count = type_to_stat(&stat, "ctl", 0); + c->fcall->count = type_to_stat(&stat, "ctl", 0); p = ixp_enc_stat(p, &stat); - r->fcall->count += type_to_stat(&stat, "display", 0); + c->fcall->count += type_to_stat(&stat, "display", 0); p = ixp_enc_stat(p, &stat); - r->fcall->count += type_to_stat(&stat, "font", 0); + c->fcall->count += type_to_stat(&stat, "font", 0); p = ixp_enc_stat(p, &stat); - r->fcall->count += type_to_stat(&stat, "new", 0); + c->fcall->count += type_to_stat(&stat, "new", 0); p = ixp_enc_stat(p, &stat); - r->fcall->count += type_to_stat(&stat, "event", 0); + c->fcall->count += type_to_stat(&stat, "event", 0); p = ixp_enc_stat(p, &stat); - r->fcall->count += type_to_stat(&stat, "default", 0); + c->fcall->count += type_to_stat(&stat, "default", 0); p = ixp_enc_stat(p, &stat); for(i = 1; i < nitem; i++) { snprintf(buf, sizeof(buf), "%u", i); len = type_to_stat(&stat, buf, i); - if(r->fcall->count + len >= r->fcall->iounit) + if(c->fcall->count + len >= c->fcall->iounit) break; - r->fcall->count += len; + c->fcall->count += len; p = ixp_enc_stat(p, &stat); } break; @@ -472,15 +474,15 @@ xread(IXPReq *r) if(i > nitem) goto error_xread; if(!i) { - r->fcall->count = type_to_stat(&stat, "color", i); + c->fcall->count = type_to_stat(&stat, "color", i); p = ixp_enc_stat(p, &stat); break; } if(i == nitem) new_item(); - r->fcall->count = type_to_stat(&stat, "color", i); + c->fcall->count = type_to_stat(&stat, "color", i); p = ixp_enc_stat(p, &stat); - r->fcall->count += type_to_stat(&stat, "data", i); + c->fcall->count += type_to_stat(&stat, "data", i); p = ixp_enc_stat(p, &stat); break; case Fctl: @@ -491,21 +493,21 @@ xread(IXPReq *r) switch(align) { case SOUTH: memcpy(p, "south", 5); - r->fcall->count = 5; + c->fcall->count = 5; break; case NORTH: memcpy(p, "north", 5); - r->fcall->count = 5; + c->fcall->count = 5; break; default: memcpy(p, "none", 4); - r->fcall->count = 4; + c->fcall->count = 4; break; } break; case Ffont: - if((r->fcall->count = strlen(font))) - memcpy(p, font, r->fcall->count); + if((c->fcall->count = strlen(font))) + memcpy(p, font, c->fcall->count); break; case Fevent: /* has to be processed asynchroneous, will be enqueued */ @@ -516,16 +518,16 @@ xread(IXPReq *r) new_item(); if(i >= nitem) goto error_xread; - if((r->fcall->count = strlen(item[i]->data))) - memcpy(p, item[i]->data, r->fcall->count); + if((c->fcall->count = strlen(item[i]->data))) + memcpy(p, item[i]->data, c->fcall->count); break; case Fcolor: if(i == nitem) new_item(); if(i >= nitem) goto error_xread; - if((r->fcall->count = strlen(item[i]->color))) - memcpy(p, item[i]->color, r->fcall->count); + if((c->fcall->count = strlen(item[i]->color))) + memcpy(p, item[i]->color, c->fcall->count); break; default: error_xread: @@ -538,9 +540,9 @@ error_xread: } static int -xstat(IXPReq *r) +xstat(IXPConn *c) { - IXPMap *m = ixp_server_fid2map(r, r->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); char *name; if(!m) { @@ -549,17 +551,17 @@ xstat(IXPReq *r) } name = qid_to_name(&m->qid); - if(!type_to_stat(&r->fcall->stat, name, qpath_item(m->qid.path))) + if(!type_to_stat(&c->fcall->stat, name, qpath_item(m->qid.path))) return -1; - r->fcall->id = RSTAT; + c->fcall->id = RSTAT; return 0; } static int -xwrite(IXPReq *r) +xwrite(IXPConn *c) { char buf[256]; - IXPMap *m = ixp_server_fid2map(r, r->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); unsigned short i; if(!m) { @@ -570,8 +572,8 @@ xwrite(IXPReq *r) i = qpath_item(m->qid.path); switch (qpath_type(m->qid.path)) { case Fctl: - if(r->fcall->count == 5) { - memcpy(buf, r->fcall->data, 4); + if(c->fcall->count == 5) { + memcpy(buf, c->fcall->data, 4); buf[4] = 0; if(!strncmp(buf, "quit", 5)) { srv.running = 0; @@ -582,10 +584,10 @@ xwrite(IXPReq *r) return -1; break; case Fdisplay: - if(r->fcall->count > 5) + if(c->fcall->count > 5) goto error_xwrite; - memcpy(buf, r->fcall->data, r->fcall->count); - buf[r->fcall->count] = 0; + memcpy(buf, c->fcall->data, c->fcall->count); + buf[c->fcall->count] = 0; if(!blitz_strtoalign(&align, buf)) goto error_xwrite; /* TODO: resize/hide */ @@ -593,20 +595,20 @@ xwrite(IXPReq *r) case Ffont: if(font) free(font); - font = cext_emallocz(r->fcall->count + 1); - memcpy(font, r->fcall->data, r->fcall->count); + font = cext_emallocz(c->fcall->count + 1); + memcpy(font, c->fcall->data, c->fcall->count); /* TODO: XQueryFont */ break; case Fdata: { - unsigned int len = r->fcall->count; + unsigned int len = c->fcall->count; if(i == nitem) new_item(); if(!i || (i >= nitem)) goto error_xwrite; if(len >= sizeof(item[i]->data)) len = sizeof(item[i]->data) - 1; - memcpy(item[i]->data, r->fcall->data, len); + memcpy(item[i]->data, c->fcall->data, len); item[i]->data[len] = 0; /* TODO: redraw */ } @@ -614,14 +616,15 @@ xwrite(IXPReq *r) case Fcolor: if(i == nitem) new_item(); - if((i >= nitem) || (r->fcall->count != 24) - || (r->fcall->data[0] != '#') || (r->fcall->data[8] != '#') - || (r->fcall->data[16] != '#')) { + if((i >= nitem) || (c->fcall->count != 24) + || (c->fcall->data[0] != '#') || (c->fcall->data[8] != '#') + || (c->fcall->data[16] != '#')) + { errstr = "wrong color format"; goto error_xwrite; } - memcpy(item[i]->color, r->fcall->data, r->fcall->count); - item[i]->color[r->fcall->count] = 0; + memcpy(item[i]->color, c->fcall->data, c->fcall->count); + item[i]->color[c->fcall->count] = 0; /* TODO: update color */ break; default: @@ -631,49 +634,68 @@ error_xwrite: return -1; break; } - r->fcall->id = RWRITE; + c->fcall->id = RWRITE; return 0; } static int -xclunk(IXPReq *r) +xclunk(IXPConn *c) { - IXPMap *m = ixp_server_fid2map(r, r->fcall->fid); + IXPMap *m = ixp_server_fid2map(c, c->fcall->fid); if(!m) { errstr = Enofid; return -1; } - ixp_server_detach_map(m, r->map); + cext_array_detach((void **)c->map, m, &c->mapsz); free(m); - r->fcall->id = RCLUNK; + c->fcall->id = RCLUNK; return 0; } static void +close_ixp_conn(IXPServer *s, IXPConn *c) +{ + size_t i; + cext_array_detach((void **)s->conn, c, &s->connsz); + if(c->map) { + for(i = 0; (i < c->mapsz) && c->map[i]; i++) + free(c->map[i]); + free(c->map); + } + if(c->pend) { + for(i = 0; (i < c->pendsz) && c->pend[i]; i++) + free(c->pend[i]); + free(c->pend); + } + shutdown(c->fd, SHUT_RDWR); + close(c->fd); + free(c); +} + +static void handle_ixp_req(IXPServer *s, IXPConn *c) { - IXPReq *r = c->aux; unsigned int msize; int ret = -1; errstr = 0; if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) { - ixp_server_free_conn(s, c); + close_ixp_conn(s, c); return; } - if(!r->fcall) - r->fcall = cext_emallocz(sizeof(Fcall)); - if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, r->fcall))) { - switch(r->fcall->id) { - case TVERSION: ret = xversion(r); break; - case TATTACH: ret = xattach(r); break; - case TWALK: ret = xwalk(r); break; - case TREMOVE: ret = xremove(r); break; - case TOPEN: ret = xopen(r); break; - case TREAD: ret = xread(r); break; - case TWRITE: ret = xwrite(r); break; - case TCLUNK: ret = xclunk(r); break; - case TSTAT: ret = xstat(r); break; + if(!c->fcall) + c->fcall = cext_emallocz(sizeof(Fcall)); + if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, c->fcall))) { + switch(c->fcall->id) { + case TVERSION: ret = xversion(c); break; + case TATTACH: ret = xattach(c); break; + case TWALK: ret = xwalk(c); break; + case TREMOVE: ret = xremove(c); break; + case TOPEN: ret = xopen(c); break; + case TREAD: ret = xread(c); break; + case TWRITE: ret = xwrite(c); break; + case TCLUNK: ret = xclunk(c); break; + case TSTAT: ret = xstat(c); break; default: break; } @@ -681,31 +703,37 @@ handle_ixp_req(IXPServer *s, IXPConn *c) if(ret == -1) { if(!errstr) errstr = Enofunc; - r->fcall->id = RERROR; - cext_strlcpy(r->fcall->errstr, errstr, sizeof(r->fcall->errstr)); + c->fcall->id = RERROR; + cext_strlcpy(c->fcall->errstr, errstr, sizeof(c->fcall->errstr)); } else if(ret == 1) { - r->async = ixp_server_attach_fcall(r->fcall, r->async, &r->asyncsz); - r->fcall = nil; + c->pend = (Fcall **)cext_array_attach((void **)c->pend, c->fcall, sizeof(Fcall *), &c->pendsz); + c->fcall = nil; return; /* response asynchroneously */ } - msize = ixp_fcall_to_msg(r->fcall, msg, IXP_MAX_MSG); + msize = ixp_fcall_to_msg(c->fcall, msg, IXP_MAX_MSG); if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) - ixp_server_free_conn(s, c); + close_ixp_conn(s, c); } static void new_ixp_conn(IXPServer *s, IXPConn *c) { - IXPConn *new = ixp_server_alloc_conn(s); - if(new && ((new->fd = ixp_accept_sock(c->fd)) >= 0)) { + IXPConn *new; + int fd = ixp_accept_sock(c->fd); + + if(fd >= 0) { + new = cext_emallocz(sizeof(IXPConn)); + new->fd = fd; new->read = handle_ixp_req; - new->close = ixp_server_close_conn; - new->aux = cext_emallocz(sizeof(IXPReq)); + new->close = close_ixp_conn; + s->conn = (IXPConn **)cext_array_attach((void **)s->conn, new, + sizeof(IXPConn *), &s->connsz); } } + /* main */ int @@ -745,14 +773,17 @@ main(int argc, char *argv[]) fprintf(stderr, "%s\n", "wmiibar: no socket address provided"); exit(1); } - ixp_server_init(&srv); - c = ixp_server_alloc_conn(&srv); - if((c->fd = ixp_create_sock(address, &errstr)) < 0) { + i = ixp_create_sock(address, &errstr); + if(i < 0) { fprintf(stderr, "wmiibar: fatal: %s\n", errstr); exit(1); } + c = cext_emallocz(sizeof(IXPConn)); + c->fd = i; c->read = new_ixp_conn; - c->close = ixp_server_close_conn; + c->close = close_ixp_conn; + srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c, + sizeof(IXPConn *), &srv.connsz); /* TODO: add X conn */ root_qid.type = IXP_QTDIR; @@ -767,11 +798,15 @@ main(int argc, char *argv[]) font = strdup(BLITZ_FONT); - if((errstr = ixp_server_loop(&srv))) { - fprintf(stderr, "wmiibar: fatal: %s\n", errstr); - ixp_server_deinit(&srv); - exit(1); - } - ixp_server_deinit(&srv); - return 0; + errstr = ixp_server_loop(&srv); + + if(errstr) + fprintf(stderr, "wmiibar: fatal: %s\n", errstr); + + /* cleanup */ + for(i = 0; (i < srv.connsz) && srv.conn[i]; i++) + if(srv.conn[i]->close) + srv.conn[i]->close(&srv, srv.conn[i]); + + return errstr ? 1 : 0; } diff --git a/libcext/Makefile b/libcext/Makefile @@ -3,7 +3,7 @@ include ../config.mk -SRC = emallocz.c estrdup.c strlcat.c strlcpy.c strtonum.c tokenize.c +SRC = array.c emallocz.c estrdup.c strlcat.c strlcpy.c strtonum.c tokenize.c OBJ = ${SRC:.c=.o} diff --git a/libcext/array.c b/libcext/array.c @@ -0,0 +1,43 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <stdlib.h> + +#include "cext.h" + +void ** +cext_array_attach(void **array, void *p, size_t psize, size_t *size) +{ + size_t i; + if(!array) { + *size = 2; + array = cext_emallocz(psize * (*size)); + } + for(i = 0; (i < (*size)) && array[i]; i++); + if(i >= (*size)) { + void **tmp = array; + (*size) *= 2; + array = cext_emallocz(psize * (*size)); + for(i = 0; tmp[i]; i++) + array[i] = tmp[i]; + free(tmp); + } + array[i] = p; + return array; +} + +void +cext_array_detach(void **array, void *p, size_t *size) +{ + size_t i; + if(!array) + return; + for(i = 0; (i < (*size)) && array[i] && array[i] != p; i++); + if((i >= (*size)) || !array[i]) + return; /* not found */ + for(; array[i + 1]; i++) + array[i] = array[i + 1]; + array[i] = nil; +} diff --git a/libcext/cext.h b/libcext/cext.h @@ -9,6 +9,10 @@ #define nil (void *)0 #endif +/* array.c */ +void ** cext_array_attach(void **array, void *p, size_t psize, size_t *size); +void cext_array_detach(void **array, void *p, size_t *size); + /* emallocz.c */ void *cext_emallocz(size_t size); diff --git a/libixp2/ixp.h b/libixp2/ixp.h @@ -194,50 +194,32 @@ typedef struct { typedef struct IXPServer IXPServer; typedef struct IXPConn IXPConn; +typedef struct IXPMap IXPMap; + +struct IXPMap { + unsigned int fid; + Qid qid; +}; struct IXPConn { int fd; void (*read) (IXPServer *, IXPConn *); void (*close) (IXPServer *, IXPConn *); - void *aux; + IXPMap **map; + size_t mapsz; + Fcall *fcall; + Fcall **pend; + size_t pendsz; }; struct IXPServer { int running; - IXPConn conn[IXP_MAX_CONN]; + IXPConn **conn; + size_t connsz; int maxfd; fd_set rd; }; -/************* begin: this should be moved to libwmii ****************/ -/* once all tools are independent from old libixp, there won;t be any - * conflicts in libwmii with this stuff - */ - -typedef struct IXPMap IXPMap; -struct IXPMap { - unsigned int fid; - Qid qid; -}; - -typedef struct { - IXPMap **map; - size_t mapsz; - Fcall *fcall; - Fcall **async; - size_t asyncsz; -} IXPReq; - -/* server.c */ -Fcall ** ixp_server_attach_fcall(Fcall *f, Fcall **array, size_t *size); -void ixp_server_detach_fcall(Fcall *f, Fcall **array); -IXPMap ** ixp_server_attach_map(IXPMap *m, IXPMap **array, size_t *size); -void ixp_server_detach_map(IXPMap *m, IXPMap **array); -IXPMap * ixp_server_fid2map(IXPReq *r, unsigned int fid); -void ixp_server_close_conn(IXPServer *s, IXPConn *c); - -/************* end: this should be moved to libwmii ****************/ - typedef struct { int fd; unsigned int root_fid; @@ -290,17 +272,12 @@ void *ixp_dec_stat(unsigned char *msg, Stat *stat); /* message.c */ unsigned short ixp_sizeof_stat(Stat *stat); -unsigned int ixp_fcall_to_msg(Fcall *fcall, void *msg, - unsigned int msglen); -unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, - Fcall *fcall); +unsigned int ixp_fcall_to_msg(Fcall *fcall, void *msg, unsigned int msglen); +unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall *fcall); /* server.c */ -IXPConn *ixp_server_alloc_conn(IXPServer *s); -void ixp_server_free_conn(IXPServer *s, IXPConn *c); char *ixp_server_loop(IXPServer *s); -void ixp_server_init(IXPServer *s); -void ixp_server_deinit(IXPServer *s); +IXPMap *ixp_server_fid2map(IXPConn *c, unsigned int fid); /* socket.c */ int ixp_connect_sock(char *address); diff --git a/libixp2/server.c b/libixp2/server.c @@ -17,52 +17,27 @@ #include "ixp.h" #include "cext.h" -static IXPConn zero_conn = { -1, 0, 0, 0 }; - -IXPConn * -ixp_server_alloc_conn(IXPServer *s) -{ - int i; - for(i = 0; i < IXP_MAX_CONN; i++) - if(s->conn[i].fd < 0) - return &s->conn[i]; - return nil; -} - static void prepare_select(IXPServer *s) { int i; FD_ZERO(&s->rd); - for(i = 0; i < IXP_MAX_CONN; i++) { - if(s->conn[i].fd >= 0) { - if(s->maxfd < s->conn[i].fd) - s->maxfd = s->conn[i].fd; - if(s->conn[i].read) - FD_SET(s->conn[i].fd, &s->rd); - } + for(i = 0; (i < s->connsz) && s->conn[i]; i++) { + if(s->maxfd < s->conn[i]->fd) + s->maxfd = s->conn[i]->fd; + if(s->conn[i]->read) + FD_SET(s->conn[i]->fd, &s->rd); } } -void -ixp_server_free_conn(IXPServer *s, IXPConn *c) -{ - if(c->close) - c->close(s, c); - *c = zero_conn; -} - static void handle_conns(IXPServer *s) { int i; - for(i = 0; i < IXP_MAX_CONN; i++) { - if(s->conn[i].fd >= 0) { - if(FD_ISSET(s->conn[i].fd, &s->rd) && s->conn[i].read) - /* call back read handler */ - s->conn[i].read(s, &s->conn[i]); - } - } + for(i = 0; (i < s->connsz) && s->conn[i]; i++) + if(FD_ISSET(s->conn[i]->fd, &s->rd) && s->conn[i]->read) + /* call read handler */ + s->conn[i]->read(s, s->conn[i]); } char * @@ -72,7 +47,7 @@ ixp_server_loop(IXPServer *s) s->running = 1; /* main loop */ - while(s->running) { + while(s->running && s->conn) { prepare_select(s); @@ -87,118 +62,12 @@ ixp_server_loop(IXPServer *s) return nil; } -void -ixp_server_init(IXPServer *s) -{ - size_t i; - for(i = 0; i < IXP_MAX_CONN; i++) - s->conn[i] = zero_conn; -} - -void -ixp_server_deinit(IXPServer *s) -{ - int i; - /* shut down server */ - for(i = 0; i < IXP_MAX_CONN; i++) - if(s->conn[i].fd >= 0) - ixp_server_free_conn(s, &s->conn[i]); -} - - -Fcall ** -ixp_server_attach_fcall(Fcall *f, Fcall **array, size_t *size) -{ - size_t i; - if(!array) { - *size = 2; - array = cext_emallocz(sizeof(Fcall *) * (*size)); - } - for(i = 0; (i < (*size)) && array[i]; i++); - if(i >= (*size)) { - Fcall **tmp = array; - (*size) *= 2; - array = cext_emallocz(sizeof(Fcall *) * (*size)); - for(i = 0; tmp[i]; i++) - array[i] = tmp[i]; - free(tmp); - } - array[i] = f; - return array; -} - -void -ixp_server_detach_fcall(Fcall *f, Fcall **array) -{ - size_t i; - for(i = 0; array[i] != f; i++); - for(; array[i + 1]; i++) - array[i] = array[i + 1]; - array[i] = nil; -} - -IXPMap ** -ixp_server_attach_map(IXPMap *m, IXPMap **array, size_t *size) -{ - size_t i; - if(!array) { - *size = 2; - array = cext_emallocz(sizeof(IXPMap *) * (*size)); - } - for(i = 0; (i < (*size)) && array[i]; i++); - if(i >= (*size)) { - IXPMap **tmp = array; - (*size) *= 2; - array = cext_emallocz(sizeof(IXPMap *) * (*size)); - for(i = 0; tmp[i]; i++) - array[i] = tmp[i]; - free(tmp); - } - array[i] = m; - return array; -} - -void -ixp_server_detach_map(IXPMap *m, IXPMap **array) -{ - size_t i; - for(i = 0; array[i] != m; i++); - for(; array[i + 1]; i++) - array[i] = array[i + 1]; - array[i] = nil; -} - - IXPMap * -ixp_server_fid2map(IXPReq *r, unsigned int fid) +ixp_server_fid2map(IXPConn *c, unsigned int fid) { size_t i; - for(i = 0; (i < r->mapsz) && r->map[i]; i++) - if(r->map[i]->fid == fid) - return r->map[i]; + for(i = 0; (i < c->mapsz) && c->map[i]; i++) + if(c->map[i]->fid == fid) + return c->map[i]; return nil; } - -void -ixp_server_close_conn(IXPServer *s, IXPConn *c) -{ - IXPReq *r = c->aux; - - if(r) { - size_t i; - if(r->map) { - for(i = 0; (i < r->mapsz) && r->map[i]; i++) - free(r->map[i]); - free(r->map); - } - if(r->async) { - for(i = 0; (i < r->asyncsz) && r->async[i]; i++) - free(r->async[i]); - free(r->async); - free(r); - } - } - c->aux = nil; - shutdown(c->fd, SHUT_RDWR); - close(c->fd); -}