2 * 9P to FUSE translator. Acts as FUSE server, 9P client.
3 * Mounts 9P servers via FUSE kernel module.
5 * There are four procs in this threaded program
6 * (ignoring the one that runs main and then exits).
7 * The first proc reads FUSE requests from /dev/fuse.
8 * It sends the requests over a channel to a second proc,
9 * which serves the requests. Each request runs in a
10 * thread in that second proc. Those threads do write
11 * FUSE replies, which in theory might block, but in practice don't.
12 * The 9P interactions are handled by lib9pclient, which
13 * allocates two more procs, one for reading and one for
14 * writing the 9P connection. Thus the many threads in the
15 * request proc can do 9P interactions without blocking.
18 #define _GNU_SOURCE 1 /* for O_DIRECTORY on Linux */
27 # define O_LARGEFILE 0
31 * Work around glibc's broken <bits/fcntl.h> which defines
32 * O_LARGEFILE to 0 on 64 bit architectures. But, on those same
33 * architectures, linux _forces_ O_LARGEFILE (which is always
34 * 0100000 in the kernel) at each file open. FUSE is all too
35 * happy to pass the flag onto us, where we'd have no idea what
36 * to do with it if we trusted glibc.
38 #if defined(__linux__)
40 # define O_LARGEFILE 0100000
44 # if defined(__linux__)
45 # define O_CLOEXEC 02000000 /* Sigh */
54 void fusedispatch(void*);
63 * The number of seconds that the kernel can cache
64 * returned file attributes. FUSE's default is 1.0.
65 * I haven't experimented with using 0.
67 double attrtimeout = 1.0;
70 * The number of seconds that the kernel can cache
71 * the returned entry nodeids returned by lookup.
72 * I haven't experimented with other values.
74 double entrytimeout = 1.0;
78 void init9p(char*, char*);
83 fprint(2, "usage: 9pfuse [-D] [-A attrtimeout] [-a aname] address mtpt\n");
87 void fusereader(void*);
91 threadmain(int argc, char **argv)
99 attrtimeout = atof(EARGF(usage()));
102 aname = EARGF(usage());
112 fmtinstall('F', fcallfmt);
113 fmtinstall('M', dirmodefmt);
114 fmtinstall('G', fusefmt);
116 setsid(); /* won't be able to use console, but can't be interrupted */
118 init9p(argv[0], aname);
121 fusechan = chancreate(sizeof(void*), 0);
122 proccreate(fusedispatch, nil, STACK);
123 sendp(fusechan, nil); /* sync */
125 proccreate(fusereader, nil, STACK);
127 * Now that we're serving FUSE, we can wait
128 * for the mount to finish and exit back to the user.
139 while((m = readfusemsg()) != nil)
142 fusemtpt = nil; /* no need to unmount */
147 init9p(char *addr, char *spec)
151 if(strcmp(addr, "-") == 0)
154 if((fd = dial(netmkaddr(addr, "tcp", "564"), nil, nil, nil)) < 0)
155 sysfatal("dial %s: %r", addr);
156 proccreate(watchfd, (void*)(uintptr)fd, STACK);
157 if((fsys = fsmount(fd, spec)) == nil)
158 sysfatal("fsmount: %r");
159 fsysroot = fsroot(fsys);
163 * FUSE uses nodeids to refer to active "struct inodes"
164 * (9P's unopened fids). FUSE uses fhs to refer to active
165 * "struct fuse_files" (9P's opened fids). The choice of
166 * numbers is up to us except that nodeid 1 is the root directory.
167 * We use the same number space for both and call the
168 * bookkeeping structure a FuseFid.
170 * FUSE requires nodeids to have associated generation
171 * numbers. If we reuse a nodeid, we have to bump the
172 * generation number to guarantee that the nodeid,gen
173 * combination is never reused.
175 * There are also inode numbers returned in directory reads
176 * and file attributes, but these do NOT need to match the nodeids.
177 * We use a combination of qid.path and qid.type as the inode
181 * TO DO: reference count the fids.
183 typedef struct Fusefid Fusefid;
193 /* directory read state */
202 Fusefid *freefusefidlist;
209 if((f = freefusefidlist) == nil){
210 f = emalloc(sizeof *f);
211 fusefid = erealloc(fusefid, (nfusefid+1)*sizeof *fusefid);
216 freefusefidlist = f->next;
224 freefusefid(Fusefid *f)
238 f->next = freefusefidlist;
244 _alloc(CFid *fid, int isnodeid)
250 ff->isnodeid = isnodeid;
252 return ff->id+2; /* skip 0 and 1 */
258 return _alloc(fid, 0);
261 allocnodeid(CFid *fid)
263 return _alloc(fid, 1);
267 lookupfusefid(uvlong id, int isnodeid)
270 if(id < 2 || id >= nfusefid+2)
272 ff = fusefid[(int)id-2];
273 if(ff->isnodeid != isnodeid)
279 _lookupcfid(uvlong id, int isnodeid)
283 if((ff = lookupfusefid(id, isnodeid)) == nil)
291 return _lookupcfid(fh, 0);
295 nodeid2fid(uvlong nodeid)
299 return _lookupcfid(nodeid, 1);
305 return q.path | ((uvlong)q.type<<56);
309 dir2attr(Dir *d, struct fuse_attr *attr)
311 attr->ino = qid2inode(d->qid);
312 attr->size = d->length;
313 attr->blocks = (d->length+8191)/8192;
314 attr->atime = d->atime;
315 attr->mtime = d->mtime;
316 attr->ctime = d->mtime; /* not right */
320 attr->mode = d->mode&0777;
322 attr->mode |= S_IFDIR;
323 else if(d->mode&DMSYMLINK)
324 attr->mode |= S_IFLNK;
326 attr->mode |= S_IFREG;
327 attr->nlink = 1; /* works for directories! - see FUSE FAQ */
328 attr->uid = getuid();
329 attr->gid = getgid();
334 f2timeout(double f, __u64 *s, __u32 *ns)
337 *ns = (f - (int)f)*1e9;
341 dir2attrout(Dir *d, struct fuse_attr_out *out)
343 f2timeout(attrtimeout, &out->attr_valid, &out->attr_valid_nsec);
344 dir2attr(d, &out->attr);
348 * Lookup. Walk to the name given as the argument.
349 * The response is a fuse_entry_out giving full stat info.
352 fuselookup(FuseMsg *m)
358 struct fuse_entry_out out;
361 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
362 replyfuseerrno(m, ESTALE);
365 if(strchr(name, '/')){
366 replyfuseerrno(m, ENOENT);
369 if((newfid = fswalk(fid, name)) == nil){
373 if((d = fsdirfstat(newfid)) == nil){
378 out.nodeid = allocnodeid(newfid);
379 ff = lookupfusefid(out.nodeid, 1);
380 out.generation = ff->gen;
381 f2timeout(attrtimeout, &out.attr_valid, &out.attr_valid_nsec);
382 f2timeout(entrytimeout, &out.entry_valid, &out.entry_valid_nsec);
383 dir2attr(d, &out.attr);
385 replyfuse(m, &out, sizeof out);
389 * Forget. Reference-counted clunk for nodeids.
390 * Does not send a reply.
391 * Each lookup response gives the kernel an additional reference
392 * to the returned nodeid. Forget says "drop this many references
393 * to this nodeid". Our fuselookup, when presented with the same query,
394 * does not return the same results (it allocates a new nodeid for each
395 * call), but if that ever changes, fuseforget already handles the ref
399 fuseforget(FuseMsg *m)
401 struct fuse_forget_in *in;
405 if((ff = lookupfusefid(m->hdr->nodeid, 1)) == nil)
407 if(ff->ref > in->nlookup){
408 ff->ref -= in->nlookup;
411 if(ff->ref < in->nlookup)
412 fprint(2, "bad count in forget\n");
419 * Replies with a fuse_attr_out structure giving the
420 * attr for the requested nodeid in out.attr.
421 * Out.attr_valid and out.attr_valid_nsec give
422 * the amount of time that the attributes can
425 * Empirically, though, if I run ls -ld on the root
426 * twice back to back, I still get two getattrs,
427 * even with a one second attribute timeout!
430 fusegetattr(FuseMsg *m)
433 struct fuse_attr_out out;
436 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
437 replyfuseerrno(m, ESTALE);
440 if((d = fsdirfstat(fid)) == nil){
444 memset(&out, 0, sizeof out);
445 dir2attrout(d, &out);
447 replyfuse(m, &out, sizeof out);
452 * FUSE treats the many Unix attribute setting routines
453 * more or less like 9P does, with a single message.
456 fusesetattr(FuseMsg *m)
460 struct fuse_setattr_in *in;
461 struct fuse_attr_out out;
464 if(in->valid&FATTR_FH){
465 if((fid = fh2fid(in->fh)) == nil){
466 replyfuseerrno(m, ESTALE);
470 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
471 replyfuseerrno(m, ESTALE);
475 * Special case: Linux issues a size change to
476 * truncate a file before opening it OTRUNC.
477 * Synthetic file servers (e.g., plumber) honor
478 * open(OTRUNC) but not wstat.
480 if(in->valid == FATTR_SIZE && in->size == 0){
481 if((nfid = fswalk(fid, nil)) == nil){
485 if(fsfopen(nfid, OWRITE|OTRUNC) < 0){
496 if(in->valid&FATTR_SIZE)
498 if(in->valid&FATTR_ATIME)
500 if(in->valid&FATTR_MTIME)
502 if(in->valid&FATTR_MODE)
504 if((in->valid&FATTR_UID) || (in->valid&FATTR_GID)){
506 * I can't be bothered with these yet.
508 replyfuseerrno(m, EPERM);
511 if(fsdirfwstat(fid, &d) < 0){
516 if((dd = fsdirfstat(fid)) == nil){
520 memset(&out, 0, sizeof out);
521 dir2attrout(dd, &out);
523 replyfuse(m, &out, sizeof out);
527 _fuseopenfid(uvlong nodeid, int isdir, int openmode, int *err)
531 if((fid = nodeid2fid(nodeid)) == nil){
535 if(isdir && !(fsqid(fid).type&QTDIR)){
539 if(openmode != OREAD && fsqid(fid).type&QTDIR){
544 /* Clone fid to get one we can open. */
545 newfid = fswalk(fid, nil);
547 *err = errstr2errno();
551 if(fsfopen(newfid, openmode) < 0){
552 *err = errstr2errno();
562 * Argument is a struct fuse_open_in.
563 * The mode field is ignored (presumably permission bits)
564 * and flags is the open mode.
565 * Replies with a struct fuse_open_out.
568 _fuseopen(FuseMsg *m, int isdir)
570 struct fuse_open_in *in;
571 struct fuse_open_out out;
573 int openmode, flags, err;
579 flags &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC);
581 * Discarding O_APPEND here is not completely wrong,
582 * because the host kernel will rewrite the offsets
583 * of write system calls for us. That's the best we
584 * can do on Unix anyway.
592 * Could translate but not standard 9P:
593 * O_DIRECT -> ODIRECT
594 * O_NONBLOCK -> ONONBLOCK
597 fprint(2, "unexpected open flags %#uo", (uint)in->flags);
598 replyfuseerrno(m, EACCES);
601 if((fid = _fuseopenfid(m->hdr->nodeid, isdir, openmode, &err)) == nil){
602 replyfuseerrno(m, err);
605 out.fh = allocfh(fid);
606 out.open_flags = FOPEN_DIRECT_IO; /* no page cache */
607 replyfuse(m, &out, sizeof out);
617 fuseopendir(FuseMsg *m)
626 _fusecreate(uvlong nodeid, char *name, int perm, int ismkdir, int omode, struct fuse_entry_out *out, int *err)
628 CFid *fid, *newfid, *newfid2;
632 if((fid = nodeid2fid(nodeid)) == nil){
639 if(ismkdir && omode != OREAD){
643 if((newfid = fswalk(fid, nil)) == nil){
644 *err = errstr2errno();
647 if(fsfcreate(newfid, name, omode, perm) < 0){
648 *err = errstr2errno();
652 if((d = fsdirfstat(newfid)) == nil){
653 *err = errstr2errno();
658 * This fid is no good, because it's open.
659 * We need an unopened fid. Sigh.
661 if((newfid2 = fswalk(fid, name)) == nil){
662 *err = errstr2errno();
667 out->nodeid = allocnodeid(newfid2);
668 ff = lookupfusefid(out->nodeid, 1);
669 out->generation = ff->gen;
670 f2timeout(attrtimeout, &out->attr_valid, &out->attr_valid_nsec);
671 f2timeout(entrytimeout, &out->entry_valid, &out->entry_valid_nsec);
672 dir2attr(d, &out->attr);
678 fusemkdir(FuseMsg *m)
680 struct fuse_mkdir_in *in;
681 struct fuse_entry_out out;
687 name = (char*)(in+1);
688 if((fid = _fusecreate(m->hdr->nodeid, name, in->mode, 1, OREAD, &out, &err)) == nil){
689 replyfuseerrno(m, err);
692 /* Toss the open fid. */
694 replyfuse(m, &out, sizeof out);
698 fusecreate(FuseMsg *m)
700 struct fuse_open_in *in;
701 struct fuse_create_out out;
703 int err, openmode, flags;
708 openmode = in->flags&3;
710 flags &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE|O_EXCL);
711 flags &= ~O_APPEND; /* see comment in _fuseopen */
712 flags &= ~(O_CREAT|O_TRUNC); /* huh? */
714 fprint(2, "bad mode %#uo\n", in->flags);
715 replyfuseerrno(m, EACCES);
718 name = (char*)(in+1);
719 if((fid = _fusecreate(m->hdr->nodeid, name, in->mode, 0, openmode, &out.e, &err)) == nil){
720 replyfuseerrno(m, err);
723 out.o.fh = allocfh(fid);
724 out.o.open_flags = FOPEN_DIRECT_IO; /* no page cache */
725 replyfuse(m, &out, sizeof out);
730 * Lib9pclient implements this just as Plan 9 does,
731 * by opening the file (or not) and then closing it.
734 fuseaccess(FuseMsg *m)
736 struct fuse_access_in *in;
751 if(in->mask >= nelem(a2o)){
752 replyfuseerrno(m, EINVAL);
755 omode = a2o[in->mask];
756 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
757 replyfuseerrno(m, ESTALE);
760 if(fsqid(fid).type&QTDIR)
762 if((fid = _fuseopenfid(m->hdr->nodeid, 0, omode, &err)) == nil){
763 replyfuseerrno(m, err);
767 replyfuse(m, nil, 0);
772 * Equivalent of clunk for file handles.
773 * in->flags is the open mode used in Open or Opendir.
776 fuserelease(FuseMsg *m)
778 struct fuse_release_in *in;
782 if((ff = lookupfusefid(in->fh, 0)) != nil)
785 fprint(2, "fuserelease: fh not found\n");
786 replyfuse(m, nil, 0);
790 fusereleasedir(FuseMsg *m)
797 * Read from file handle in->fh at offset in->offset for size in->size.
798 * We truncate size to maxwrite just to keep the buffer reasonable.
806 struct fuse_read_in *in;
809 if((fid = fh2fid(in->fh)) == nil){
810 replyfuseerrno(m, ESTALE);
817 n = fspread(fid, buf, n, in->offset);
823 replyfuse(m, buf, n);
831 fusereadlink(FuseMsg *m)
836 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
837 replyfuseerrno(m, ESTALE);
840 if((d = fsdirfstat(fid)) == nil){
844 if(!(d->mode&DMSYMLINK)){
845 replyfuseerrno(m, EINVAL);
848 replyfuse(m, d->ext, strlen(d->ext));
855 * Read from file handle in->fh at offset in->offset for size in->size.
856 * We truncate size to maxwrite just to keep the buffer reasonable.
857 * We assume 9P directory read semantics: a read at offset 0 rewinds
858 * and a read at any other offset starts where we left off.
859 * If it became necessary, we could implement a crude seek
860 * or cache the entire list of directory entries.
861 * Directory entries read from 9P but not yet handed to FUSE
862 * are stored in m->d,nd,d0.
864 int canpack(Dir*, uvlong, uchar**, uchar*);
867 fusereaddir(FuseMsg *m)
869 struct fuse_read_in *in;
875 if((ff = lookupfusefid(in->fh, 0)) == nil){
876 replyfuseerrno(m, ESTALE);
880 fsseek(ff->fid, 0, 0);
882 ff->d0 = ff->d = dotdirs(ff->fid);
893 if(!canpack(ff->d, ff->off, &p, ep))
902 if((ff->nd = fsdirread(ff->fid, &ff->d0)) < 0){
912 replyfuse(m, buf, p - buf);
917 * Fuse assumes that it can always read two directory entries.
918 * If it gets just one, it will double it in the dirread results.
919 * Thus if a directory contains just "a", you see "a" twice.
920 * Adding . as the first directory entry works around this.
921 * We could add .. too, but it isn't necessary.
929 d = emalloc(2*sizeof *d);
933 f1 = fswalk(f, "..");
935 d[1].qid = fsqid(f1);
942 canpack(Dir *d, uvlong off, uchar **pp, uchar *ep)
945 struct fuse_dirent *de;
949 size = FUSE_NAME_OFFSET + strlen(d->name);
953 if(size+pad > ep - p)
955 de = (struct fuse_dirent*)p;
956 de->ino = qid2inode(d->qid);
958 de->namelen = strlen(d->name);
959 memmove(de->name, d->name, de->namelen);
961 memset(de->name+de->namelen, 0, pad);
968 * Write from file handle in->fh at offset in->offset for size in->size.
969 * Don't know what in->write_flags means.
971 * Apparently implementations are allowed to buffer these writes
972 * and wait until Flush is sent, but FUSE docs say flush may be
973 * called zero, one, or even more times per close. So better do the
974 * actual writing here. Also, errors that happen during Flush just
975 * show up in the close() return status, which no one checks anyway.
978 fusewrite(FuseMsg *m)
980 struct fuse_write_in *in;
981 struct fuse_write_out out;
988 if((fid = fh2fid(in->fh)) == nil){
989 replyfuseerrno(m, ESTALE);
992 if(in->size > fusemaxwrite){
993 replyfuseerrno(m, EINVAL);
996 n = fspwrite(fid, a, in->size, in->offset);
1002 replyfuse(m, &out, sizeof out);
1006 * Flush. Supposed to flush any buffered writes. Don't use this.
1008 * Flush is a total crock. It gets called on close() of a file descriptor
1009 * associated with this open file. Some open files have multiple file
1010 * descriptors and thus multiple closes of those file descriptors.
1011 * In those cases, Flush is called multiple times. Some open files
1012 * have file descriptors that are closed on process exit instead of
1013 * closed explicitly. For those files, Flush is never called.
1014 * Even more amusing, Flush gets called before close() of read-only
1015 * file descriptors too!
1017 * This is just a bad idea.
1020 fuseflush(FuseMsg *m)
1022 replyfuse(m, nil, 0);
1029 _fuseremove(FuseMsg *m, int isdir)
1035 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
1036 replyfuseerrno(m, ESTALE);
1039 if(strchr(name, '/')){
1040 replyfuseerrno(m, ENOENT);
1043 if((newfid = fswalk(fid, name)) == nil){
1047 if(isdir && !(fsqid(newfid).type&QTDIR)){
1048 replyfuseerrno(m, ENOTDIR);
1052 if(!isdir && (fsqid(newfid).type&QTDIR)){
1053 replyfuseerrno(m, EISDIR);
1057 if(fsfremove(newfid) < 0){
1061 replyfuse(m, nil, 0);
1065 fuseunlink(FuseMsg *m)
1071 fusermdir(FuseMsg *m)
1079 * FUSE sends the nodeid for the source and destination
1080 * directory and then the before and after names as strings.
1081 * 9P can only do the rename if the source and destination
1082 * are the same. If the same nodeid is used for source and
1083 * destination, we're fine, but if FUSE gives us different nodeids
1084 * that happen to correspond to the same directory, we have
1085 * no way of figuring that out. Let's hope it doesn't happen too often.
1088 fuserename(FuseMsg *m)
1090 struct fuse_rename_in *in;
1091 char *before, *after;
1096 if(in->newdir != m->hdr->nodeid){
1097 replyfuseerrno(m, EXDEV);
1100 before = (char*)(in+1);
1101 after = before + strlen(before) + 1;
1102 if((fid = nodeid2fid(m->hdr->nodeid)) == nil){
1103 replyfuseerrno(m, ESTALE);
1106 if(strchr(before, '/') || strchr(after, '/')){
1107 replyfuseerrno(m, ENOENT);
1110 if((newfid = fswalk(fid, before)) == nil){
1116 if(fsdirfwstat(newfid, &d) < 0){
1122 replyfuse(m, nil, 0);
1126 * Fsync. Commit file info to stable storage.
1127 * Not sure what in->fsync_flags are.
1130 fusefsync(FuseMsg *m)
1132 struct fuse_fsync_in *in;
1137 if((fid = fh2fid(in->fh)) == nil){
1138 replyfuseerrno(m, ESTALE);
1142 if(fsdirfwstat(fid, &d) < 0){
1146 replyfuse(m, nil, 0);
1150 * Fsyncdir. Commit dir info to stable storage?
1153 fusefsyncdir(FuseMsg *m)
1159 * Statfs. Send back information about file system.
1160 * Not really worth implementing, except that if we
1161 * reply with ENOSYS, programs like df print messages like
1162 * df: `/tmp/z': Function not implemented
1163 * and that gets annoying. Returning all zeros excludes
1164 * us from df without appearing to cause any problems.
1167 fusestatfs(FuseMsg *m)
1169 struct fuse_statfs_out out;
1171 memset(&out, 0, sizeof out);
1172 replyfuse(m, &out, sizeof out);
1175 void (*fusehandlers[100])(FuseMsg*);
1179 void (*fn)(FuseMsg*);
1181 { FUSE_LOOKUP, fuselookup },
1182 { FUSE_FORGET, fuseforget },
1183 { FUSE_GETATTR, fusegetattr },
1184 { FUSE_SETATTR, fusesetattr },
1186 * FUSE_SYMLINK, FUSE_MKNOD are unimplemented.
1188 { FUSE_READLINK, fusereadlink },
1189 { FUSE_MKDIR, fusemkdir },
1190 { FUSE_UNLINK, fuseunlink },
1191 { FUSE_RMDIR, fusermdir },
1192 { FUSE_RENAME, fuserename },
1194 * FUSE_LINK is unimplemented.
1196 { FUSE_OPEN, fuseopen },
1197 { FUSE_READ, fuseread },
1198 { FUSE_WRITE, fusewrite },
1199 { FUSE_STATFS, fusestatfs },
1200 { FUSE_RELEASE, fuserelease },
1201 { FUSE_FSYNC, fusefsync },
1203 * FUSE_SETXATTR, FUSE_GETXATTR, FUSE_LISTXATTR, and
1204 * FUSE_REMOVEXATTR are unimplemented.
1205 * FUSE will stop sending these requests after getting
1206 * an -ENOSYS reply (see dispatch below).
1208 { FUSE_FLUSH, fuseflush },
1210 * FUSE_INIT is handled in initfuse and should not be seen again.
1212 { FUSE_OPENDIR, fuseopendir },
1213 { FUSE_READDIR, fusereaddir },
1214 { FUSE_RELEASEDIR, fusereleasedir },
1215 { FUSE_FSYNCDIR, fusefsyncdir },
1216 { FUSE_ACCESS, fuseaccess },
1217 { FUSE_CREATE, fusecreate },
1226 if((uint)m->hdr->opcode >= nelem(fusehandlers)
1227 || !fusehandlers[m->hdr->opcode]){
1228 replyfuseerrno(m, ENOSYS);
1231 fusehandlers[m->hdr->opcode](m);
1235 fusedispatch(void *v)
1240 eofkill9pclient = 1; /* threadexitsall on 9P eof */
1241 atexit(unmountatexit);
1243 recvp(fusechan); /* sync */
1245 for(i=0; i<nelem(fuselist); i++){
1246 if(fuselist[i].op >= nelem(fusehandlers))
1247 sysfatal("make fusehandlers bigger op=%d", fuselist[i].op);
1248 fusehandlers[fuselist[i].op] = fuselist[i].fn;
1251 while((m = recvp(fusechan)) != nil)
1252 threadcreate(fusethread, m, STACK);
1262 sysfatal("malloc(%d): %r", n);
1268 erealloc(void *p, uint n)
1272 sysfatal("realloc(..., %d): %r", n);
1282 sysfatal("strdup(%.20s): %r", p);
1289 int fd = (int)(uintptr)v;
1291 /* wait for exception (file closed) */
1295 if(select(fd+1, NULL, NULL, &set, NULL) >= 0)
1296 threadexitsall(nil);