PageRenderTime 63ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/src/9vx/a/chan.c

https://bitbucket.org/rsc/vx32
C | 1782 lines | 1306 code | 189 blank | 287 comment | 346 complexity | c0e53a379e2edd899ec764323b13cb9d MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. #include "u.h"
  2. #include "lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "error.h"
  7. int chandebug=0; /* toggled by sysr1 */
  8. #define DBG if(chandebug)iprint
  9. enum
  10. {
  11. PATHSLOP = 20,
  12. PATHMSLOP = 20,
  13. };
  14. struct
  15. {
  16. Lock lk;
  17. int fid;
  18. Chan *free;
  19. Chan *list;
  20. }chanalloc;
  21. typedef struct Elemlist Elemlist;
  22. struct Elemlist
  23. {
  24. char *aname; /* original name */
  25. char *name; /* copy of name, so '/' can be overwritten */
  26. int nelems;
  27. char **elems;
  28. int *off;
  29. int mustbedir;
  30. int nerror;
  31. int prefix;
  32. };
  33. #define SEP(c) ((c) == 0 || (c) == '/')
  34. /*static*/ void
  35. dumpmount(void) /* DEBUGGING */
  36. {
  37. Pgrp *pg;
  38. Mount *t;
  39. Mhead **h, **he, *f;
  40. if(up == nil){
  41. print("no process for dumpmount\n");
  42. return;
  43. }
  44. pg = up->pgrp;
  45. if(pg == nil){
  46. print("no pgrp for dumpmount\n");
  47. return;
  48. }
  49. rlock(&pg->ns);
  50. if(waserror()){
  51. runlock(&pg->ns);
  52. nexterror();
  53. }
  54. he = &pg->mnthash[MNTHASH];
  55. for(h = pg->mnthash; h < he; h++){
  56. for(f = *h; f; f = f->hash){
  57. print("head: %p: %s 0x%llux.%lud %C %lud -> \n", f,
  58. f->from->path->s, f->from->qid.path,
  59. f->from->qid.vers, devtab[f->from->type]->dc,
  60. f->from->dev);
  61. for(t = f->mount; t; t = t->next)
  62. print("\t%p: %s (umh %p) (path %.8llux dev %C %lud)\n", t, t->to->path->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev);
  63. }
  64. }
  65. poperror();
  66. runlock(&pg->ns);
  67. }
  68. char*
  69. chanpath(Chan *c)
  70. {
  71. if(c == nil)
  72. return "<nil chan>";
  73. if(c->path == nil)
  74. return "<nil path>";
  75. if(c->path->s == nil)
  76. return "<nil path.s>";
  77. return c->path->s;
  78. }
  79. int
  80. isdotdot(char *p)
  81. {
  82. return p[0]=='.' && p[1]=='.' && p[2]=='\0';
  83. }
  84. long
  85. incref(Ref *r)
  86. {
  87. long x;
  88. lock(&r->lk);
  89. x = ++r->ref;
  90. unlock(&r->lk);
  91. return x;
  92. }
  93. long
  94. decref(Ref *r)
  95. {
  96. long x;
  97. lock(&r->lk);
  98. x = --r->ref;
  99. unlock(&r->lk);
  100. if(x < 0)
  101. panic("decref pc=0x%lux", getcallerpc(&r));
  102. return x;
  103. }
  104. /*
  105. * Rather than strncpy, which zeros the rest of the buffer, kstrcpy
  106. * truncates if necessary, always zero terminates, does not zero fill,
  107. * and puts ... at the end of the string if it's too long. Usually used to
  108. * save a string in up->genbuf;
  109. */
  110. void
  111. kstrcpy(char *s, char *t, int ns)
  112. {
  113. int nt;
  114. nt = strlen(t);
  115. if(nt+1 <= ns){
  116. memmove(s, t, nt+1);
  117. return;
  118. }
  119. /* too long */
  120. if(ns < 4){
  121. /* but very short! */
  122. strncpy(s, t, ns);
  123. return;
  124. }
  125. /* truncate with ... at character boundary (very rare case) */
  126. memmove(s, t, ns-4);
  127. ns -= 4;
  128. s[ns] = '\0';
  129. /* look for first byte of UTF-8 sequence by skipping continuation bytes */
  130. while(ns>0 && (s[--ns]&0xC0)==0x80)
  131. ;
  132. strcpy(s+ns, "...");
  133. }
  134. int
  135. emptystr(char *s)
  136. {
  137. if(s == nil)
  138. return 1;
  139. if(s[0] == '\0')
  140. return 1;
  141. return 0;
  142. }
  143. /*
  144. * Atomically replace *p with copy of s
  145. */
  146. void
  147. kstrdup(char **p, char *s)
  148. {
  149. int n;
  150. char *t, *prev;
  151. n = strlen(s)+1;
  152. /* if it's a user, we can wait for memory; if not, something's very wrong */
  153. if(up){
  154. t = smalloc(n);
  155. setmalloctag(t, getcallerpc(&p));
  156. }else{
  157. t = malloc(n);
  158. if(t == nil)
  159. panic("kstrdup: no memory");
  160. }
  161. memmove(t, s, n);
  162. prev = *p;
  163. *p = t;
  164. free(prev);
  165. }
  166. void
  167. chandevreset(void)
  168. {
  169. int i;
  170. for(i=0; devtab[i] != nil; i++)
  171. devtab[i]->reset();
  172. }
  173. void
  174. chandevinit(void)
  175. {
  176. int i;
  177. for(i=0; devtab[i] != nil; i++)
  178. devtab[i]->init();
  179. }
  180. void
  181. chandevshutdown(void)
  182. {
  183. int i;
  184. /* shutdown in reverse order */
  185. for(i=0; devtab[i] != nil; i++)
  186. ;
  187. for(i--; i >= 0; i--)
  188. devtab[i]->shutdown();
  189. }
  190. Chan*
  191. newchan(void)
  192. {
  193. Chan *c;
  194. lock(&chanalloc.lk);
  195. c = chanalloc.free;
  196. if(c != 0)
  197. chanalloc.free = c->next;
  198. unlock(&chanalloc.lk);
  199. if(c == nil){
  200. c = smalloc(sizeof(Chan));
  201. lock(&chanalloc.lk);
  202. c->fid = ++chanalloc.fid;
  203. c->link = chanalloc.list;
  204. chanalloc.list = c;
  205. unlock(&chanalloc.lk);
  206. }
  207. /* if you get an error before associating with a dev,
  208. close calls rootclose, a nop */
  209. c->type = 0;
  210. c->flag = 0;
  211. c->ref.ref = 1;
  212. c->dev = 0;
  213. c->offset = 0;
  214. c->devoffset = 0;
  215. c->iounit = 0;
  216. c->umh = 0;
  217. c->uri = 0;
  218. c->dri = 0;
  219. c->aux = 0;
  220. c->mchan = 0;
  221. c->mcp = 0;
  222. c->mux = 0;
  223. memset(&c->mqid, 0, sizeof(c->mqid));
  224. c->path = 0;
  225. c->ismtpt = 0;
  226. return c;
  227. }
  228. Ref npath;
  229. Path*
  230. newpath(char *s)
  231. {
  232. int i;
  233. Path *p;
  234. p = smalloc(sizeof(Path));
  235. i = strlen(s);
  236. p->len = i;
  237. p->alen = i+PATHSLOP;
  238. p->s = smalloc(p->alen);
  239. memmove(p->s, s, i+1);
  240. p->ref.ref = 1;
  241. incref(&npath);
  242. /*
  243. * Cannot use newpath for arbitrary names because the mtpt
  244. * array will not be populated correctly. The names #/ and / are
  245. * allowed, but other names with / in them draw warnings.
  246. */
  247. if(strchr(s, '/') && strcmp(s, "#/") != 0 && strcmp(s, "/") != 0)
  248. print("newpath: %s from %lux\n", s, getcallerpc(&s));
  249. p->mlen = 1;
  250. p->malen = PATHMSLOP;
  251. p->mtpt = smalloc(p->malen*sizeof p->mtpt[0]);
  252. return p;
  253. }
  254. static Path*
  255. copypath(Path *p)
  256. {
  257. int i;
  258. Path *pp;
  259. pp = smalloc(sizeof(Path));
  260. pp->ref.ref = 1;
  261. incref(&npath);
  262. DBG("copypath %s %p => %p\n", p->s, p, pp);
  263. pp->len = p->len;
  264. pp->alen = p->alen;
  265. pp->s = smalloc(p->alen);
  266. memmove(pp->s, p->s, p->len+1);
  267. pp->mlen = p->mlen;
  268. pp->malen = p->malen;
  269. pp->mtpt = smalloc(p->malen*sizeof pp->mtpt[0]);
  270. for(i=0; i<pp->mlen; i++){
  271. pp->mtpt[i] = p->mtpt[i];
  272. if(pp->mtpt[i])
  273. incref(&pp->mtpt[i]->ref);
  274. }
  275. return pp;
  276. }
  277. void
  278. pathclose(Path *p)
  279. {
  280. int i;
  281. if(p == nil)
  282. return;
  283. //XXX
  284. DBG("pathclose %p %s ref=%ld =>", p, p->s, p->ref.ref);
  285. for(i=0; i<p->mlen; i++)
  286. DBG(" %p", p->mtpt[i]);
  287. DBG("\n");
  288. if(decref(&p->ref))
  289. return;
  290. decref(&npath);
  291. free(p->s);
  292. for(i=0; i<p->mlen; i++)
  293. if(p->mtpt[i])
  294. cclose(p->mtpt[i]);
  295. free(p->mtpt);
  296. free(p);
  297. }
  298. /*
  299. * In place, rewrite name to compress multiple /, eliminate ., and process ..
  300. * (Really only called to remove a trailing .. that has been added.
  301. * Otherwise would need to update n->mtpt as well.)
  302. */
  303. static void
  304. fixdotdotname(Path *p)
  305. {
  306. char *r;
  307. if(p->s[0] == '#'){
  308. r = strchr(p->s, '/');
  309. if(r == nil)
  310. return;
  311. cleanname(r);
  312. /*
  313. * The correct name is #i rather than #i/,
  314. * but the correct name of #/ is #/.
  315. */
  316. if(strcmp(r, "/")==0 && p->s[1] != '/')
  317. *r = '\0';
  318. }else
  319. cleanname(p->s);
  320. p->len = strlen(p->s);
  321. }
  322. static Path*
  323. uniquepath(Path *p)
  324. {
  325. Path *new;
  326. if(p->ref.ref > 1){
  327. /* copy on write */
  328. new = copypath(p);
  329. pathclose(p);
  330. p = new;
  331. }
  332. return p;
  333. }
  334. /*static*/ Path*
  335. addelem(Path *p, char *s, Chan *from)
  336. {
  337. char *t;
  338. int a, i;
  339. Chan *c, **tt;
  340. if(s[0]=='.' && s[1]=='\0')
  341. return p;
  342. p = uniquepath(p);
  343. i = strlen(s);
  344. if(p->len+1+i+1 > p->alen){
  345. a = p->len+1+i+1 + PATHSLOP;
  346. t = smalloc(a);
  347. memmove(t, p->s, p->len+1);
  348. free(p->s);
  349. p->s = t;
  350. p->alen = a;
  351. }
  352. /* don't insert extra slash if one is present */
  353. if(p->len>0 && p->s[p->len-1]!='/' && s[0]!='/')
  354. p->s[p->len++] = '/';
  355. memmove(p->s+p->len, s, i+1);
  356. p->len += i;
  357. if(isdotdot(s)){
  358. fixdotdotname(p);
  359. DBG("addelem %s .. => rm %p\n", p->s, p->mtpt[p->mlen-1]);
  360. if(p->mlen>1 && (c = p->mtpt[--p->mlen])){
  361. p->mtpt[p->mlen] = nil;
  362. cclose(c);
  363. }
  364. }else{
  365. if(p->mlen >= p->malen){
  366. p->malen = p->mlen+1+PATHMSLOP;
  367. tt = smalloc(p->malen*sizeof tt[0]);
  368. memmove(tt, p->mtpt, p->mlen*sizeof tt[0]);
  369. free(p->mtpt);
  370. p->mtpt = tt;
  371. }
  372. DBG("addelem %s %s => add %p\n", p->s, s, from);
  373. p->mtpt[p->mlen++] = from;
  374. if(from)
  375. incref(&from->ref);
  376. }
  377. return p;
  378. }
  379. void
  380. chanfree(Chan *c)
  381. {
  382. c->flag = CFREE;
  383. if(c->dirrock != nil){
  384. free(c->dirrock);
  385. c->dirrock = 0;
  386. c->nrock = 0;
  387. c->mrock = 0;
  388. }
  389. if(c->umh != nil){
  390. putmhead(c->umh);
  391. c->umh = nil;
  392. }
  393. if(c->umc != nil){
  394. cclose(c->umc);
  395. c->umc = nil;
  396. }
  397. if(c->mux != nil){
  398. muxclose(c->mux);
  399. c->mux = nil;
  400. }
  401. if(c->mchan != nil){
  402. cclose(c->mchan);
  403. c->mchan = nil;
  404. }
  405. pathclose(c->path);
  406. c->path = nil;
  407. lock(&chanalloc.lk);
  408. c->next = chanalloc.free;
  409. chanalloc.free = c;
  410. unlock(&chanalloc.lk);
  411. }
  412. void
  413. cclose(Chan *c)
  414. {
  415. if(c->flag&CFREE)
  416. panic("cclose %lux", getcallerpc(&c));
  417. DBG("cclose %p name=%s ref=%ld\n", c, c->path->s, c->ref.ref);
  418. if(decref(&c->ref))
  419. return;
  420. if(!waserror()){
  421. devtab[c->type]->close(c);
  422. poperror();
  423. }
  424. chanfree(c);
  425. }
  426. /*
  427. * Queue a chan to be closed by one of the clunk procs.
  428. */
  429. struct {
  430. Chan *head;
  431. Chan *tail;
  432. int nqueued;
  433. int nclosed;
  434. Lock l;
  435. QLock q;
  436. Rendez r;
  437. } clunkq;
  438. void closeproc(void*);
  439. void
  440. ccloseq(Chan *c)
  441. {
  442. if(c->flag&CFREE)
  443. panic("cclose %lux", getcallerpc(&c));
  444. DBG("ccloseq %p name=%s ref=%ld\n", c, c->path->s, c->ref.ref);
  445. if(decref(&c->ref))
  446. return;
  447. lock(&clunkq.l);
  448. clunkq.nqueued++;
  449. c->next = nil;
  450. if(clunkq.head)
  451. clunkq.tail->next = c;
  452. else
  453. clunkq.head = c;
  454. clunkq.tail = c;
  455. unlock(&clunkq.l);
  456. if(!wakeup(&clunkq.r))
  457. kproc("closeproc", closeproc, nil);
  458. }
  459. static int
  460. clunkwork(void *v)
  461. {
  462. return clunkq.head != nil;
  463. }
  464. void
  465. closeproc(void *v)
  466. {
  467. Chan *c;
  468. for(;;){
  469. qlock(&clunkq.q);
  470. if(clunkq.head == nil){
  471. if(!waserror()){
  472. tsleep(&clunkq.r, clunkwork, nil, 5000);
  473. poperror();
  474. }
  475. if(clunkq.head == nil){
  476. qunlock(&clunkq.q);
  477. pexit("no work", 1);
  478. }
  479. }
  480. lock(&clunkq.l);
  481. c = clunkq.head;
  482. clunkq.head = c->next;
  483. clunkq.nclosed++;
  484. unlock(&clunkq.l);
  485. qunlock(&clunkq.q);
  486. if(!waserror()){
  487. devtab[c->type]->close(c);
  488. poperror();
  489. }
  490. chanfree(c);
  491. }
  492. }
  493. /*
  494. * Make sure we have the only copy of c. (Copy on write.)
  495. */
  496. Chan*
  497. cunique(Chan *c)
  498. {
  499. Chan *nc;
  500. if(c->ref.ref != 1){
  501. nc = cclone(c);
  502. cclose(c);
  503. c = nc;
  504. }
  505. return c;
  506. }
  507. int
  508. eqqid(Qid a, Qid b)
  509. {
  510. return a.path==b.path && a.vers==b.vers;
  511. }
  512. int
  513. eqchan(Chan *a, Chan *b, int skipvers)
  514. {
  515. if(a->qid.path != b->qid.path)
  516. return 0;
  517. if(!skipvers && a->qid.vers!=b->qid.vers)
  518. return 0;
  519. if(a->type != b->type)
  520. return 0;
  521. if(a->dev != b->dev)
  522. return 0;
  523. return 1;
  524. }
  525. int
  526. eqchantdqid(Chan *a, int type, int dev, Qid qid, int skipvers)
  527. {
  528. if(a->qid.path != qid.path)
  529. return 0;
  530. if(!skipvers && a->qid.vers!=qid.vers)
  531. return 0;
  532. if(a->type != type)
  533. return 0;
  534. if(a->dev != dev)
  535. return 0;
  536. return 1;
  537. }
  538. Mhead*
  539. newmhead(Chan *from)
  540. {
  541. Mhead *mh;
  542. mh = smalloc(sizeof(Mhead));
  543. mh->ref.ref = 1;
  544. mh->from = from;
  545. incref(&from->ref);
  546. return mh;
  547. }
  548. int
  549. cmount(Chan **newp, Chan *old, int flag, char *spec)
  550. {
  551. int order, flg;
  552. Chan *new;
  553. Mhead *m, **l, *mh;
  554. Mount *nm, *f, *um, **h;
  555. Pgrp *pg;
  556. if(QTDIR & (old->qid.type^(*newp)->qid.type))
  557. error(Emount);
  558. if(old->umh)
  559. print("cmount: unexpected umh, caller %.8lux\n", getcallerpc(&newp));
  560. order = flag&MORDER;
  561. if((old->qid.type&QTDIR)==0 && order != MREPL)
  562. error(Emount);
  563. new = *newp;
  564. mh = new->umh;
  565. /*
  566. * Not allowed to bind when the old directory is itself a union.
  567. * (Maybe it should be allowed, but I don't see what the semantics
  568. * would be.)
  569. *
  570. * We need to check mh->mount->next to tell unions apart from
  571. * simple mount points, so that things like
  572. * mount -c fd /root
  573. * bind -c /root /
  574. * work.
  575. *
  576. * The check of mount->mflag allows things like
  577. * mount fd /root
  578. * bind -c /root /
  579. *
  580. * This is far more complicated than it should be, but I don't
  581. * see an easier way at the moment.
  582. */
  583. if((flag&MCREATE) && mh && mh->mount
  584. && (mh->mount->next || !(mh->mount->mflag&MCREATE)))
  585. error(Emount);
  586. pg = up->pgrp;
  587. wlock(&pg->ns);
  588. l = &MOUNTH(pg, old->qid);
  589. for(m = *l; m; m = m->hash){
  590. if(eqchan(m->from, old, 1))
  591. break;
  592. l = &m->hash;
  593. }
  594. if(m == nil){
  595. /*
  596. * nothing mounted here yet. create a mount
  597. * head and add to the hash table.
  598. */
  599. m = newmhead(old);
  600. *l = m;
  601. /*
  602. * if this is a union mount, add the old
  603. * node to the mount chain.
  604. */
  605. if(order != MREPL)
  606. m->mount = newmount(m, old, 0, 0);
  607. }
  608. wlock(&m->lock);
  609. if(waserror()){
  610. wunlock(&m->lock);
  611. nexterror();
  612. }
  613. wunlock(&pg->ns);
  614. nm = newmount(m, new, flag, spec);
  615. if(mh != nil && mh->mount != nil){
  616. /*
  617. * copy a union when binding it onto a directory
  618. */
  619. flg = order;
  620. if(order == MREPL)
  621. flg = MAFTER;
  622. h = &nm->next;
  623. um = mh->mount;
  624. for(um = um->next; um; um = um->next){
  625. f = newmount(m, um->to, flg, um->spec);
  626. *h = f;
  627. h = &f->next;
  628. }
  629. }
  630. if(m->mount && order == MREPL){
  631. mountfree(m->mount);
  632. m->mount = 0;
  633. }
  634. if(flag & MCREATE)
  635. nm->mflag |= MCREATE;
  636. if(m->mount && order == MAFTER){
  637. for(f = m->mount; f->next; f = f->next)
  638. ;
  639. f->next = nm;
  640. }else{
  641. for(f = nm; f->next; f = f->next)
  642. ;
  643. f->next = m->mount;
  644. m->mount = nm;
  645. }
  646. wunlock(&m->lock);
  647. poperror();
  648. return nm->mountid;
  649. }
  650. void
  651. cunmount(Chan *mnt, Chan *mounted)
  652. {
  653. Pgrp *pg;
  654. Mhead *m, **l;
  655. Mount *f, **p;
  656. if(mnt->umh) /* should not happen */
  657. print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
  658. /*
  659. * It _can_ happen that mounted->umh is non-nil,
  660. * because mounted is the result of namec(Aopen)
  661. * (see sysfile.c:/^sysunmount).
  662. * If we open a union directory, it will have a umh.
  663. * Although surprising, this is okay, since the
  664. * cclose will take care of freeing the umh.
  665. */
  666. pg = up->pgrp;
  667. wlock(&pg->ns);
  668. l = &MOUNTH(pg, mnt->qid);
  669. for(m = *l; m; m = m->hash){
  670. if(eqchan(m->from, mnt, 1))
  671. break;
  672. l = &m->hash;
  673. }
  674. if(m == 0){
  675. wunlock(&pg->ns);
  676. error(Eunmount);
  677. }
  678. wlock(&m->lock);
  679. if(mounted == 0){
  680. *l = m->hash;
  681. wunlock(&pg->ns);
  682. mountfree(m->mount);
  683. m->mount = nil;
  684. cclose(m->from);
  685. wunlock(&m->lock);
  686. putmhead(m);
  687. return;
  688. }
  689. p = &m->mount;
  690. for(f = *p; f; f = f->next){
  691. /* BUG: Needs to be 2 pass */
  692. if(eqchan(f->to, mounted, 1) ||
  693. (f->to->mchan && eqchan(f->to->mchan, mounted, 1))){
  694. *p = f->next;
  695. f->next = 0;
  696. mountfree(f);
  697. if(m->mount == nil){
  698. *l = m->hash;
  699. cclose(m->from);
  700. wunlock(&m->lock);
  701. wunlock(&pg->ns);
  702. putmhead(m);
  703. return;
  704. }
  705. wunlock(&m->lock);
  706. wunlock(&pg->ns);
  707. return;
  708. }
  709. p = &f->next;
  710. }
  711. wunlock(&m->lock);
  712. wunlock(&pg->ns);
  713. error(Eunion);
  714. }
  715. Chan*
  716. cclone(Chan *c)
  717. {
  718. Chan *nc;
  719. Walkqid *wq;
  720. wq = devtab[c->type]->walk(c, nil, nil, 0);
  721. if(wq == nil)
  722. error("clone failed");
  723. nc = wq->clone;
  724. free(wq);
  725. nc->path = c->path;
  726. if(c->path)
  727. incref(&c->path->ref);
  728. return nc;
  729. }
  730. /* also used by sysfile.c:/^mountfix */
  731. int
  732. findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
  733. {
  734. Pgrp *pg;
  735. Mhead *m;
  736. pg = up->pgrp;
  737. rlock(&pg->ns);
  738. for(m = MOUNTH(pg, qid); m; m = m->hash){
  739. rlock(&m->lock);
  740. if(m->from == nil){
  741. print("m %p m->from 0\n", m);
  742. runlock(&m->lock);
  743. continue;
  744. }
  745. if(eqchantdqid(m->from, type, dev, qid, 1)){
  746. runlock(&pg->ns);
  747. if(mp != nil){
  748. incref(&m->ref);
  749. if(*mp != nil)
  750. putmhead(*mp);
  751. *mp = m;
  752. }
  753. if(*cp != nil)
  754. cclose(*cp);
  755. incref(&m->mount->to->ref);
  756. *cp = m->mount->to;
  757. runlock(&m->lock);
  758. return 1;
  759. }
  760. runlock(&m->lock);
  761. }
  762. runlock(&pg->ns);
  763. return 0;
  764. }
  765. /*
  766. * Calls findmount but also updates path.
  767. */
  768. static int
  769. domount(Chan **cp, Mhead **mp, Path **path)
  770. {
  771. Chan **lc;
  772. Path *p;
  773. if(findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid) == 0)
  774. return 0;
  775. if(path){
  776. p = *path;
  777. p = uniquepath(p);
  778. if(p->mlen <= 0)
  779. print("domount: path %s has mlen==%d\n", p->s, p->mlen);
  780. else{
  781. lc = &p->mtpt[p->mlen-1];
  782. DBG("domount %p %s => add %p (was %p)\n", p, p->s, (*mp)->from, p->mtpt[p->mlen-1]);
  783. incref(&(*mp)->from->ref);
  784. if(*lc)
  785. cclose(*lc);
  786. *lc = (*mp)->from;
  787. }
  788. *path = p;
  789. }
  790. return 1;
  791. }
  792. /*
  793. * If c is the right-hand-side of a mount point, returns the left hand side.
  794. * Changes name to reflect the fact that we've uncrossed the mountpoint,
  795. * so name had better be ours to change!
  796. */
  797. static Chan*
  798. undomount(Chan *c, Path *path)
  799. {
  800. Chan *nc;
  801. if(path->ref.ref != 1 || path->mlen == 0)
  802. print("undomount: path %s ref %ld mlen %d caller %lux\n",
  803. path->s, path->ref.ref, path->mlen, getcallerpc(&c));
  804. if(path->mlen>0 && (nc=path->mtpt[path->mlen-1]) != nil){
  805. DBG("undomount %p %s => remove %p\n", path, path->s, nc);
  806. cclose(c);
  807. path->mtpt[path->mlen-1] = nil;
  808. c = nc;
  809. }
  810. return c;
  811. }
  812. /*
  813. * Call dev walk but catch errors.
  814. */
  815. static Walkqid*
  816. ewalk(Chan *c, Chan *nc, char **name, int nname)
  817. {
  818. Walkqid *wq;
  819. if(waserror())
  820. return nil;
  821. wq = devtab[c->type]->walk(c, nc, name, nname);
  822. poperror();
  823. return wq;
  824. }
  825. /*
  826. * Either walks all the way or not at all. No partial results in *cp.
  827. * *nerror is the number of names to display in an error message.
  828. */
  829. static char Edoesnotexist[] = "does not exist";
  830. int
  831. walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
  832. {
  833. int dev, didmount, dotdot, i, n, nhave, ntry, type;
  834. Chan *c, *nc, *mtpt;
  835. Path *path;
  836. Mhead *mh, *nmh;
  837. Mount *f;
  838. Walkqid *wq;
  839. c = *cp;
  840. incref(&c->ref);
  841. path = c->path;
  842. incref(&path->ref);
  843. mh = nil;
  844. /*
  845. * While we haven't gotten all the way down the path:
  846. * 1. step through a mount point, if any
  847. * 2. send a walk request for initial dotdot or initial prefix without dotdot
  848. * 3. move to the first mountpoint along the way.
  849. * 4. repeat.
  850. *
  851. * Each time through the loop:
  852. *
  853. * If didmount==0, c is on the undomount side of the mount point.
  854. * If didmount==1, c is on the domount side of the mount point.
  855. * Either way, c's full path is path.
  856. */
  857. didmount = 0;
  858. for(nhave=0; nhave<nnames; nhave+=n){
  859. if((c->qid.type&QTDIR)==0){
  860. if(nerror)
  861. *nerror = nhave;
  862. pathclose(path);
  863. cclose(c);
  864. strcpy(up->errstr, Enotdir);
  865. if(mh != nil)
  866. putmhead(mh);
  867. return -1;
  868. }
  869. ntry = nnames - nhave;
  870. if(ntry > MAXWELEM)
  871. ntry = MAXWELEM;
  872. dotdot = 0;
  873. for(i=0; i<ntry; i++){
  874. if(isdotdot(names[nhave+i])){
  875. if(i==0){
  876. dotdot = 1;
  877. ntry = 1;
  878. }else
  879. ntry = i;
  880. break;
  881. }
  882. }
  883. if(!dotdot && !nomount && !didmount)
  884. domount(&c, &mh, &path);
  885. type = c->type;
  886. dev = c->dev;
  887. if((wq = ewalk(c, nil, names+nhave, ntry)) == nil){
  888. /* try a union mount, if any */
  889. if(mh && !nomount){
  890. /*
  891. * mh->mount->to == c, so start at mh->mount->next
  892. */
  893. rlock(&mh->lock);
  894. for(f = mh->mount->next; f; f = f->next)
  895. if((wq = ewalk(f->to, nil, names+nhave, ntry)) != nil)
  896. break;
  897. runlock(&mh->lock);
  898. if(f != nil){
  899. type = f->to->type;
  900. dev = f->to->dev;
  901. }
  902. }
  903. if(wq == nil){
  904. cclose(c);
  905. pathclose(path);
  906. if(nerror)
  907. *nerror = nhave+1;
  908. if(mh != nil)
  909. putmhead(mh);
  910. return -1;
  911. }
  912. }
  913. didmount = 0;
  914. if(dotdot){
  915. assert(wq->nqid == 1);
  916. assert(wq->clone != nil);
  917. path = addelem(path, "..", nil);
  918. nc = undomount(wq->clone, path);
  919. nmh = nil;
  920. n = 1;
  921. }else{
  922. nc = nil;
  923. nmh = nil;
  924. if(!nomount){
  925. for(i=0; i<wq->nqid && i<ntry-1; i++){
  926. if(findmount(&nc, &nmh, type, dev, wq->qid[i])){
  927. didmount = 1;
  928. break;
  929. }
  930. }
  931. }
  932. if(nc == nil){ /* no mount points along path */
  933. if(wq->clone == nil){
  934. cclose(c);
  935. pathclose(path);
  936. if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
  937. if(nerror)
  938. *nerror = nhave+wq->nqid+1;
  939. strcpy(up->errstr, Edoesnotexist);
  940. }else{
  941. if(nerror)
  942. *nerror = nhave+wq->nqid;
  943. strcpy(up->errstr, Enotdir);
  944. }
  945. free(wq);
  946. if(mh != nil)
  947. putmhead(mh);
  948. return -1;
  949. }
  950. n = wq->nqid;
  951. nc = wq->clone;
  952. }else{ /* stopped early, at a mount point */
  953. didmount = 1;
  954. if(wq->clone != nil){
  955. cclose(wq->clone);
  956. wq->clone = nil;
  957. }
  958. n = i+1;
  959. }
  960. for(i=0; i<n; i++){
  961. mtpt = nil;
  962. if(i==n-1 && nmh)
  963. mtpt = nmh->from;
  964. path = addelem(path, names[nhave+i], mtpt);
  965. }
  966. }
  967. cclose(c);
  968. c = nc;
  969. putmhead(mh);
  970. mh = nmh;
  971. free(wq);
  972. }
  973. putmhead(mh);
  974. c = cunique(c);
  975. if(c->umh != nil){ //BUG
  976. print("walk umh\n");
  977. putmhead(c->umh);
  978. c->umh = nil;
  979. }
  980. pathclose(c->path);
  981. c->path = path;
  982. cclose(*cp);
  983. *cp = c;
  984. if(nerror)
  985. *nerror = nhave;
  986. return 0;
  987. }
  988. /*
  989. * c is a mounted non-creatable directory. find a creatable one.
  990. */
  991. Chan*
  992. createdir(Chan *c, Mhead *m)
  993. {
  994. Chan *nc;
  995. Mount *f;
  996. rlock(&m->lock);
  997. if(waserror()){
  998. runlock(&m->lock);
  999. nexterror();
  1000. }
  1001. for(f = m->mount; f; f = f->next){
  1002. if(f->mflag&MCREATE){
  1003. nc = cclone(f->to);
  1004. runlock(&m->lock);
  1005. poperror();
  1006. cclose(c);
  1007. return nc;
  1008. }
  1009. }
  1010. error(Enocreate);
  1011. return 0;
  1012. }
  1013. void
  1014. saveregisters(void)
  1015. {
  1016. }
  1017. static void
  1018. growparse(Elemlist *e)
  1019. {
  1020. char **new;
  1021. int *inew;
  1022. enum { Delta = 8 };
  1023. if(e->nelems % Delta == 0){
  1024. new = smalloc((e->nelems+Delta) * sizeof(char*));
  1025. memmove(new, e->elems, e->nelems*sizeof(char*));
  1026. free(e->elems);
  1027. e->elems = new;
  1028. inew = smalloc((e->nelems+Delta+1) * sizeof(int));
  1029. memmove(inew, e->off, (e->nelems+1)*sizeof(int));
  1030. free(e->off);
  1031. e->off = inew;
  1032. }
  1033. }
  1034. /*
  1035. * The name is known to be valid.
  1036. * Copy the name so slashes can be overwritten.
  1037. * An empty string will set nelem=0.
  1038. * A path ending in / or /. or /.//./ etc. will have
  1039. * e.mustbedir = 1, so that we correctly
  1040. * reject, e.g., "/adm/users/." when /adm/users is a file
  1041. * rather than a directory.
  1042. */
  1043. static void
  1044. parsename(char *aname, Elemlist *e)
  1045. {
  1046. char *name, *slash;
  1047. kstrdup(&e->name, aname);
  1048. name = e->name;
  1049. e->nelems = 0;
  1050. e->elems = nil;
  1051. e->off = smalloc(sizeof(int));
  1052. e->off[0] = skipslash(name) - name;
  1053. for(;;){
  1054. name = skipslash(name);
  1055. if(*name == '\0'){
  1056. e->off[e->nelems] = name+strlen(name) - e->name;
  1057. e->mustbedir = 1;
  1058. break;
  1059. }
  1060. growparse(e);
  1061. e->elems[e->nelems++] = name;
  1062. slash = utfrune(name, '/');
  1063. if(slash == nil){
  1064. e->off[e->nelems] = name+strlen(name) - e->name;
  1065. e->mustbedir = 0;
  1066. break;
  1067. }
  1068. e->off[e->nelems] = slash - e->name;
  1069. *slash++ = '\0';
  1070. name = slash;
  1071. }
  1072. if(0 && chandebug){
  1073. int i;
  1074. print("parsename %s:", e->name);
  1075. for(i=0; i<=e->nelems; i++)
  1076. print(" %d", e->off[i]);
  1077. print("\n");
  1078. }
  1079. }
  1080. void*
  1081. memrchr(void *va, int c, long n)
  1082. {
  1083. uchar *a, *e;
  1084. a = va;
  1085. for(e=a+n-1; e>a; e--)
  1086. if(*e == c)
  1087. return e;
  1088. return nil;
  1089. }
  1090. void
  1091. namelenerror(char *aname, int len, char *err)
  1092. {
  1093. char *ename, *name, *next;
  1094. int i, errlen;
  1095. /*
  1096. * If the name is short enough, just use the whole thing.
  1097. */
  1098. errlen = strlen(err);
  1099. if(len < ERRMAX/3 || len+errlen < 2*ERRMAX/3)
  1100. snprint(up->genbuf, sizeof up->genbuf, "%.*s",
  1101. utfnlen(aname, len), aname);
  1102. else{
  1103. /*
  1104. * Print a suffix of the name, but try to get a little info.
  1105. */
  1106. ename = aname+len;
  1107. next = ename;
  1108. do{
  1109. name = next;
  1110. next = memrchr(aname, '/', name-aname);
  1111. if(next == nil)
  1112. next = aname;
  1113. len = ename-next;
  1114. }while(len < ERRMAX/3 || len + errlen < 2*ERRMAX/3);
  1115. /*
  1116. * If the name is ridiculously long, chop it.
  1117. */
  1118. if(name == ename){
  1119. name = ename-ERRMAX/4;
  1120. if(name <= aname)
  1121. panic("bad math in namelenerror");
  1122. /* walk out of current UTF sequence */
  1123. for(i=0; (*name&0xC0)==0x80 && i<3; i++)
  1124. name++;
  1125. }
  1126. snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
  1127. utfnlen(name, ename-name), name);
  1128. }
  1129. snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
  1130. nexterror();
  1131. }
  1132. void
  1133. nameerror(char *name, char *err)
  1134. {
  1135. namelenerror(name, strlen(name), err);
  1136. }
  1137. /*
  1138. * Turn a name into a channel.
  1139. * &name[0] is known to be a valid address. It may be a kernel address.
  1140. *
  1141. * Opening with amode Aopen, Acreate, Aremove, or Aaccess guarantees
  1142. * that the result will be the only reference to that particular fid.
  1143. * This is necessary since we might pass the result to
  1144. * devtab[]->remove().
  1145. *
  1146. * Opening Atodir or Amount does not guarantee this.
  1147. *
  1148. * Under certain circumstances, opening Aaccess will cause
  1149. * an unnecessary clone in order to get a cunique Chan so it
  1150. * can attach the correct name. Sysstat and sys_stat need the
  1151. * correct name so they can rewrite the stat info.
  1152. */
  1153. Chan*
  1154. namec(char *aname, int amode, int omode, ulong perm)
  1155. {
  1156. int len, n, t, nomount;
  1157. Chan *c, *cnew;
  1158. Path *path;
  1159. Elemlist e;
  1160. Rune r;
  1161. Mhead *m;
  1162. char *createerr, tmperrbuf[ERRMAX];
  1163. char *name;
  1164. if(aname[0] == '\0')
  1165. error("empty file name");
  1166. aname = validnamedup(aname, 1);
  1167. if(waserror()){
  1168. free(aname);
  1169. nexterror();
  1170. }
  1171. if(tracesyscalls)
  1172. iprint("\tnamec %s\n", aname);
  1173. DBG("namec %s %d %d\n", aname, amode, omode);
  1174. name = aname;
  1175. /*
  1176. * Find the starting off point (the current slash, the root of
  1177. * a device tree, or the current dot) as well as the name to
  1178. * evaluate starting there.
  1179. */
  1180. nomount = 0;
  1181. switch(name[0]){
  1182. case '/':
  1183. c = up->slash;
  1184. incref(&c->ref);
  1185. break;
  1186. case '#':
  1187. nomount = 1;
  1188. up->genbuf[0] = '\0';
  1189. n = 0;
  1190. while(*name != '\0' && (*name != '/' || n < 2)){
  1191. if(n >= sizeof(up->genbuf)-1)
  1192. error(Efilename);
  1193. up->genbuf[n++] = *name++;
  1194. }
  1195. up->genbuf[n] = '\0';
  1196. /*
  1197. * noattach is sandboxing.
  1198. *
  1199. * the OK exceptions are:
  1200. * | it only gives access to pipes you create
  1201. * d this process's file descriptors
  1202. * e this process's environment
  1203. * the iffy exceptions are:
  1204. * c time and pid, but also cons and consctl
  1205. * p control of your own processes (and unfortunately
  1206. * any others left unprotected)
  1207. */
  1208. n = chartorune(&r, up->genbuf+1)+1;
  1209. /* actually / is caught by parsing earlier */
  1210. if(utfrune("M", r))
  1211. error(Enoattach);
  1212. if(up->pgrp->noattach && utfrune("|decp", r)==nil)
  1213. error(Enoattach);
  1214. t = devno(r, 1);
  1215. if(t == -1)
  1216. error(Ebadsharp);
  1217. c = devtab[t]->attach(up->genbuf+n);
  1218. break;
  1219. default:
  1220. c = up->dot;
  1221. incref(&c->ref);
  1222. break;
  1223. }
  1224. e.aname = aname;
  1225. e.prefix = name - aname;
  1226. e.name = nil;
  1227. e.elems = nil;
  1228. e.off = nil;
  1229. e.nelems = 0;
  1230. e.nerror = 0;
  1231. if(waserror()){
  1232. cclose(c);
  1233. free(e.name);
  1234. free(e.elems);
  1235. /*
  1236. * Prepare nice error, showing first e.nerror elements of name.
  1237. */
  1238. if(e.nerror == 0)
  1239. nexterror();
  1240. strcpy(tmperrbuf, up->errstr);
  1241. if(e.off[e.nerror]==0)
  1242. print("nerror=%d but off=%d\n",
  1243. e.nerror, e.off[e.nerror]);
  1244. if(0 && chandebug)
  1245. print("showing %d+%d/%d (of %d) of %s (%d %d)\n", e.prefix, e.off[e.nerror], e.nerror, e.nelems, aname, e.off[0], e.off[1]);
  1246. len = e.prefix+e.off[e.nerror];
  1247. free(e.off);
  1248. namelenerror(aname, len, tmperrbuf);
  1249. }
  1250. /*
  1251. * Build a list of elements in the name.
  1252. */
  1253. parsename(name, &e);
  1254. /*
  1255. * On create, ....
  1256. */
  1257. if(amode == Acreate){
  1258. /* perm must have DMDIR if last element is / or /. */
  1259. if(e.mustbedir && !(perm&DMDIR)){
  1260. e.nerror = e.nelems;
  1261. error("create without DMDIR");
  1262. }
  1263. /* don't try to walk the last path element just yet. */
  1264. if(e.nelems == 0)
  1265. error(Eexist);
  1266. e.nelems--;
  1267. }
  1268. if(walk(&c, e.elems, e.nelems, nomount, &e.nerror) < 0){
  1269. if(e.nerror < 0 || e.nerror > e.nelems){
  1270. print("namec %s walk error nerror=%d\n", aname, e.nerror);
  1271. e.nerror = 0;
  1272. }
  1273. nexterror();
  1274. }
  1275. if(e.mustbedir && !(c->qid.type&QTDIR))
  1276. error("not a directory");
  1277. if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR))
  1278. error("cannot exec directory");
  1279. switch(amode){
  1280. case Abind:
  1281. /* no need to maintain path - cannot dotdot an Abind */
  1282. m = nil;
  1283. if(!nomount)
  1284. domount(&c, &m, nil);
  1285. if(c->umh != nil)
  1286. putmhead(c->umh);
  1287. c->umh = m;
  1288. break;
  1289. case Aaccess:
  1290. case Aremove:
  1291. case Aopen:
  1292. Open:
  1293. /* save&update the name; domount might change c */
  1294. path = c->path;
  1295. incref(&path->ref);
  1296. m = nil;
  1297. if(!nomount)
  1298. domount(&c, &m, &path);
  1299. /* our own copy to open or remove */
  1300. c = cunique(c);
  1301. /* now it's our copy anyway, we can put the name back */
  1302. pathclose(c->path);
  1303. c->path = path;
  1304. /* record whether c is on a mount point */
  1305. c->ismtpt = m!=nil;
  1306. switch(amode){
  1307. case Aaccess:
  1308. case Aremove:
  1309. putmhead(m);
  1310. break;
  1311. case Aopen:
  1312. case Acreate:
  1313. if(c->umh != nil){
  1314. print("cunique umh Open\n");
  1315. putmhead(c->umh);
  1316. c->umh = nil;
  1317. }
  1318. /* only save the mount head if it's a multiple element union */
  1319. if(m && m->mount && m->mount->next)
  1320. c->umh = m;
  1321. else
  1322. putmhead(m);
  1323. /* save registers else error() in open has wrong value of c saved */
  1324. saveregisters();
  1325. if(omode == OEXEC)
  1326. c->flag &= ~CCACHE;
  1327. c = devtab[c->type]->open(c, omode&~OCEXEC);
  1328. if(omode & OCEXEC)
  1329. c->flag |= CCEXEC;
  1330. if(omode & ORCLOSE)
  1331. c->flag |= CRCLOSE;
  1332. break;
  1333. }
  1334. break;
  1335. case Atodir:
  1336. /*
  1337. * Directories (e.g. for cd) are left before the mount point,
  1338. * so one may mount on / or . and see the effect.
  1339. */
  1340. if(!(c->qid.type & QTDIR))
  1341. error(Enotdir);
  1342. break;
  1343. case Amount:
  1344. /*
  1345. * When mounting on an already mounted upon directory,
  1346. * one wants subsequent mounts to be attached to the
  1347. * original directory, not the replacement. Don't domount.
  1348. */
  1349. break;
  1350. case Acreate:
  1351. /*
  1352. * We've already walked all but the last element.
  1353. * If the last exists, try to open it OTRUNC.
  1354. * If omode&OEXCL is set, just give up.
  1355. */
  1356. e.nelems++;
  1357. e.nerror++;
  1358. if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
  1359. if(omode&OEXCL)
  1360. error(Eexist);
  1361. omode |= OTRUNC;
  1362. goto Open;
  1363. }
  1364. /*
  1365. * The semantics of the create(2) system call are that if the
  1366. * file exists and can be written, it is to be opened with truncation.
  1367. * On the other hand, the create(5) message fails if the file exists.
  1368. * If we get two create(2) calls happening simultaneously,
  1369. * they might both get here and send create(5) messages, but only
  1370. * one of the messages will succeed. To provide the expected create(2)
  1371. * semantics, the call with the failed message needs to try the above
  1372. * walk again, opening for truncation. This correctly solves the
  1373. * create/create race, in the sense that any observable outcome can
  1374. * be explained as one happening before the other.
  1375. * The create/create race is quite common. For example, it happens
  1376. * when two rc subshells simultaneously update the same
  1377. * environment variable.
  1378. *
  1379. * The implementation still admits a create/create/remove race:
  1380. * (A) walk to file, fails
  1381. * (B) walk to file, fails
  1382. * (A) create file, succeeds, returns
  1383. * (B) create file, fails
  1384. * (A) remove file, succeeds, returns
  1385. * (B) walk to file, return failure.
  1386. *
  1387. * This is hardly as common as the create/create race, and is really
  1388. * not too much worse than what might happen if (B) got a hold of a
  1389. * file descriptor and then the file was removed -- either way (B) can't do
  1390. * anything with the result of the create call. So we don't care about this race.
  1391. *
  1392. * Applications that care about more fine-grained decision of the races
  1393. * can use the OEXCL flag to get at the underlying create(5) semantics;
  1394. * by default we provide the common case.
  1395. *
  1396. * We need to stay behind the mount point in case we
  1397. * need to do the first walk again (should the create fail).
  1398. *
  1399. * We also need to cross the mount point and find the directory
  1400. * in the union in which we should be creating.
  1401. *
  1402. * The channel staying behind is c, the one moving forward is cnew.
  1403. */
  1404. m = nil;
  1405. cnew = nil; /* is this assignment necessary? */
  1406. if(!waserror()){ /* try create */
  1407. if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
  1408. cnew = createdir(cnew, m);
  1409. else{
  1410. cnew = c;
  1411. incref(&cnew->ref);
  1412. }
  1413. /*
  1414. * We need our own copy of the Chan because we're
  1415. * about to send a create, which will move it. Once we have
  1416. * our own copy, we can fix the name, which might be wrong
  1417. * if findmount gave us a new Chan.
  1418. */
  1419. cnew = cunique(cnew);
  1420. pathclose(cnew->path);
  1421. cnew->path = c->path;
  1422. incref(&cnew->path->ref);
  1423. devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
  1424. poperror();
  1425. if(omode & OCEXEC)
  1426. cnew->flag |= CCEXEC;
  1427. if(omode & ORCLOSE)
  1428. cnew->flag |= CRCLOSE;
  1429. if(m)
  1430. putmhead(m);
  1431. cclose(c);
  1432. c = cnew;
  1433. c->path = addelem(c->path, e.elems[e.nelems-1], nil);
  1434. break;
  1435. }
  1436. /* create failed */
  1437. cclose(cnew);
  1438. if(m)
  1439. putmhead(m);
  1440. if(omode & OEXCL)
  1441. nexterror();
  1442. /* save error */
  1443. createerr = up->errstr;
  1444. up->errstr = tmperrbuf;
  1445. /* note: we depend that walk does not error */
  1446. if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
  1447. up->errstr = createerr;
  1448. error(createerr); /* report true error */
  1449. }
  1450. up->errstr = createerr;
  1451. omode |= OTRUNC;
  1452. goto Open;
  1453. default:
  1454. panic("unknown namec access %d\n", amode);
  1455. }
  1456. /* place final element in genbuf for e.g. exec */
  1457. if(e.nelems > 0)
  1458. kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf);
  1459. else
  1460. kstrcpy(up->genbuf, ".", sizeof up->genbuf);
  1461. free(e.name);
  1462. free(e.elems);
  1463. free(e.off);
  1464. poperror(); /* e c */
  1465. free(aname);
  1466. poperror(); /* aname */
  1467. return c;
  1468. }
  1469. /*
  1470. * name is valid. skip leading / and ./ as much as possible
  1471. */
  1472. char*
  1473. skipslash(char *name)
  1474. {
  1475. while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
  1476. name++;
  1477. return name;
  1478. }
  1479. char isfrog[256]={
  1480. /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1481. /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1482. /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1483. /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1,
  1484. ['/'] 1,
  1485. [0x7f] 1,
  1486. };
  1487. /*
  1488. * Check that the name
  1489. * a) is in valid memory.
  1490. * b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
  1491. * c) contains no frogs.
  1492. * The first byte is known to be addressible by the requester, so the
  1493. * routine works for kernel and user memory both.
  1494. * The parameter slashok flags whether a slash character is an error
  1495. * or a valid character.
  1496. *
  1497. * The parameter dup flags whether the string should be copied
  1498. * out of user space before being scanned the second time.
  1499. * (Otherwise a malicious thread could remove the NUL, causing us
  1500. * to access unchecked addresses.)
  1501. */
  1502. static char*
  1503. validname0(char *aname, int slashok, int dup, ulong pc)
  1504. {
  1505. char *p, *ename, *name, *s;
  1506. uint t;
  1507. int c, n;
  1508. Rune r;
  1509. name = aname;
  1510. if(isuaddr(name)){
  1511. if(!dup)
  1512. print("warning: validname called from %lux with user pointer", pc);
  1513. p = name;
  1514. t = BY2PG-((ulong)p&(BY2PG-1));
  1515. while((ename=vmemchr(p, 0, t)) == nil){
  1516. p += t;
  1517. t = BY2PG;
  1518. }
  1519. }else
  1520. ename = memchr(name, 0, (1<<16));
  1521. if(ename==nil || ename-name>=(1<<16))
  1522. error("name too long");
  1523. s = nil;
  1524. if(dup){
  1525. n = ename-name;
  1526. s = smalloc(n+1);
  1527. memmove(s, name, n);
  1528. s[n] = 0;
  1529. aname = s;
  1530. name = s;
  1531. setmalloctag(s, pc);
  1532. }
  1533. while(*name){
  1534. /* all characters above '~' are ok */
  1535. c = *(uchar*)name;
  1536. if(c >= Runeself)
  1537. name += chartorune(&r, name);
  1538. else{
  1539. if(isfrog[c])
  1540. if(!slashok || c!='/'){
  1541. snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
  1542. free(s);
  1543. error(up->genbuf);
  1544. }
  1545. name++;
  1546. }
  1547. }
  1548. return s;
  1549. }
  1550. void
  1551. validname(char *aname, int slashok)
  1552. {
  1553. validname0(aname, slashok, 0, getcallerpc(&aname));
  1554. }
  1555. char*
  1556. validnamedup(char *aname, int slashok)
  1557. {
  1558. return validname0(aname, slashok, 1, getcallerpc(&aname));
  1559. }
  1560. void
  1561. isdir(Chan *c)
  1562. {
  1563. if(c->qid.type & QTDIR)
  1564. return;
  1565. error(Enotdir);
  1566. }
  1567. /*
  1568. * This is necessary because there are many
  1569. * pointers to the top of a given mount list:
  1570. *
  1571. * - the mhead in the namespace hash table
  1572. * - the mhead in chans returned from findmount:
  1573. * used in namec and then by unionread.
  1574. * - the mhead in chans returned from createdir:
  1575. * used in the open/create race protect, which is gone.
  1576. *
  1577. * The RWlock in the Mhead protects the mount list it contains.
  1578. * The mount list is deleted when we cunmount.
  1579. * The RWlock ensures that nothing is using the mount list at that time.
  1580. *
  1581. * It is okay to replace c->mh with whatever you want as
  1582. * long as you are sure you have a unique reference to it.
  1583. *
  1584. * This comment might belong somewhere else.
  1585. */
  1586. void
  1587. putmhead(Mhead *m)
  1588. {
  1589. if(m && decref(&m->ref) == 0){
  1590. m->mount = (Mount*)0xCafeBeef;
  1591. free(m);
  1592. }
  1593. }