diff options
| -rw-r--r-- | CHANGES | 457 | ||||
| -rw-r--r-- | emu/port/devsrv.c | 198 | ||||
| -rw-r--r-- | man/3/srv | 2 | ||||
| -rw-r--r-- | os/port/devsrv.c | 204 |
4 files changed, 300 insertions, 561 deletions
@@ -1,3 +1,5 @@ +20101220 + changes to srv(3) to notify client when server vanishes [issue 244, thanks to powerman and roger] 20101205 change a few types in ipif-posix.c to appease the gods emu/MacOSX/mkfile - include portmkfile at correct point for LIBFILES to work (and other, minor, changes) [issue 24] @@ -360,457 +362,4 @@ 20071015 add cap creation to infauth in server role in factotum 20071011 - remove obsolete references to sh-exception(2) -20071010 - add abhey's changes for cmd key as unicode compose key for MacOS X to emu/MacOSX/win.c -20071008 - nemo's change to emu/port/random.c; really the file needs a little rewriting for clarity (too many overlapping states) -20071002 - ensure fmtdef.h included by some lib9 functions so that va_copy is defined on older systems that lack that needless notion - <{} and >{} added to sh(1) -20070929 - move emu/MacOSX/mkfile to .../mkfile-x11 and replace it by the variant that builds for Carbon, now the default -20070927 - add working drawcursor to emu/MacOSX/win.c, based on mirtchovski's changes (but mapping general cursor images to Mac's form) -20070910 - update spki(2) [change handling of hashes, add signature functions] appl/lib/spki/spki.b module/spki.m, updated for GSoC -20070906 - add toreal to string(2) -20070905 - /appl/cmd/ed.b (caerwyn's fix for g/.../d) - also /appl/lib/ecmascript/builtin.b (toupper fix) -20070902 - make /appl/lib/daytime.b accept Daytime->text's output; add string2tm to man page (issue 59) -20070901 - add andrey's changes to emu/MacOSX/win.c (used by emu/MacOSX/mkfile-a) - add saoret's changes to dis/lookman, dis/man (issue 58) - add micah.stetson's change to /appl/cmd/src.b (issue 57) -20070817 - two old changes that weren't in the distribution... - libkeyring/rsaalg.c: previously failed to ensure the output key was the right length (really rsagen should do that) - libinterp/alt.c: use a better random number generator -20070814 - bufio.b didn't update the buffer pointers correctly on write errors -20070807 - libinterp/keyring.c don't include owner= if owner is nil or "" - add auth/rsagen -20070806 - /module/lists.m add PATH(!), also simplify concat implementation -20070725 - /dis/man initialise fils correctly to empty list and remove hack (issue 56) -20070720 - utils/5l/asm.c: ensure SBZ field in MOV is regarded as MBZ (ie, force to zero) -20070714 - add Sys->readn, update sys-read(2) - copy two repairs from emu/port/inferno.c to os/port/inferno.c - remove readn implementation from several commands - print correct diagnostic in appl/cmd/crypt.b - prevent window titlebars from being dragged out of the main window in wm/wm.b -20070619 - remembered to include /appl/cmd/trfs.b /dis/trfs.dis -20070614 - /appl/lib/venti.b bug fixes, a few more errstrs, remove prints to stderr - add initial module/vac.m appl/lib/vac.b from mjl (gsoc project ventivac) - add initial /appl/cmd/^(vacfs.b vacget.b vacput.b) /man/4/vacfs /man/1/vacget from mjl (gsoc:ventivac) - include omitted man/mkfile man/lib -20070608 - update /lib9 functions to use silly va_copy (and then va_end) instead of just assigning, to account for silly C implementations - change /appl/cmd/mc.b not to require Draw or Env (so lc works on smaller systems) - update acme to include the font size data (eg, for use by mc(1)) -20070607 - /appl/wm/man.b /appl/lib/man.b to allow 10.1 etc as section references -20070605 - add another xopen #define to lib9.h includes for Linux - copy plan9 acme's colormix -20070601 - /appl/cmd/ls.b /dis/ls.dis /man/1/ls: document new -F option and -T option - /appl/cmd/auth/factotum/factotum.b: ignore empty writes, don't fail; make a few diagnostics match plan 9 - rename /appl/cmd/mc.b to /appl/cmd/calc.b; also /man/1/mc to /man/1/calc; /dis/mc.dis to /dis/calc.dis - add /appl/cmd/mc.b (initial version) - replace /dis/lc.dis by /dis/lc; remove /appl/cmd/lc.b - remove /appl/cmd/mathcalc.b /dis/mathcalc.dis /man/1/mathcalc -20070510 - quickly remove references to udp's "oldheaders" because plan 9 removed it - remove obootpd completely -20070418 - add scan code to X11 (issue 45) -20070411 - if mkconfig has been changed from the distribution, use it to set parameters in makemk.sh (issue 41) - add iso8859-15 (what? will the line stretch on to the crack of doom?) (issue 43) -20070410 - fix some porting errors in /appl/cmd/look.b - document look's -r option in look(1) -20070407 - /os/port/^(portdat.h lib.h portfns.h xalloc.c) compatiblity changes with plan 9 - /os/pc ether drivers updated to match plan 9, and os/ip (and a few files in /os/port) also updated, including removing some unreachable code - /os/ip/tcp.c changes from plan 9 for out-of-sequence segments -20070319 - emu/port/devsrv.c and os/port/devsrv.c delete wc at correct time -20070312 - rename -D and -k options to plumb (old ones still accepted); add -i option to take data from standard input; update man page - enable 64-bit seeks in /emu/Nt/devfs.c -20070302 - change /mkfile to build yacc earlier, mainly to make bootstrap of a new host easier (makemk.sh and mk install) - change /utils/mkfile not to build k[acl] and q[acl] on Plan 9, since the system ones are the same -20070228 - make array bounds checking the default for on-the-fly compilers (emu/port/main.c) - improve wording in security-ssl(2) and ssl(3) -20070227 - /include/fcall.h: ensure unsigned promotion to counter ansi sign-extending rules for GBIT64 - /libmemdraw/draw.c: copy fix to memfillcolor -20070220 - add 0x92 as chip ID for ether91c111.c -20070217 - repair /appl/lib/libc.b and /appl/lib/libc0.b strncmp implementations (used only by c2l output) [inferno-os issue 9] - /emu/port/devip.c, get socket fd on reopen of ctl - /appl/acme/exec.b, trim string correctly [inferno-os issue 11] -20070216 - add /module/lists.m, /appl/lib/lists.b, and lists(2) -20070209 - remove debugging -d option to exportfs call in emu/Plan9/devsrv9.c(!) -20070206 - /appl/svc/auth.sh: replace exit by raise - /man/2/styxservers: document replychan and replydirect -20070201 - update US timezone files to save energy -20070131 - add /appl/lib/convcs/utf16_btos.b, utf16_stob.b etc [rog] -20070130 - fix wording in some of the licence files (eg, remove references to old liberal licence) -20070123 - check lengths properly in devenv.c - move all of doc into lib/proto/inferno from lib/proto/src -20070122 - add doc/port.ms, doc/port.pdf to src proto. add brief instructions for source rebuild to port.ms -20070118 - add json(2) {/appl/lib/json.b, /module/json.m, /dis/lib/json.dis} for RFC4627 notation [json(6)] -20070117 - remove duplicate libmp/libsec reference from /mkfile (i assume it wasn't necessary to visit them twice!) -20070116 - move Man from /dis/man.dis (which vanished a few changes ago) to /dis/lib/man.dis. honestly. wm/man works again. -20070114 - remove some unused static declarations in /utils/mk/shprint.c -20070111 - delete drawxflush from devdraw.c (call drawq(un)?lock instead) -20070107 - have emu (/emu/port/main.c) check environment variables INFERNO and ROOT before EMU and -r, for inferno root directory - (haven't yet changed the build system and mkfiles to match) - remove /include/libcrypt_o.h since the library isn't used - add complete(2) -20070103 - replace man.dis by Salva Peiró's sh version of plan 9's man script -20061221 - add data2c to Irix package prototype - remove unwanted .dis/.sbl files from /appl packages - change liblogfs to GPLv2 from proprietary, to fit google code - correct cmd(3) to account for new stderr file -20061219 - cmd(3) and thus os(1) change to separate standard output and error streams - all /emu/*/cmd.c change to account for that (original changes to devcmd.c and MacOSX/cmd.c courtesy Cibernet) -20061215 - replaced things like <???> because gcc annoyingly whines even with 1950's trigraphs off - libtk/textu.c: uninitialised field in boundary case - libtk/textw.c: possibly uninitialised value; leave unchanged - utils/ql/l.h: uchar as to ushort, because of extra ops -20061214 - added fopen to xml.m to allow bufio->sopen and others to be used -20061213 - added MacOSX/386 components -20061013 - updated /os/ip/lookbackmedium.c and /os/ip/rudp.c -20061021 - change /os/port/exportfs.c to allow negotiating up to 64k msize - (matching /emu/port/exportfs.c) -20060809 - /appl/lib/newns.b uses String->unquoted, if it can load it -20060803 - /libtk/textw.c: default page up/down scrolls 0.75 of a page (to give context); also allows fractional value -20060801 - /utils/data2s/data2s.c: allocate at least one linker byte to empty files to avoid complaints -20060715 - /appl/lib/pop3.b remove defaultserver(); update pop3(2) to remove references to /services - similarly update smtp(2) - avoid some boundary cases in /appl/charon/^(build.b layout.b) -20060625 - added caerwynj@gmail.com changes to /appl/acme/acme/mail/src/Mailpop3.b -20060622 - /appl/lib/sets*.b: correct op's implementation of 2r1101 -20060613 - added csv(2), /module/csv.m, /appl/lib/csv.b -20060608 - preliminary rfc822(2), /appl/lib/rfc822.b -20060605 - /appl/lib/chanfill.b: remove alt => * -20060601 - fix /appl/lib/dis.b to save the real array once read in -20060526 - /appl/lib/venti.b: fix g64's byte ordering [not that it is, or can be called yet] -20060524 - copy end fix to lib*/utfecpy.c -20060523 - w3c-uris(2): add a .copy() operation -20060518 - /Nt/386/include/lib9.h define _USE_32BIT_TIME_T and deprecate `deprecated' warnings -20060504 - remove use of HEAP_ALIGN from /*/port/devprof.c; change Heap.pad to Heap.hprof in /include/interp.h -20060426 - correct text and selection colours in wm/sh for loss-of-focus and holding modes -20060423 - add /appl/lib/w3c/uris.b w3c-uris(2) /module/uris.m -20060419 - /emu/port/devcmd.c: correct wakeup state for started command -20060412 - /appl/svc/webget include caerwyn's changes -20060411 - put `|| exit 1' after each (command-list) in the mkfiles, just for bash -20060410 - /appl/cmd/limbo/typecheck.b /limbo/typecheck.c - stop wrong warning wrt use of ref fn -20060313 - remembered to install cddb port from last year... cddb(7) -20060312 - /emu/Nt/win.c; #define windows names out of the way to remove IPoint etc - /emu/Nt/os.c, simplify osblock/osready and eliminate erendezvous - /emu/port/devcons.c, tug into line with /os/port, to prepare for single-window changes - echo ^U on CAN (ctrl-U) -20060311 - replace Limbo version of shutdown by sh script; it's still a bit silly -20060309 - /*/port/inferno.c: 0 or -1 return value from dial functions - /os/port/portmkfile: remove reference to ../kfs - /man/8/httpd document -a; /appl/svc/httpd/httpd.b - /libmp/port/mptouv.c sign extension fix from 9 - /module/keyring.m, /libinterp/ipint.c: add some bitwise operators - change (undocumented) /appl/cmd/test.b so that `host' mkfiles will work in Inferno - should probably change the mkfiles to replace it -20060303 - /emu/Plan9/win.c replace ldepthof -20060302 - add KPX11 flag to hosted kproc to boost the stack for silly x11 & co. - put keyboard and cursor processing into a separate kproc with big stack in /emu/port/win-x11a.c - change various os.c to match -20060301 - /appl/cmd/rioimport.b fix initialisation race -20060227 - fix /utils/ql/l.h: oprange should be [ALAST] (with extra 405xx opcodes), also AEND->ALIST elsewhere - put faster gethunk in ql and kl (mimic other compilers) -20060226 - enable /emu/port/devpointer.c, with changes to /emu/*/win*.c to call mousetrack, /emu/port/main.c to bind #m, - and code for pointer and cursor removed from devcons.c - update Nt/win.c and port/win-x11a.c from drawterm to get/put host snarf buffer - change devmem.c from #m to #% not to clash with pointer -20060225 - add /emu/port/devsnarf.c (#^) and put clipread from drawterm in /emu/Nt/win.c -20060224 - modify /appl/lib/secstore.b, /module/secstore.m, secstore(2) [add dial, auth, mkseckey, mkfilekey, remove] - add /appl/cmd/auth/secstore.b, secstore(1) - remove strange exception handling in /appl/cmd/dd.b - add dhcpclient(2) -20060223 - add /appl/cmd/auth/aescbc.c - add /appl/cmd/crypt.b [rog] - add crypt(1) - add /appl/lib/secstore.b /module/secstore.m secstore(2) -20060221 - /libsec/port/hmac.c: treat existing but not seeded digest correctly - /libinterp/ipint.c, /module/keyring.m, add new operator `invert' -20060220 - add ida(2), /appl/lib/ida, /module/ida.m -20060216 - add ubfa(2), ubfa(6), /module/ubfa.m, /appl/lib/ubfa.b -20060214 - [rog] add cursor changing support to tk, wm, wmlib (eg, for acme) -20060213 - remove libcrypt_o from distribution -20060211 - add /man/1/9win [rog] - change /appl/cmd/auth/keyfs.b to confirm key only when creating the file [rog] - punt floating-point conversions in powerpc jit on macos for time being - (have particular values in certain FP registers when native) -20060210 - update /libmemdraw/draw.c to include 9's changes for concurrent use - remove canlock as assembly language interface, replaced by _tas - replace native use of tas by _tas; make declarations all agree - add holdon/holdoff ctl request to wm/sh - wmproxy in appl/lib/wmlib.b does not create new pgrp -20060206 - update /appl/cmd/cp.b with digbyt's changes (mode/uid/gid correct on copied directories) -20060203 - update /appl/cmd/ip/dhcp.b /appl/cmd/lib/dhcpclient.b - update /os/init/i4e.b to use it - add /man/8/dhcp -20060118 - add ksize(10.1), kstrip(10.1), /utils/kstrip - new _MAGIC definitions in utils/libmach/a.out.h -20060114 - change /os/boot/arm1110 mkfile to work on unix and windows; add to /lib/proto/os -20060111 - -s (exportonly) -x/-y (geometry) options to 9win (TODO: rog, manual page!) - wm/sh.b: correct hold mode; remove little-used and undocumented history file -20060109 - delete #pragma from flate.h - ensure lib9 compiles replacement sbrk for MacOSX -20060106 - update compilers - update compilers' manual page - fix os/port/portmkfile for Plan 9: don't use $OBJDIR but Inferno/$OBJTYPE - have os/port/portmkfile check for i$CONF.p9 and use that not i$CONF for acid - add srclist(10.1) -20060105 - account for new definition of rendezvous (void* not ulong) - add dummy setmalloctag to utils where needed (for Plan 9) - set profileflg only for ATEXT in utils/?c/txt.c - update /os/boot/pc -20060103 - /os/ip updated from Plan 9 - /os/ip/^(bootp.c dhcp.c ihbootp.c) changed to use announce not connect for udp -20051215 - /man/6/keytext added -20051207 - /tools/odbc.c portability changes, and fix modes on several files -20051202 - /emu/Plan9/devfs.c strip Inferno root from file system diagnostics -20051130 - change /appl/svc/httpd to use lock(2) not lockprocs -20051123 - /appl/cmd/bind.b changed not to use arg.dis, implement -q, and diagnostic change - /appl/cmd/mount.b acquired a -q option as well -20051114 - avoid limit==0 in wm/memory.b -20051108 - have poolmaxsize return 0 for pool of size 0 - remove /os/*/u.h (in favour of /$SYSTARG/$OBJTYPE/include/u.h) - update mkfiles accordingly - adjust mkfiles for libsec and libmp compilation for native kernels -20051107 - added /os/manga -20051101 - fixed /os/port/devloopback.c - updated netif.c netif.h -20051028 - updated gettar(1) and /appl/cmd/gettar.b -20051025 - fix British Summer Time in locales -20051021 - updated /appl/lib/newns.b and namespace(6) for environment variable substitution -20051018 - moved in changes from home to os/port: cis.c devbridge.c ethermii.c portclock.c devuart.c devbench.c random.c portfns.h tod.c uart.h - - mainly for changes to implement fasttick and timers -20051017 - /limbo/ecom.c and /appl/cmd/limbo/ecom.c: ensure src set in temporary Node to avoid `no file specified' in sbl.[bc] -20050925 - added format(2) -20050922 - iostats(4) added -20050919 - improve behaviour in wm/sh when in raw mode -20050916 - /appl/lib/styx.b: return value for Rmsg.unpack for Rstat didn't include len[2] -20050912 - update /appl/lib/disks.b, disks(2) - update /appl/cmd/disk/format.b - add /appl/cmd/disk/prep, /appl/cmd/disk/mbr.b - replace format(8) by prep(8) - delete undocumented /appl/cmd/disk/part.b -20050908 - added disks(2) and scsiio(2) -20050906 - os/port/devsrv.c and emu/port/devsrv.c to allow setting length by wstat (also DMAPPEND) - appl/cmd/dossrv.b fix to interpret aname:offset - usb updated to support current native uhci drivers - /appl/lib/usb/usbmass.b changed to work with new driver and more devices -20050901 - new /appl/cmd/ip/sntp.b, sntp(8) -20050824 - cp(1): added -gux options -20050810 - mangaload(8): new -20050812 - /appl/cmd/limbo/nodes.b didn't always initialise n.c (eg, a != a) -20050712 - updated utils/[12][acl] to match Plan 9's -20050627 - added streamcp (renamed fcp since that's what plan 9 calls a similar thing) -20050626 - added write lock to emu/port/devip.c to stop Linux (and perhaps others) splitting socket writes by different processes -20050620 - added w3c-xpointers(2) [/module/xpointers.m; /appl/lib/w3c/xpointers.b] -20050617 - fixed qid array reference in /appl/cmd/lockfs.b [cjones83] -20050610 - updated lib/ndb/dns - fixed count < 0 when reading beyond end of file in disk/kfs -20050526 - fixed factotum's p9any to use user= attribute in key not /dev/user - fix /appl/lib/daytime.b's handling of dlpairs; also read /env/timezone if that's there - update /appl/lib/w3c/css.b to read CSS2.1 - add w3c-css(2); possibly should move module file to w3c/css.m? -20050518 - added GPL/LGPL notice files - made single mk.b from many included source files - added MIT-template or LGPL NOTICE files to lib* directories - updated doc/port.ms - included libmp and libsec in lib/proto/src (Lucent Public License), not yet used - fix bug in cmd(3) introduced by killonclose -20050425 - add sexprs(6) - add truerand/ntruerand and nsec[defined as osnsec] to lib9.h - redefine fmax and log2 in lib9.h - some/all FreeBSD-5.x-y don't initialise rfork_thread's procmask from parent (contrary to docs); compensate in FreeBSD/os.c - finally copy last year's changes to 1c from home - call logs->init in applylog - changed /appl/cmd/cmp.b to work correctly for differing buffer sizes, errors, etc. - included /os/pc/sd53c8xx.[in] and added /utils/na [not compiled by default] - mask off OEXCL in (emu/port os/port)^/sysfile.c:/^kcreate's openmode - wm/sh.b: keep menuitem 0 if noscroll selected - added units(1) -20050413 - licence following MIT-template replaces `free for all' instances - "-N nice" option in os(1) - geodesy(2) is new - ebook(1) is newly released (Open Ebook browser) - wm-sh(1) has a rearranged menu, with scroll/noscroll option added - /doc/asm.ms has been updated - section 10 has been updated - limbo compiler will make simple functions inline if possible - limbo compiler supports `ref fn' type - /doc/limbo/addendum.ms [also .ps .pdf] updated to reflect `ref fn' and other changes - keyring-ipint(2) has a few new operations (shl, shr, copy) - DigestState has new copy operation replacing cloneDigestState - Keyring has new functions certtoattr, pktoattr and sktoattr each returning - a string containing attr=value ... representations of certificates and keys - u.h has been updated for all platforms, hosted and native - new ptrint, u8int, u16int, u64int, FPdbleword, and more accurate varargs for < 4 byte values - lib9.h has extra encode/decode functions moved from libcrypt - string.m has new quotec function [TODO: man page] - crypt/ssl3.b handles a particular certificate type better - charon has several bug fixes in javascript, notably parsing of certain expressions - /doc/descent/* `Descent into Limbo' updated - internally libinterp uses a different representation for parts of the linkage table - /doc/lprof.ms [also .ps and .pdf] gives overview of Limbo profiling - /doc/ebookimp.ms [also .ps and .pdf] discusses implementation of its XML browsing - /doc/compiler.ms has been updated - /doc/dis.ms eclr has been removed - emu(1) -b enables bounds checking in JIT - cs(8) handles general query (!attr=val ...) - mkfs/mkext(8) handles big archives - emuinit tries sh -c on command if not immediately dis - /appl/lib/string.b: rewritten unquoted for correct handling of embedded quotes - limbo warns about unused local variables - limbo: -F enables new implementation of function ref - limbo: -O runs optimiser - mount -9 uses 9fs not styx as service address - cmd(3) adds "killonclose" and parameter to "nice" - TODO: group check in styxserver - styxlisten accumulates algs correctly - os/port/mkdevc builds vgacursor table - touch uses OEXCL - /appl/lib/debug knows about ref fn - ecmascript: for(... in ...) parsed correctly - getuserpasswd added to factotum(2) - /appl/lib/print reincorporated - wm/clock - ftpfs calls factotum (getuserpasswd) - hoststdin/hoststdout/hoststderr [preliminary] - /os/boot/pc updated, as is its shipping list -20041217 - base point + remove obsolete references to sh-exception(
\ No newline at end of file diff --git a/emu/port/devsrv.c b/emu/port/devsrv.c index f655bf96..d98eb8e3 100644 --- a/emu/port/devsrv.c +++ b/emu/port/devsrv.c @@ -6,22 +6,39 @@ #include "runt.h" typedef struct SrvFile SrvFile; +typedef struct Pending Pending; + +/* request pending to a server, in case a server vanishes */ +struct Pending +{ + Pending* next; + Pending* prev; + int fid; + Channel* rc; + Channel* wc; +}; + struct SrvFile { - char* spec; char* name; char* user; ulong perm; - vlong length; Qid qid; int ref; + + /* root directory */ + char* spec; + SrvFile* devlist; + SrvFile* entry; + + /* file */ int opens; int flags; + vlong length; Channel* read; Channel* write; - SrvFile* entry; - SrvFile* dir; - SrvFile* devlist; + SrvFile* dir; /* parent directory */ + Pending waitlist; /* pending requests from client opens */ }; enum @@ -47,6 +64,7 @@ static SrvDev dev; void freechan(Heap*, int); static void freerdchan(Heap*, int); static void freewrchan(Heap*, int); +static void delwaiting(Pending*); Type *Trdchan; Type *Twrchan; @@ -98,7 +116,7 @@ srvinit(void) } static int -srvchkattach(SrvFile *d) +srvcanattach(SrvFile *d) { if(strcmp(d->user, up->env->user) == 0) return 1; @@ -119,47 +137,47 @@ srvattach(char *spec) Chan *c; SrvFile *d; + qlock(&dev.l); + if(waserror()){ + qunlock(&dev.l); + nexterror(); + } + if(spec[0] != '\0'){ - qlock(&dev.l); for(d = dev.devices; d != nil; d = d->devlist){ if(strcmp(spec, d->spec) == 0){ - if(srvchkattach(d) == 0){ - qunlock(&dev.l); + if(!srvcanattach(d)) error(Eperm); - } + c = devattach('s', spec); + c->aux = d; + c->qid = d->qid; d->ref++; - break; + poperror(); + qunlock(&dev.l); + return c; } } - qunlock(&dev.l); - - if(d != nil){ - c = devattach('s', spec); - c->aux = d; - c->qid = d->qid; - return c; - } } d = malloc(sizeof(SrvFile)); if(d == nil) error(Enomem); - c = devattach('s', spec); - d->ref = 1; kstrdup(&d->spec, spec); kstrdup(&d->user, up->env->user); snprint(up->genbuf, sizeof(up->genbuf), "srv%ld", up->env->pgrp->pgrpid); kstrdup(&d->name, up->genbuf); d->perm = DMDIR|0770; - - qlock(&dev.l); mkqid(&d->qid, dev.pathgen++, 0, QTDIR); + d->devlist = dev.devices; dev.devices = d; + + poperror(); qunlock(&dev.l); + c = devattach('s', spec); c->aux = d; c->qid = d->qid; @@ -194,6 +212,7 @@ srvwalk(Chan *c, Chan *nc, char **name, int nname) w->clone->aux = d; d->ref++; } + poperror(); qunlock(&dev.l); return w; @@ -294,23 +313,23 @@ srvwstat(Chan *c, uchar *dp, int n) } static void -srvputdir(SrvFile *sf) +srvputdir(SrvFile *dir) { SrvFile **l, *d; - sf->ref--; - if(sf->ref != 0) + dir->ref--; + if(dir->ref != 0) return; for(l = &dev.devices; (d = *l) != nil; l = &d->devlist) - if(d == sf){ + if(d == dir){ *l = d->devlist; break; } - free(sf->spec); - free(sf->user); - free(sf->name); - free(sf); + free(dir->spec); + free(dir->user); + free(dir->name); + free(dir); } static void @@ -347,30 +366,59 @@ srvunblock(SrvFile *sf, int fid) } static void -srvdecr(SrvFile *sf, int remove) +srvcancelreqs(SrvFile *sf) +{ + Pending *w, *ws; + Sys_Rread rreply; + Sys_Rwrite wreply; + + acquire(); + ws = &sf->waitlist; + while((w = ws->next) != ws){ + delwaiting(w); + if(waserror() == 0){ + if(w->rc != nil){ + rreply.t0 = H; + rreply.t1 = c2string(Ehungup, strlen(Ehungup)); + csend(w->rc, &rreply); + } + if(w->wc != nil){ + wreply.t0 = 0; + wreply.t1 = c2string(Ehungup, strlen(Ehungup)); + csend(w->wc, &wreply); + } + poperror(); + } + } + release(); +} + +static void +srvdelete(SrvFile *sf) { SrvFile *f, **l; - if(remove){ - l = &sf->dir->entry; - for(f = *l; f != nil; f = f->entry){ + if((sf->flags & SREMOVED) == 0){ + for(l = &sf->dir->entry; (f = *l) != nil; l = &f->entry){ if(sf == f){ *l = f->entry; break; } - l = &f->entry; } sf->ref--; sf->flags |= SREMOVED; } +} +static void +srvchkref(SrvFile *sf) +{ if(sf->ref != 0) return; if(sf->dir != nil) srvputdir(sf->dir); - free(sf->spec); free(sf->user); free(sf->name); free(sf); @@ -382,7 +430,10 @@ srvfree(SrvFile *sf, int flag) sf->flags |= flag; if((sf->flags & (SRDCLOSE | SWRCLOSE)) == (SRDCLOSE | SWRCLOSE)){ sf->ref--; - srvdecr(sf, (sf->flags & SREMOVED) == 0); + srvdelete(sf); + /* no further requests can arrive; return error to pending requests */ + srvcancelreqs(sf); + srvchkref(sf); } } @@ -398,6 +449,7 @@ freerdchan(Heap *h, int swept) srvfree(sf, SRDCLOSE); qunlock(&dev.l); acquire(); + freechan(h, swept); } @@ -413,6 +465,7 @@ freewrchan(Heap *h, int swept) srvfree(sf, SWRCLOSE); qunlock(&dev.l); acquire(); + freechan(h, swept); } @@ -431,17 +484,16 @@ srvclunk(Chan *c, int remove) error(Eperm); return; } - opens = 0; if(c->flag & COPEN){ opens = sf->opens--; - if (sf->read != H || sf->write != H) + if(sf->read != H || sf->write != H) srvunblock(sf, c->fid); } sf->ref--; if(opens == 1){ - if((sf->flags & (SORCLOSE | SREMOVED)) == SORCLOSE) + if(sf->flags & SORCLOSE) remove = 1; } @@ -450,8 +502,9 @@ srvclunk(Chan *c, int remove) noperm = 1; remove = 0; } - - srvdecr(sf, remove); + if(remove) + srvdelete(sf); + srvchkref(sf); qunlock(&dev.l); if(noperm) @@ -470,6 +523,25 @@ srvremove(Chan *c) srvclunk(c, 1); } +static void +addwaiting(SrvFile *sp, Pending *w) +{ + Pending *sw; + + sw = &sp->waitlist; + w->next = sw; + w->prev = sw->prev; + sw->prev->next = w; + sw->prev = w; +} + +static void +delwaiting(Pending *w) +{ + w->next->prev = w->prev; + w->prev->next = w->next; +} + static long srvread(Chan *c, void *va, long count, vlong offset) { @@ -479,6 +551,7 @@ srvread(Chan *c, void *va, long count, vlong offset) SrvFile *sp; Channel *rc; Channel *rd; + Pending wait; Sys_Rread * volatile r; Sys_FileIO_read req; @@ -504,7 +577,7 @@ srvread(Chan *c, void *va, long count, vlong offset) rd = sp->read; if(rd == H) - error(Eshutdown); + error(Ehungup); rc = cnewc(dev.Rread, movtmp, 1); ptradd(D2H(rc)); @@ -520,16 +593,23 @@ srvread(Chan *c, void *va, long count, vlong offset) req.t3 = rc; csend(rd, &req); + wait.fid = c->fid; + wait.rc = rc; + wait.wc = nil; + addwaiting(sp, &wait); + h = heap(dev.Rread); r = H2D(Sys_Rread *, h); ptradd(h); if(waserror()){ ptrdel(h); destroy(r); + delwaiting(&wait); nexterror(); } crecv(rc, r); + delwaiting(&wait); if(r->t1 != H) error(string2c(r->t1)); @@ -564,6 +644,7 @@ srvwrite(Chan *c, void *va, long count, vlong offset) SrvFile *sp; Channel *wc; Channel *wr; + Pending wait; Sys_Rwrite * volatile w; Sys_FileIO_write req; @@ -579,7 +660,7 @@ srvwrite(Chan *c, void *va, long count, vlong offset) sp = c->aux; wr = sp->write; if(wr == H) - error(Eshutdown); + error(Ehungup); wc = cnewc(dev.Rwrite, movtmp, 1); ptradd(D2H(wc)); @@ -595,6 +676,7 @@ srvwrite(Chan *c, void *va, long count, vlong offset) req.t3 = wc; ptradd(D2H(req.t1)); + if(waserror()){ ptrdel(D2H(req.t1)); destroy(req.t1); @@ -610,12 +692,20 @@ srvwrite(Chan *c, void *va, long count, vlong offset) h = heap(dev.Rwrite); w = H2D(Sys_Rwrite *, h); ptradd(h); + + wait.fid = c->fid; + wait.rc = nil; + wait.wc = wc; + addwaiting(sp, &wait); + if(waserror()){ + delwaiting(&wait); ptrdel(h); destroy(w); nexterror(); } crecv(wc, w); + delwaiting(&wait); if(w->t1 != H) error(string2c(w->t1)); poperror(); @@ -640,7 +730,7 @@ srvretype(Channel *c, SrvFile *f, Type *t) Heap *h; h = D2H(c); - h->t->ref--; + freetype(h->t); h->t = t; t->ref++; c->aux = f; @@ -668,23 +758,26 @@ srvf2c(char *dir, char *file, Sys_FileIO *io) s = c.c->aux; qlock(&dev.l); + if(waserror()){ + qunlock(&dev.l); + nexterror(); + } for(f = s->entry; f != nil; f = f->entry){ - if(strcmp(f->name, file) == 0){ - qunlock(&dev.l); + if(strcmp(f->name, file) == 0) error(Eexist); - } } f = malloc(sizeof(SrvFile)); - if(f == nil){ - qunlock(&dev.l); + if(f == nil) error(Enomem); - } srvretype(io->read, f, Trdchan); srvretype(io->write, f, Twrchan); f->read = io->read; f->write = io->write; + + f->waitlist.next = &f->waitlist; + f->waitlist.prev = &f->waitlist; kstrdup(&f->name, file); kstrdup(&f->user, up->env->user); @@ -697,6 +790,7 @@ srvf2c(char *dir, char *file, Sys_FileIO *io) s->entry = f; s->ref++; f->dir = s; + poperror(); qunlock(&dev.l); cclose(c.c); @@ -84,5 +84,3 @@ is conventionally bound by various applications .IR plumb (1), .IR wm (1), .IR sys-file2chan (2) -.SH BUGS -A client with a read or write pending can remain blocked if the server exits before reply. diff --git a/os/port/devsrv.c b/os/port/devsrv.c index 724e007e..707c690d 100644 --- a/os/port/devsrv.c +++ b/os/port/devsrv.c @@ -9,22 +9,39 @@ #include "runt.h" typedef struct SrvFile SrvFile; +typedef struct Pending Pending; + +/* request pending to a server, in case a server vanishes */ +struct Pending +{ + Pending* next; + Pending* prev; + int fid; + Channel* rc; + Channel* wc; +}; + struct SrvFile { - char* spec; char* name; char* user; ulong perm; - vlong length; Qid qid; int ref; + + /* root directory */ + char* spec; + SrvFile* devlist; + SrvFile* entry; + + /* file */ int opens; int flags; + vlong length; Channel* read; Channel* write; - SrvFile* entry; - SrvFile* dir; - SrvFile* devlist; + SrvFile* dir; /* parent directory */ + Pending waitlist; /* pending requests from client opens */ }; enum @@ -50,15 +67,20 @@ static SrvDev dev; void freechan(Heap*, int); static void freerdchan(Heap*, int); static void freewrchan(Heap*, int); +static void delwaiting(Pending*); Type *Trdchan; Type *Twrchan; static int -srvgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp) +srvgen(Chan *c, char *name, Dirtab *tab, int ntab, int s, Dir *dp) { SrvFile *f; + USED(name); + USED(tab); + USED(ntab); + if(s == DEVDOTDOT){ devdir(c, c->qid, "#s", 0, eve, 0555, dp); return 1; @@ -97,7 +119,7 @@ srvinit(void) } static int -srvchkattach(SrvFile *d) +srvcanattach(SrvFile *d) { if(strcmp(d->user, up->env->user) == 0) return 1; @@ -118,47 +140,47 @@ srvattach(char *spec) Chan *c; SrvFile *d; + qlock(&dev.l); + if(waserror()){ + qunlock(&dev.l); + nexterror(); + } + if(spec[0] != '\0'){ - qlock(&dev.l); for(d = dev.devices; d != nil; d = d->devlist){ if(strcmp(spec, d->spec) == 0){ - if(srvchkattach(d) == 0){ - qunlock(&dev.l); + if(!srvcanattach(d)) error(Eperm); - } + c = devattach('s', spec); + c->aux = d; + c->qid = d->qid; d->ref++; - break; + poperror(); + qunlock(&dev.l); + return c; } } - qunlock(&dev.l); - - if(d != nil){ - c = devattach('s', spec); - c->aux = d; - c->qid = d->qid; - return c; - } } d = malloc(sizeof(SrvFile)); if(d == nil) error(Enomem); - c = devattach('s', spec); - d->ref = 1; kstrdup(&d->spec, spec); kstrdup(&d->user, up->env->user); snprint(up->genbuf, sizeof(up->genbuf), "srv%ld", up->env->pgrp->pgrpid); kstrdup(&d->name, up->genbuf); d->perm = DMDIR|0770; - - qlock(&dev.l); mkqid(&d->qid, dev.pathgen++, 0, QTDIR); + d->devlist = dev.devices; dev.devices = d; + + poperror(); qunlock(&dev.l); + c = devattach('s', spec); c->aux = d; c->qid = d->qid; @@ -193,6 +215,7 @@ srvwalk(Chan *c, Chan *nc, char **name, int nname) w->clone->aux = d; d->ref++; } + poperror(); qunlock(&dev.l); return w; @@ -293,23 +316,23 @@ srvwstat(Chan *c, uchar *dp, int n) } static void -srvputdir(SrvFile *sf) +srvputdir(SrvFile *dir) { SrvFile **l, *d; - sf->ref--; - if(sf->ref != 0) + dir->ref--; + if(dir->ref != 0) return; for(l = &dev.devices; (d = *l) != nil; l = &d->devlist) - if(d == sf){ + if(d == dir){ *l = d->devlist; break; } - free(sf->spec); - free(sf->user); - free(sf->name); - free(sf); + free(dir->spec); + free(dir->user); + free(dir->name); + free(dir); } static void @@ -346,30 +369,59 @@ srvunblock(SrvFile *sf, int fid) } static void -srvdecr(SrvFile *sf, int remove) +srvcancelreqs(SrvFile *sf) +{ + Pending *w, *ws; + Sys_Rread rreply; + Sys_Rwrite wreply; + + acquire(); + ws = &sf->waitlist; + while((w = ws->next) != ws){ + delwaiting(w); + if(waserror() == 0){ + if(w->rc != nil){ + rreply.t0 = H; + rreply.t1 = c2string(Ehungup, strlen(Ehungup)); + csend(w->rc, &rreply); + } + if(w->wc != nil){ + wreply.t0 = 0; + wreply.t1 = c2string(Ehungup, strlen(Ehungup)); + csend(w->wc, &wreply); + } + poperror(); + } + } + release(); +} + +static void +srvdelete(SrvFile *sf) { SrvFile *f, **l; - if(remove){ - l = &sf->dir->entry; - for(f = *l; f != nil; f = f->entry){ + if((sf->flags & SREMOVED) == 0){ + for(l = &sf->dir->entry; (f = *l) != nil; l = &f->entry){ if(sf == f){ *l = f->entry; break; } - l = &f->entry; } sf->ref--; sf->flags |= SREMOVED; } +} +static void +srvchkref(SrvFile *sf) +{ if(sf->ref != 0) return; if(sf->dir != nil) srvputdir(sf->dir); - free(sf->spec); free(sf->user); free(sf->name); free(sf); @@ -381,7 +433,10 @@ srvfree(SrvFile *sf, int flag) sf->flags |= flag; if((sf->flags & (SRDCLOSE | SWRCLOSE)) == (SRDCLOSE | SWRCLOSE)){ sf->ref--; - srvdecr(sf, (sf->flags & SREMOVED) == 0); + srvdelete(sf); + /* no further requests can arrive; return error to pending requests */ + srvcancelreqs(sf); + srvchkref(sf); } } @@ -397,6 +452,7 @@ freerdchan(Heap *h, int swept) srvfree(sf, SRDCLOSE); qunlock(&dev.l); acquire(); + freechan(h, swept); } @@ -412,6 +468,7 @@ freewrchan(Heap *h, int swept) srvfree(sf, SWRCLOSE); qunlock(&dev.l); acquire(); + freechan(h, swept); } @@ -430,17 +487,16 @@ srvclunk(Chan *c, int remove) error(Eperm); return; } - opens = 0; if(c->flag & COPEN){ opens = sf->opens--; - if (sf->read != H || sf->write != H) + if(sf->read != H || sf->write != H) srvunblock(sf, c->fid); } sf->ref--; if(opens == 1){ - if((sf->flags & (SORCLOSE | SREMOVED)) == SORCLOSE) + if(sf->flags & SORCLOSE) remove = 1; } @@ -449,8 +505,9 @@ srvclunk(Chan *c, int remove) noperm = 1; remove = 0; } - - srvdecr(sf, remove); + if(remove) + srvdelete(sf); + srvchkref(sf); qunlock(&dev.l); if(noperm) @@ -469,6 +526,25 @@ srvremove(Chan *c) srvclunk(c, 1); } +static void +addwaiting(SrvFile *sp, Pending *w) +{ + Pending *sw; + + sw = &sp->waitlist; + w->next = sw; + w->prev = sw->prev; + sw->prev->next = w; + sw->prev = w; +} + +static void +delwaiting(Pending *w) +{ + w->next->prev = w->prev; + w->prev->next = w->next; +} + static long srvread(Chan *c, void *va, long count, vlong offset) { @@ -478,6 +554,7 @@ srvread(Chan *c, void *va, long count, vlong offset) SrvFile *sp; Channel *rc; Channel *rd; + Pending wait; Sys_Rread * volatile r; Sys_FileIO_read req; @@ -503,7 +580,7 @@ srvread(Chan *c, void *va, long count, vlong offset) rd = sp->read; if(rd == H) - error(Eshutdown); + error(Ehungup); rc = cnewc(dev.Rread, movtmp, 1); ptradd(D2H(rc)); @@ -519,16 +596,23 @@ srvread(Chan *c, void *va, long count, vlong offset) req.t3 = rc; csend(rd, &req); + wait.fid = c->fid; + wait.rc = rc; + wait.wc = nil; + addwaiting(sp, &wait); + h = heap(dev.Rread); r = H2D(Sys_Rread *, h); ptradd(h); if(waserror()){ ptrdel(h); destroy(r); + delwaiting(&wait); nexterror(); } crecv(rc, r); + delwaiting(&wait); if(r->t1 != H) error(string2c(r->t1)); @@ -563,6 +647,7 @@ srvwrite(Chan *c, void *va, long count, vlong offset) SrvFile *sp; Channel *wc; Channel *wr; + Pending wait; Sys_Rwrite * volatile w; Sys_FileIO_write req; @@ -578,7 +663,7 @@ srvwrite(Chan *c, void *va, long count, vlong offset) sp = c->aux; wr = sp->write; if(wr == H) - error(Eshutdown); + error(Ehungup); wc = cnewc(dev.Rwrite, movtmp, 1); ptradd(D2H(wc)); @@ -594,6 +679,7 @@ srvwrite(Chan *c, void *va, long count, vlong offset) req.t3 = wc; ptradd(D2H(req.t1)); + if(waserror()){ ptrdel(D2H(req.t1)); destroy(req.t1); @@ -609,12 +695,20 @@ srvwrite(Chan *c, void *va, long count, vlong offset) h = heap(dev.Rwrite); w = H2D(Sys_Rwrite *, h); ptradd(h); + + wait.fid = c->fid; + wait.rc = nil; + wait.wc = wc; + addwaiting(sp, &wait); + if(waserror()){ + delwaiting(&wait); ptrdel(h); destroy(w); nexterror(); } crecv(wc, w); + delwaiting(&wait); if(w->t1 != H) error(string2c(w->t1)); poperror(); @@ -639,7 +733,7 @@ srvretype(Channel *c, SrvFile *f, Type *t) Heap *h; h = D2H(c); - h->t->ref--; + freetype(h->t); h->t = t; t->ref++; c->aux = f; @@ -667,23 +761,26 @@ srvf2c(char *dir, char *file, Sys_FileIO *io) s = c.c->aux; qlock(&dev.l); + if(waserror()){ + qunlock(&dev.l); + nexterror(); + } for(f = s->entry; f != nil; f = f->entry){ - if(strcmp(f->name, file) == 0){ - qunlock(&dev.l); + if(strcmp(f->name, file) == 0) error(Eexist); - } } f = malloc(sizeof(SrvFile)); - if(f == nil){ - qunlock(&dev.l); + if(f == nil) error(Enomem); - } srvretype(io->read, f, Trdchan); srvretype(io->write, f, Twrchan); f->read = io->read; f->write = io->write; + + f->waitlist.next = &f->waitlist; + f->waitlist.prev = &f->waitlist; kstrdup(&f->name, file); kstrdup(&f->user, up->env->user); @@ -696,6 +793,7 @@ srvf2c(char *dir, char *file, Sys_FileIO *io) s->entry = f; s->ref++; f->dir = s; + poperror(); qunlock(&dev.l); cclose(c.c); |
