libixp

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

commit e9f62eb246537af265d7ed98eb696d95abd2e6ec
parent 9a44f48eca37c7ced9c93da6002dfec2d77e32da
Author: Kris Maglione <jg@suckless.org>
Date:   Sat, 10 Oct 2009 14:59:02 -0400

Remove LPL-licensed Plan 9 code. Update build system. Cleanup.

Diffstat:
config.mk | 2+-
include/ixp.h | 4++--
include/ixp_local.h | 42+++++++++++++++++-------------------------
libixp/LICENSE | 5++---
libixp/LICENSE.p9p | 251-------------------------------------------------------------------------------
libixp/Makefile | 2+-
libixp/intmap.c | 151------------------------------------------------------------------------------
libixp/map.c | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
libixp/request.c | 304+++++++++++++++++++++++++++++++++++++++++--------------------------------------
mk/hdr.mk | 37++++++++++++++++++++++++++++---------
mk/ixp.mk | 2+-
util/compile | 5++++-
util/link | 3+++
13 files changed, 349 insertions(+), 591 deletions(-)

diff --git a/config.mk b/config.mk @@ -13,7 +13,7 @@ PREFIX = /usr/local INCLUDE = $(PREFIX)/include # Includes and libs -INCPATH = .:$(ROOT)/include:$(INCLUDE):/usr/include +INCLUDES = -I. -I$(ROOT)/include -I$(INCLUDE) -I/usr/include LIBS = -L/usr/lib -lc # Flags diff --git a/include/ixp.h b/include/ixp.h @@ -216,7 +216,7 @@ enum { # define IxpStat Stat #endif -typedef struct Intmap Intmap; +typedef struct IxpMap IxpMap; typedef struct Ixp9Conn Ixp9Conn; typedef struct Ixp9Req Ixp9Req; typedef struct Ixp9Srv Ixp9Srv; @@ -543,7 +543,7 @@ struct IxpFid { /* Implementation details */ Ixp9Conn* conn; - Intmap* map; + IxpMap* map; }; struct Ixp9Req { diff --git a/include/ixp_local.h b/include/ixp_local.h @@ -1,6 +1,7 @@ #define IXP_NO_P9_ #define IXP_P9_STRUCTS #include <ixp.h> +#include <stdbool.h> char *argv0; #define ARGBEGIN \ @@ -30,6 +31,7 @@ char *argv0; #undef nil #define nil ((void*)0) +#define nelem(ary) (sizeof(ary) / sizeof(*ary)) #define thread ixp_thread @@ -45,29 +47,22 @@ char *argv0; #define muxfree ixp_muxfree #define muxrpc ixp_muxrpc -#define initmap ixp_initmap -#define incref ixp_incref -#define decref ixp_decref -#define freemap ixp_freemap -#define execmap ixp_execmap -#define lookupkey ixp_lookupkey -#define insertkey ixp_insertkey -#define deletekey ixp_deletekey -#define caninsertkey ixp_caninsertkey - #define errstr ixp_errstr #define rerrstr ixp_rerrstr #define werrstr ixp_werrstr -typedef struct Intlist Intlist; +typedef struct IxpMap Map; +typedef struct MapEnt MapEnt; + typedef IxpTimer Timer; typedef struct timeval timeval; -struct Intmap { - ulong nhash; - Intlist **hash; - IxpRWLock lk; +struct IxpMap { + MapEnt** bucket; + int nhash; + + IxpRWLock lock; }; struct IxpTimer { @@ -78,16 +73,13 @@ struct IxpTimer { void* aux; }; -/* intmap.c */ -int caninsertkey(Intmap*, ulong, void*); -void decref_map(Intmap*); -void* deletekey(Intmap*, ulong); -void execmap(Intmap*, void (*destroy)(void*)); -void freemap(Intmap*, void (*destroy)(void*)); -void incref_map(Intmap*); -void initmap(Intmap*, ulong, void*); -void* insertkey(Intmap*, ulong, void*); -void* lookupkey(Intmap*, ulong); +/* map.c */ +void ixp_mapfree(Map*, void(*)(void*)); +void ixp_mapexec(Map*, void(*)(void*, void*), void*); +void ixp_mapinit(Map*, MapEnt**, int); +bool ixp_mapinsert(Map*, ulong, void*, bool); +void* ixp_mapget(Map*, ulong); +void* ixp_maprm(Map*, ulong); /* mux.c */ void muxfree(IxpClient*); diff --git a/libixp/LICENSE b/libixp/LICENSE @@ -1,7 +1,6 @@ -MIT/X Consortium License -(C)opyright MMV-MMVI Anselm R. Garbe <garbeam@gmail.com> -(C)opyright MMVI Kris Maglione <bsdaemon at comcast dot net> +© 2005-2006 Anselm R. Garbe <garbeam@gmail.com> +© 2006-2009 Kris Maglione <maglione.k at Gmail> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/libixp/LICENSE.p9p b/libixp/LICENSE.p9p @@ -1,251 +0,0 @@ -The bulk of this software is derived from Plan 9 and is thus distributed -under the Lucent Public License, Version 1.02, reproduced below. - -There are a few exceptions: libutf, libfmt, and libregexp are distributed -under simpler BSD-like boilerplates. See the LICENSE files in those -directories. There are other exceptions, also marked with LICENSE files -in their directories. - -The bitmap fonts in the font/luc, font/lucm, font/lucsans, and font/pelm -directory are copyright B&H Inc. and distributed under more restricted -terms under agreement with B&H. See the NOTICE file in those directories. - -=================================================================== - -Lucent Public License Version 1.02 - -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC -LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE -PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS - -"Contribution" means: - - a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original - Program, and - b. in the case of each Contributor, - - i. changes to the Program, and - ii. additions to the Program; - - where such changes and/or additions to the Program were added to the - Program by such Contributor itself or anyone acting on such - Contributor's behalf, and the Contributor explicitly consents, in - accordance with Section 3C, to characterization of the changes and/or - additions as Contributions. - -"Contributor" means LUCENT and any other entity that has Contributed a -Contribution to the Program. - -"Distributor" means a Recipient that distributes the Program, -modifications to the Program, or any part thereof. - -"Licensed Patents" mean patent claims licensable by a Contributor -which are necessarily infringed by the use or sale of its Contribution -alone or when combined with the Program. - -"Original Program" means the original version of the software -accompanying this Agreement as released by LUCENT, including source -code, object code and documentation, if any. - -"Program" means the Original Program and Contributions or any part -thereof - -"Recipient" means anyone who receives the Program under this -Agreement, including all Contributors. - -2. GRANT OF RIGHTS - - a. Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free copyright - license to reproduce, prepare derivative works of, publicly display, - publicly perform, distribute and sublicense the Contribution of such - Contributor, if any, and such derivative works, in source code and - object code form. - - b. Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free patent - license under Licensed Patents to make, use, sell, offer to sell, - import and otherwise transfer the Contribution of such Contributor, if - any, in source code and object code form. The patent license granted - by a Contributor shall also apply to the combination of the - Contribution of that Contributor and the Program if, at the time the - Contribution is added by the Contributor, such addition of the - Contribution causes such combination to be covered by the Licensed - Patents. The patent license granted by a Contributor shall not apply - to (i) any other combinations which include the Contribution, nor to - (ii) Contributions of other Contributors. No hardware per se is - licensed hereunder. - - c. Recipient understands that although each Contributor grants the - licenses to its Contributions set forth herein, no assurances are - provided by any Contributor that the Program does not infringe the - patent or other intellectual property rights of any other entity. Each - Contributor disclaims any liability to Recipient for claims brought by - any other entity based on infringement of intellectual property rights - or otherwise. As a condition to exercising the rights and licenses - granted hereunder, each Recipient hereby assumes sole responsibility - to secure any other intellectual property rights needed, if any. For - example, if a third party patent license is required to allow - Recipient to distribute the Program, it is Recipient's responsibility - to acquire that license before distributing the Program. - - d. Each Contributor represents that to its knowledge it has sufficient - copyright rights in its Contribution, if any, to grant the copyright - license set forth in this Agreement. - -3. REQUIREMENTS - -A. Distributor may choose to distribute the Program in any form under -this Agreement or under its own license agreement, provided that: - - a. it complies with the terms and conditions of this Agreement; - - b. if the Program is distributed in source code or other tangible - form, a copy of this Agreement or Distributor's own license agreement - is included with each copy of the Program; and - - c. if distributed under Distributor's own license agreement, such - license agreement: - - i. effectively disclaims on behalf of all Contributors all warranties - and conditions, express and implied, including warranties or - conditions of title and non-infringement, and implied warranties or - conditions of merchantability and fitness for a particular purpose; - ii. effectively excludes on behalf of all Contributors all liability - for damages, including direct, indirect, special, incidental and - consequential damages, such as lost profits; and - iii. states that any provisions which differ from this Agreement are - offered by that Contributor alone and not by any other party. - -B. Each Distributor must include the following in a conspicuous - location in the Program: - - Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights - Reserved. - -C. In addition, each Contributor must identify itself as the -originator of its Contribution in a manner that reasonably allows -subsequent Recipients to identify the originator of the Contribution. -Also, each Contributor must agree that the additions and/or changes -are intended to be a Contribution. Once a Contribution is contributed, -it may not thereafter be revoked. - -4. COMMERCIAL DISTRIBUTION - -Commercial distributors of software may accept certain -responsibilities with respect to end users, business partners and the -like. While this license is intended to facilitate the commercial use -of the Program, the Distributor who includes the Program in a -commercial product offering should do so in a manner which does not -create potential liability for Contributors. Therefore, if a -Distributor includes the Program in a commercial product offering, -such Distributor ("Commercial Distributor") hereby agrees to defend -and indemnify every Contributor ("Indemnified Contributor") against -any losses, damages and costs (collectively"Losses") arising from -claims, lawsuits and other legal actions brought by a third party -against the Indemnified Contributor to the extent caused by the acts -or omissions of such Commercial Distributor in connection with its -distribution of the Program in a commercial product offering. The -obligations in this section do not apply to any claims or Losses -relating to any actual or alleged intellectual property infringement. -In order to qualify, an Indemnified Contributor must: a) promptly -notify the Commercial Distributor in writing of such claim, and b) -allow the Commercial Distributor to control, and cooperate with the -Commercial Distributor in, the defense and any related settlement -negotiations. The Indemnified Contributor may participate in any such -claim at its own expense. - -For example, a Distributor might include the Program in a commercial -product offering, Product X. That Distributor is then a Commercial -Distributor. If that Commercial Distributor then makes performance -claims, or offers warranties related to Product X, those performance -claims and warranties are such Commercial Distributor's responsibility -alone. Under this section, the Commercial Distributor would have to -defend claims against the Contributors related to those performance -claims and warranties, and if a court requires any Contributor to pay -any damages as a result, the Commercial Distributor must pay those -damages. - -5. NO WARRANTY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS -PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY -WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY -OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely -responsible for determining the appropriateness of using and -distributing the Program and assumes all risks associated with its -exercise of rights under this Agreement, including but not limited to -the risks and costs of program errors, compliance with applicable -laws, damage to or loss of data, programs or equipment, and -unavailability or interruption of operations. - -6. DISCLAIMER OF LIABILITY - -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR -ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING -WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR -DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. EXPORT CONTROL - -Recipient agrees that Recipient alone is responsible for compliance -with the United States export administration regulations (and the -export control laws and regulation of any other countries). - -8. GENERAL - -If any provision of this Agreement is invalid or unenforceable under -applicable law, it shall not affect the validity or enforceability of -the remainder of the terms of this Agreement, and without further -action by the parties hereto, such provision shall be reformed to the -minimum extent necessary to make such provision valid and enforceable. - -If Recipient institutes patent litigation against a Contributor with -respect to a patent applicable to software (including a cross-claim or -counterclaim in a lawsuit), then any patent licenses granted by that -Contributor to such Recipient under this Agreement shall terminate as -of the date such litigation is filed. In addition, if Recipient -institutes patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Program -itself (excluding combinations of the Program with other software or -hardware) infringes such Recipient's patent(s), then such Recipient's -rights granted under Section 2(b) shall terminate as of the date such -litigation is filed. - -All Recipient's rights under this Agreement shall terminate if it -fails to comply with any of the material terms or conditions of this -Agreement and does not cure such failure in a reasonable period of -time after becoming aware of such noncompliance. If all Recipient's -rights under this Agreement terminate, Recipient agrees to cease use -and distribution of the Program as soon as reasonably practicable. -However, Recipient's obligations under this Agreement and any licenses -granted by Recipient relating to the Program shall continue and -survive. - -LUCENT may publish new versions (including revisions) of this -Agreement from time to time. Each new version of the Agreement will be -given a distinguishing version number. The Program (including -Contributions) may always be distributed subject to the version of the -Agreement under which it was received. In addition, after a new -version of the Agreement is published, Contributor may elect to -distribute the Program (including its Contributions) under the new -version. No one other than LUCENT has the right to modify this -Agreement. Except as expressly stated in Sections 2(a) and 2(b) above, -Recipient receives no rights or licenses to the intellectual property -of any Contributor under this Agreement, whether expressly, by -implication, estoppel or otherwise. All rights in the Program not -expressly granted under this Agreement are reserved. - -This Agreement is governed by the laws of the State of New York and -the intellectual property laws of the United States of America. No -party to this Agreement will bring a legal action under this Agreement -more than one year after the cause of action arose. Each party waives -its rights to a jury trial in any resulting litigation. - diff --git a/libixp/Makefile b/libixp/Makefile @@ -7,7 +7,7 @@ TARG = libixp OBJ = client \ convert \ error \ - intmap \ + map \ message \ request \ rpc \ diff --git a/libixp/intmap.c b/libixp/intmap.c @@ -1,151 +0,0 @@ -/* This file is derived from src/lib9p/intmap.c from plan9port */ -/* See LICENCE.p9p for terms of use */ - -#include <stdlib.h> -#include "ixp_local.h" - -struct Intlist { - ulong id; - void* aux; - Intlist* link; - uint ref; -}; - -static ulong -hashid(Intmap *map, ulong id) { - return id%map->nhash; -} - -static void -nop(void *v) { - USED(v); -} - -void -initmap(Intmap *m, ulong nhash, void *hash) { - m->nhash = nhash; - m->hash = hash; - - thread->initrwlock(&m->lk); -} - -static Intlist** -llookup(Intmap *map, ulong id) { - Intlist **lf; - - for(lf=&map->hash[hashid(map, id)]; *lf; lf=&(*lf)->link) - if((*lf)->id == id) - break; - return lf; -} - -void -freemap(Intmap *map, void (*destroy)(void*)) { - int i; - Intlist *p, *nlink; - - if(destroy == nil) - destroy = nop; - for(i=0; i<map->nhash; i++){ - for(p=map->hash[i]; p; p=nlink){ - nlink = p->link; - destroy(p->aux); - free(p); - } - } - - thread->rwdestroy(&map->lk); -} - -void -execmap(Intmap *map, void (*run)(void*)) { - int i; - Intlist *p, *nlink; - - thread->rlock(&map->lk); - for(i=0; i<map->nhash; i++){ - for(p=map->hash[i]; p; p=nlink){ - thread->runlock(&map->lk); - nlink = p->link; - run(p->aux); - thread->rlock(&map->lk); - } - } - thread->runlock(&map->lk); -} - -void* -lookupkey(Intmap *map, ulong id) { - Intlist *f; - void *v; - - thread->rlock(&map->lk); - if((f = *llookup(map, id))) - v = f->aux; - else - v = nil; - thread->runlock(&map->lk); - return v; -} - -void* -insertkey(Intmap *map, ulong id, void *v) { - Intlist *f; - void *ov; - ulong h; - - thread->wlock(&map->lk); - if((f = *llookup(map, id))){ - /* no decrement for ov because we're returning it */ - ov = f->aux; - f->aux = v; - }else{ - f = emallocz(sizeof *f); - f->id = id; - f->aux = v; - h = hashid(map, id); - f->link = map->hash[h]; - map->hash[h] = f; - ov = nil; - } - thread->wunlock(&map->lk); - return ov; -} - -int -caninsertkey(Intmap *map, ulong id, void *v) { - Intlist *f; - int rv; - ulong h; - - thread->wlock(&map->lk); - if(*llookup(map, id)) - rv = 0; - else{ - f = emallocz(sizeof *f); - f->id = id; - f->aux = v; - h = hashid(map, id); - f->link = map->hash[h]; - map->hash[h] = f; - rv = 1; - } - thread->wunlock(&map->lk); - return rv; -} - -void* -deletekey(Intmap *map, ulong id) { - Intlist **lf, *f; - void *ov; - - thread->wlock(&map->lk); - if((f = *(lf = llookup(map, id)))){ - ov = f->aux; - *lf = f->link; - free(f); - }else - ov = nil; - thread->wunlock(&map->lk); - return ov; -} diff --git a/libixp/map.c b/libixp/map.c @@ -0,0 +1,132 @@ +/* Written by Kris Maglione */ +/* Public domain */ +#include <stdlib.h> +#include "ixp_local.h" + +/* Edit s/^([a-zA-Z].*)\n([a-z].*) {/\1 \2;/g x/^([^a-zA-Z]|static|$)/-+d s/ (\*map|val|*str)//g */ + +struct MapEnt { + ulong hash; + const char* key; + void* val; + MapEnt* next; +}; + +MapEnt *NM; + +static void +insert(MapEnt **e, ulong val, const char *key) { + MapEnt *te; + + te = emallocz(sizeof *te); + te->hash = val; + te->key = key; + te->next = *e; + *e = te; +} + +static MapEnt** +map_getp(Map *map, ulong val, bool create, bool *exists) { + MapEnt **e; + + e = &map->bucket[val%map->nhash]; + for(; *e; e = &(*e)->next) + if((*e)->hash >= val) break; + if(exists) + *exists = *e && (*e)->hash == val; + + if(*e == nil || (*e)->hash != val) { + if(create) + insert(e, val, nil); + else + e = &NM; + } + return e; +} + +void +ixp_mapfree(Map *map, void (*destroy)(void*)) { + int i; + MapEnt *e; + + thread->wlock(&map->lock); + for(i=0; i < map->nhash; i++) + while((e = map->bucket[i])) { + map->bucket[i] = e->next; + if(destroy) + destroy(e->val); + free(e); + } + thread->wunlock(&map->lock); + thread->rwdestroy(&map->lock); +} + +void +ixp_mapexec(Map *map, void (*run)(void*, void*), void *context) { + int i; + MapEnt *e; + + thread->rlock(&map->lock); + for(i=0; i < map->nhash; i++) + for(e=map->bucket[i]; e; e=e->next) + run(context, e->val); + thread->runlock(&map->lock); +} + +void +ixp_mapinit(Map *map, MapEnt **buckets, int nbuckets) { + + map->bucket = buckets; + map->nhash = nbuckets; + + thread->initrwlock(&map->lock); +} + +bool +ixp_mapinsert(Map *map, ulong key, void *val, bool overwrite) { + MapEnt *e; + bool existed, res; + + res = true; + thread->wlock(&map->lock); + e = *map_getp(map, key, true, &existed); + if(existed && !overwrite) + res = false; + else + e->val = val; + thread->wunlock(&map->lock); + return res; +} + +void* +ixp_mapget(Map *map, ulong val) { + MapEnt *e; + void *res; + + thread->rlock(&map->lock); + e = *map_getp(map, val, false, nil); + res = e ? e->val : nil; + thread->runlock(&map->lock); + return res; +} + +void* +ixp_maprm(Map *map, ulong val) { + MapEnt **e, *te; + void *ret; + + ret = nil; + thread->wlock(&map->lock); + e = map_getp(map, val, false, nil); + if(*e) { + te = *e; + ret = te->val; + *e = te->next; + thread->wunlock(&map->lock); + free(te); + } + else + thread->wunlock(&map->lock); + return ret; +} + diff --git a/libixp/request.c b/libixp/request.c @@ -42,68 +42,69 @@ enum { }; struct Ixp9Conn { - Intmap tagmap; - Intmap fidmap; - void *taghash[TAG_BUCKETS]; - void *fidhash[FID_BUCKETS]; - Ixp9Srv *srv; - IxpConn *conn; - IxpMutex rlock, wlock; + Map tagmap; + Map fidmap; + MapEnt* taghash[TAG_BUCKETS]; + MapEnt* fidhash[FID_BUCKETS]; + Ixp9Srv* srv; + IxpConn* conn; + IxpMutex rlock; + IxpMutex wlock; IxpMsg rmsg; IxpMsg wmsg; int ref; }; static void -decref_p9conn(Ixp9Conn *pc) { - thread->lock(&pc->wlock); - if(--pc->ref > 0) { - thread->unlock(&pc->wlock); +decref_p9conn(Ixp9Conn *p9conn) { + thread->lock(&p9conn->wlock); + if(--p9conn->ref > 0) { + thread->unlock(&p9conn->wlock); return; } - thread->unlock(&pc->wlock); + thread->unlock(&p9conn->wlock); - assert(pc->conn == nil); + assert(p9conn->conn == nil); - thread->mdestroy(&pc->rlock); - thread->mdestroy(&pc->wlock); + thread->mdestroy(&p9conn->rlock); + thread->mdestroy(&p9conn->wlock); - freemap(&pc->tagmap, nil); - freemap(&pc->fidmap, nil); + ixp_mapfree(&p9conn->tagmap, nil); + ixp_mapfree(&p9conn->fidmap, nil); - free(pc->rmsg.data); - free(pc->wmsg.data); - free(pc); + free(p9conn->rmsg.data); + free(p9conn->wmsg.data); + free(p9conn); } static void* -createfid(Intmap *map, int fid, Ixp9Conn *pc) { +createfid(Map *map, int fid, Ixp9Conn *p9conn) { Fid *f; f = emallocz(sizeof *f); - pc->ref++; - f->conn = pc; + p9conn->ref++; + f->conn = p9conn; f->fid = fid; f->omode = -1; f->map = map; - if(caninsertkey(map, fid, f)) + if(ixp_mapinsert(map, fid, f, false)) return f; free(f); return nil; } static int -destroyfid(Ixp9Conn *pc, ulong fid) { +destroyfid(Ixp9Conn *p9conn, ulong fid) { Fid *f; - f = deletekey(&pc->fidmap, fid); + f = ixp_maprm(&p9conn->fidmap, fid); if(f == nil) return 0; - if(pc->srv->freefid) - pc->srv->freefid(f); + if(p9conn->srv->freefid) + p9conn->srv->freefid(f); - decref_p9conn(pc); + decref_p9conn(p9conn); free(f); return 1; } @@ -111,26 +112,26 @@ destroyfid(Ixp9Conn *pc, ulong fid) { static void handlefcall(IxpConn *c) { Fcall fcall = {0}; - Ixp9Conn *pc; + Ixp9Conn *p9conn; Ixp9Req *req; - pc = c->aux; + p9conn = c->aux; - thread->lock(&pc->rlock); - if(ixp_recvmsg(c->fd, &pc->rmsg) == 0) + thread->lock(&p9conn->rlock); + if(ixp_recvmsg(c->fd, &p9conn->rmsg) == 0) goto Fail; - if(ixp_msg2fcall(&pc->rmsg, &fcall) == 0) + if(ixp_msg2fcall(&p9conn->rmsg, &fcall) == 0) goto Fail; - thread->unlock(&pc->rlock); + thread->unlock(&p9conn->rlock); req = emallocz(sizeof *req); - pc->ref++; - req->conn = pc; - req->srv = pc->srv; + p9conn->ref++; + req->conn = p9conn; + req->srv = p9conn->srv; req->ifcall = fcall; - pc->conn = c; + p9conn->conn = c; - if(caninsertkey(&pc->tagmap, fcall.hdr.tag, req) == 0) { + if(!ixp_mapinsert(&p9conn->tagmap, fcall.hdr.tag, req, false)) { respond(req, Eduptag); return; } @@ -139,18 +140,18 @@ handlefcall(IxpConn *c) { return; Fail: - thread->unlock(&pc->rlock); + thread->unlock(&p9conn->rlock); ixp_hangup(c); return; } static void handlereq(Ixp9Req *r) { - Ixp9Conn *pc; + Ixp9Conn *p9conn; Ixp9Srv *srv; - pc = r->conn; - srv = pc->srv; + p9conn = r->conn; + srv = p9conn->srv; ixp_printfcall(&r->ifcall); @@ -169,7 +170,7 @@ handlereq(Ixp9Req *r) { respond(r, nil); break; case TAttach: - if(!(r->fid = createfid(&pc->fidmap, r->ifcall.hdr.fid, pc))) { + if(!(r->fid = createfid(&p9conn->fidmap, r->ifcall.hdr.fid, p9conn))) { respond(r, Edupfid); return; } @@ -177,7 +178,7 @@ handlereq(Ixp9Req *r) { srv->attach(r); break; case TClunk: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -188,7 +189,7 @@ handlereq(Ixp9Req *r) { srv->clunk(r); break; case TFlush: - if(!(r->oldreq = lookupkey(&pc->tagmap, r->ifcall.tflush.oldtag))) { + if(!(r->oldreq = ixp_mapget(&p9conn->tagmap, r->ifcall.tflush.oldtag))) { respond(r, Enotag); return; } @@ -199,7 +200,7 @@ handlereq(Ixp9Req *r) { srv->flush(r); break; case TCreate: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -211,14 +212,14 @@ handlereq(Ixp9Req *r) { respond(r, Enotdir); return; } - if(!pc->srv->create) { + if(!p9conn->srv->create) { respond(r, Enofunc); return; } - pc->srv->create(r); + p9conn->srv->create(r); break; case TOpen: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -227,14 +228,14 @@ handlereq(Ixp9Req *r) { return; } r->ofcall.ropen.qid = r->fid->qid; - if(!pc->srv->open) { + if(!p9conn->srv->open) { respond(r, Enofunc); return; } - pc->srv->open(r); + p9conn->srv->open(r); break; case TRead: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -242,36 +243,36 @@ handlereq(Ixp9Req *r) { respond(r, Enoread); return; } - if(!pc->srv->read) { + if(!p9conn->srv->read) { respond(r, Enofunc); return; } - pc->srv->read(r); + p9conn->srv->read(r); break; case TRemove: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } - if(!pc->srv->remove) { + if(!p9conn->srv->remove) { respond(r, Enofunc); return; } - pc->srv->remove(r); + p9conn->srv->remove(r); break; case TStat: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } - if(!pc->srv->stat) { + if(!p9conn->srv->stat) { respond(r, Enofunc); return; } - pc->srv->stat(r); + p9conn->srv->stat(r); break; case TWalk: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -284,20 +285,20 @@ handlereq(Ixp9Req *r) { return; } if((r->ifcall.hdr.fid != r->ifcall.twalk.newfid)) { - if(!(r->newfid = createfid(&pc->fidmap, r->ifcall.twalk.newfid, pc))) { + if(!(r->newfid = createfid(&p9conn->fidmap, r->ifcall.twalk.newfid, p9conn))) { respond(r, Edupfid); return; } }else r->newfid = r->fid; - if(!pc->srv->walk) { + if(!p9conn->srv->walk) { respond(r, Enofunc); return; } - pc->srv->walk(r); + p9conn->srv->walk(r); break; case TWrite: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -305,14 +306,14 @@ handlereq(Ixp9Req *r) { respond(r, "write on fid not opened for writing"); return; } - if(!pc->srv->write) { + if(!p9conn->srv->write) { respond(r, Enofunc); return; } - pc->srv->write(r); + p9conn->srv->write(r); break; case TWStat: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) { + if(!(r->fid = ixp_mapget(&p9conn->fidmap, r->ifcall.hdr.fid))) { respond(r, Enofid); return; } @@ -336,7 +337,7 @@ handlereq(Ixp9Req *r) { respond(r, "wstat on DMDIR bit"); return; } - pc->srv->wstat(r); + p9conn->srv->wstat(r); break; /* Still to be implemented: auth */ } @@ -344,10 +345,10 @@ handlereq(Ixp9Req *r) { void respond(Ixp9Req *r, const char *error) { - Ixp9Conn *pc; + Ixp9Conn *p9conn; int msize; - pc = r->conn; + p9conn = r->conn; switch(r->ifcall.hdr.type) { default: @@ -358,27 +359,27 @@ respond(Ixp9Req *r, const char *error) { assert(error == nil); free(r->ifcall.version.version); - thread->lock(&pc->rlock); - thread->lock(&pc->wlock); + thread->lock(&p9conn->rlock); + thread->lock(&p9conn->wlock); msize = min(r->ofcall.version.msize, IXP_MAX_MSG); - pc->rmsg.data = erealloc(pc->rmsg.data, msize); - pc->wmsg.data = erealloc(pc->wmsg.data, msize); - pc->rmsg.size = msize; - pc->wmsg.size = msize; - thread->unlock(&pc->wlock); - thread->unlock(&pc->rlock); + p9conn->rmsg.data = erealloc(p9conn->rmsg.data, msize); + p9conn->wmsg.data = erealloc(p9conn->wmsg.data, msize); + p9conn->rmsg.size = msize; + p9conn->wmsg.size = msize; + thread->unlock(&p9conn->wlock); + thread->unlock(&p9conn->rlock); r->ofcall.version.msize = msize; break; case TAttach: if(error) - destroyfid(pc, r->fid->fid); + destroyfid(p9conn, r->fid->fid); free(r->ifcall.tattach.uname); free(r->ifcall.tattach.aname); break; case TOpen: case TCreate: if(!error) { - r->ofcall.ropen.iounit = pc->rmsg.size - 24; + r->ofcall.ropen.iounit = p9conn->rmsg.size - 24; r->fid->iounit = r->ofcall.ropen.iounit; r->fid->omode = r->ifcall.topen.mode; r->fid->qid = r->ofcall.ropen.qid; @@ -388,7 +389,7 @@ respond(Ixp9Req *r, const char *error) { case TWalk: if(error || r->ofcall.rwalk.nwqid < r->ifcall.twalk.nwname) { if(r->ifcall.hdr.fid != r->ifcall.twalk.newfid && r->newfid) - destroyfid(pc, r->newfid->fid); + destroyfid(p9conn, r->newfid->fid); if(!error && r->ofcall.rwalk.nwqid == 0) error = Enofile; }else{ @@ -404,14 +405,14 @@ respond(Ixp9Req *r, const char *error) { break; case TRemove: if(r->fid) - destroyfid(pc, r->fid->fid); + destroyfid(p9conn, r->fid->fid); break; case TClunk: if(r->fid) - destroyfid(pc, r->fid->fid); + destroyfid(p9conn, r->fid->fid); break; case TFlush: - if((r->oldreq = lookupkey(&pc->tagmap, r->ifcall.tflush.oldtag))) + if((r->oldreq = ixp_mapget(&p9conn->tagmap, r->ifcall.tflush.oldtag))) respond(r->oldreq, Eintr); break; case TWStat: @@ -432,14 +433,14 @@ respond(Ixp9Req *r, const char *error) { r->ofcall.error.ename = (char*)error; } - deletekey(&pc->tagmap, r->ifcall.hdr.tag);; + ixp_maprm(&p9conn->tagmap, r->ifcall.hdr.tag);; - if(pc->conn) { - thread->lock(&pc->wlock); - msize = ixp_fcall2msg(&pc->wmsg, &r->ofcall); - if(ixp_sendmsg(pc->conn->fd, &pc->wmsg) != msize) - ixp_hangup(pc->conn); - thread->unlock(&pc->wlock); + if(p9conn->conn) { + thread->lock(&p9conn->wlock); + msize = ixp_fcall2msg(&p9conn->wmsg, &r->ofcall); + if(ixp_sendmsg(p9conn->conn->fd, &p9conn->wmsg) != msize) + ixp_hangup(p9conn->conn); + thread->unlock(&p9conn->wlock); } switch(r->ofcall.hdr.type) { @@ -451,82 +452,93 @@ respond(Ixp9Req *r, const char *error) { break; } free(r); - decref_p9conn(pc); + decref_p9conn(p9conn); } /* Flush a pending request */ static void -voidrequest(void *t) { - Ixp9Req *r, *tr; - Ixp9Conn *pc; - - r = t; - pc = r->conn; - pc->ref++; - - tr = emallocz(sizeof *tr); - tr->ifcall.hdr.type = TFlush; - tr->ifcall.hdr.tag = IXP_NOTAG; - tr->ifcall.tflush.oldtag = r->ifcall.hdr.tag; - tr->conn = pc; - handlereq(tr); +voidrequest(void *context, void *arg) { + Ixp9Req *orig_req, *flush_req; + Ixp9Conn *conn; + + orig_req = arg; + conn = orig_req->conn; + conn->ref++; + + flush_req = emallocz(sizeof *orig_req); + flush_req->ifcall.hdr.type = TFlush; + flush_req->ifcall.hdr.tag = IXP_NOTAG; + flush_req->ifcall.tflush.oldtag = orig_req->ifcall.hdr.tag; + flush_req->conn = conn; + + flush_req->aux = *(void**)context; + *(void**)context = flush_req; } /* Clunk an open Fid */ static void -voidfid(void *t) { - Ixp9Conn *pc; - Ixp9Req *tr; - Fid *f; - - f = t; - pc = f->conn; - pc->ref++; - - tr = emallocz(sizeof *tr); - tr->ifcall.hdr.type = TClunk; - tr->ifcall.hdr.tag = IXP_NOTAG; - tr->ifcall.hdr.fid = f->fid; - tr->fid = f; - tr->conn = pc; - handlereq(tr); +voidfid(void *context, void *arg) { + Ixp9Conn *p9conn; + Ixp9Req *clunk_req; + Fid *fid; + + fid = arg; + p9conn = fid->conn; + p9conn->ref++; + + clunk_req = emallocz(sizeof *clunk_req); + clunk_req->ifcall.hdr.type = TClunk; + clunk_req->ifcall.hdr.tag = IXP_NOTAG; + clunk_req->ifcall.hdr.fid = fid->fid; + clunk_req->fid = fid; + clunk_req->conn = p9conn; + + clunk_req->aux = *(void**)context; + *(void**)context = clunk_req; } static void cleanupconn(IxpConn *c) { - Ixp9Conn *pc; - - pc = c->aux; - pc->conn = nil; - if(pc->ref > 1) { - execmap(&pc->tagmap, voidrequest); - execmap(&pc->fidmap, voidfid); + Ixp9Conn *p9conn; + Ixp9Req *req, *r; + + p9conn = c->aux; + p9conn->conn = nil; + req = nil; + if(p9conn->ref > 1) { + ixp_mapexec(&p9conn->fidmap, voidfid, &req); + ixp_mapexec(&p9conn->tagmap, voidrequest, &req); + } + while((r = req)) { + req = r->aux; + r->aux = nil; + handlereq(r); } - decref_p9conn(pc); + decref_p9conn(p9conn); } /* Handle incoming 9P connections */ void serve_9pcon(IxpConn *c) { - Ixp9Conn *pc; + Ixp9Conn *p9conn; int fd; fd = accept(c->fd, nil, nil); if(fd < 0) return; - pc = emallocz(sizeof *pc); - pc->ref++; - pc->srv = c->aux; - pc->rmsg.size = 1024; - pc->wmsg.size = 1024; - pc->rmsg.data = emalloc(pc->rmsg.size); - pc->wmsg.data = emalloc(pc->wmsg.size); + p9conn = emallocz(sizeof *p9conn); + p9conn->ref++; + p9conn->srv = c->aux; + p9conn->rmsg.size = 1024; + p9conn->wmsg.size = 1024; + p9conn->rmsg.data = emalloc(p9conn->rmsg.size); + p9conn->wmsg.data = emalloc(p9conn->wmsg.size); - initmap(&pc->tagmap, TAG_BUCKETS, &pc->taghash); - initmap(&pc->fidmap, FID_BUCKETS, &pc->fidhash); - thread->initmutex(&pc->rlock); - thread->initmutex(&pc->wlock); + ixp_mapinit(&p9conn->tagmap, p9conn->taghash, nelem(p9conn->taghash)); + ixp_mapinit(&p9conn->fidmap, p9conn->fidhash, nelem(p9conn->fidhash)); + thread->initmutex(&p9conn->rlock); + thread->initmutex(&p9conn->wlock); - ixp_listen(c->srv, fd, pc, handlefcall, cleanupconn); + ixp_listen(c->srv, fd, p9conn, handlefcall, cleanupconn); } diff --git a/mk/hdr.mk b/mk/hdr.mk @@ -1,11 +1,21 @@ FILTER = cat -EXCFLAGS = -I$$(echo $(INCPATH)|sed 's/:/ -I/g') -D_XOPEN_SOURCE=600 -COMPILE= CC="$(CC)" CFLAGS="$(EXCFLAGS) $(CFLAGS)" $(ROOT)/util/compile -COMPILEPIC= CC="$(CC)" CFLAGS="$(EXCFLAGS) $(CFLAGS) $(SOCFLAGS)" $(ROOT)/util/compile -LINK= LD="$(LD)" LDFLAGS="$(LDFLAGS)" $(ROOT)/util/link -LINKSO= LD="$(LD)" LDFLAGS="$(SOLDFLAGS) $(SHARED)" $(ROOT)/util/link + +EXCFLAGS = $(INCLUDES) -D_XOPEN_SOURCE=600 + +COMPILE = $(ROOT)/util/compile "$(CC)" "$(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES))" +COMPILEPIC = $(ROOT)/util/compile "$(CC)" "$(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES)) $(SOCFLAGS)" + +LINK = $(ROOT)/util/link "$(LD)" "$$(pkg-config --libs $(PACKAGES)) $(LDFLAGS)" +LINKSO = $(ROOT)/util/link "$(LD)" "$$(pkg-config --libs $(PACKAGES)) $(SOLDFLAGS) $(SHARED)" + CLEANNAME=$(ROOT)/util/cleanname + SOEXT=so +TAGFILES= + +CTAGS=ctags + +PACKAGES = 2>/dev/null include $(ROOT)/config.mk @@ -14,9 +24,10 @@ MKCFGSH=if test -f $(ROOT)/config.local.mk; then echo $(ROOT)/config.local.mk; e MKCFG:=${shell $(MKCFGSH)} MKCFG!=${MKCFGSH} include $(MKCFG) + # and this: # Try to find a sane shell. /bin/sh is a last resort, because it's -# usually bash on Linux, which means, it's painfully slow. +# usually bash on Linux, which means it's painfully slow. BINSH := $(shell \ if [ -x /bin/dash ]; then echo /bin/dash; \ elif [ -x /bin/ksh ]; then echo /bin/ksh; \ @@ -24,7 +35,7 @@ BINSH := $(shell \ BINSH != echo /bin/sh .SILENT: -.SUFFIXES: .out .o .o_pic .c .sh .rc .$(SOEXT) .awk .1 .man1 .depend .install .uninstall .clean +.SUFFIXES: .out .o .o_pic .c .pdf .sh .rc .$(SOEXT) .awk .1 .man1 .depend .install .uninstall .clean all: .c.depend: @@ -56,7 +67,7 @@ all: chmod 0755 $@ .man1.1: echo TXT2TAGS $(BASE)$< - txt2tags -o- $< | $(FILTER) >$@ + txt2tags -o- $< >$@ .out.install: echo INSTALL $$($(CLEANNAME) $(BASE)$*) @@ -82,12 +93,20 @@ all: echo UNINSTALL $$($(CLEANNAME) $(BASE)$<) rm -f $(DESTDIR)$(INCLUDE)/$< +.pdf.install: + echo INSTALL $$($(CLEANNAME) $(BASE)$<) + cp -f $< $(DESTDIR)$(DOC)/$< + chmod 0644 $(DESTDIR)$(DOC)/$< +.pdf.uninstall: + echo UNINSTALL $$($(CLEANNAME) $(BASE)$<) + rm -f $(DESTDIR)$(DOC)/$< + .1.install: set -e; \ man=1; \ path="$(MAN)/man$$man/$*.$$man"; \ echo INSTALL man $$($(CLEANNAME) "$(BASE)/$*($$man)"); \ - cp "$<" $(DESTDIR)"$$path"; \ + $(FILTER) <"$<" >$(DESTDIR)"$$path"; \ chmod 0644 $(DESTDIR)"$$path" .1.uninstall: echo UNINSTALL man $$($(CLEANNAME) $*'(1)') diff --git a/mk/ixp.mk b/mk/ixp.mk @@ -1,5 +1,5 @@ VERSION = 0.5 $(ROOT)/include/ixp.h: $(ROOT)/config.mk -CFLAGS += -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 +CFLAGS += '-DVERSION=\"$(VERSION)\"' -D_XOPEN_SOURCE=600 diff --git a/util/compile b/util/compile @@ -1,5 +1,8 @@ #!/bin/sh -f +CC=$1 +CFLAGS=$2; shift 2 + outfile="$1"; shift bin="$(echo $0 | sed 's,/[^/]*$,,')" @@ -9,7 +12,7 @@ xtmp=/tmp/cc.$$.$USER.out echo CC $($bin/cleanname ${BASE}$outfile) [ -n "$noisycc" ] && echo $CC -o $outfile $CFLAGS $@ -$CC -o $outfile $CFLAGS $@ >$xtmp 2>&1 +eval '$CC -o $outfile '"$CFLAGS"' $@ >$xtmp 2>&1' status=$? [ $? -eq 0 ] || echo $CC -o $outfile $CFLAGS $@ >&2 diff --git a/util/link b/util/link @@ -1,5 +1,8 @@ #!/bin/sh -f +LD=$1 +LDFLAGS=$2; shift 2 + outfile="$1"; shift bin="$(echo $0 | sed 's,/[^/]*$,,')"