1
0

prog4.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. <html>
  2. <title>
  3. data
  4. </title>
  5. <body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044">
  6. <H1>Changes to the Programming Environment
  7. <br>
  8. in the
  9. <br>
  10. Fourth Release of Plan 9
  11. </H1>
  12. <DL><DD><I>Rob Pike<br>
  13. <br>&#32;<br>
  14. rob@plan9.bell-labs.com<br>
  15. </I></DL>
  16. <H4>Introduction
  17. </H4>
  18. <P>
  19. The fourth release of Plan 9 includes changes at many levels of the system,
  20. with repercussions in the libraries and program interfaces.
  21. This document summarizes the changes and describes how
  22. existing programs must be modified to run in the new release.
  23. It is not exhaustive, of course; for further detail about any of the
  24. topics refer to the manual pages, as always.
  25. </P>
  26. <P>
  27. Programmers new to Plan 9 may find valuable tidbits here, but the
  28. real audience for this paper is those with a need to update applications
  29. and servers written in C for earlier releases of the Plan 9 operating system.
  30. </P>
  31. <H4>9P, NAMELEN, and strings
  32. </H4>
  33. <P>
  34. The underlying file service protocol for Plan 9, 9P, retains its basic form
  35. but has had a number of adjustments to deal with longer file names and error strings,
  36. new authentication mechanisms, and to make it more efficient at
  37. evaluating file names.
  38. The change to file names affects a number of system interfaces;
  39. because file name elements are no longer of fixed size, they can
  40. no longer be stored as arrays.
  41. </P>
  42. <P>
  43. 9P used to be a fixed-format protocol with
  44. <TT>NAMELEN</TT>-sized
  45. byte arrays representing file name elements.
  46. Now, it is a variable-format protocol, as described in
  47. <A href="/magic/man2html/5/intro"><I>intro</I>(5),
  48. </A>in which strings are represented by a count followed by that many bytes.
  49. Thus, the string
  50. <TT>ken</TT>
  51. would previously have occupied 28
  52. (<TT>NAMELEN</TT>)
  53. bytes in the message; now it occupies 5: a two-byte count followed by the three bytes of
  54. <TT>ken</TT>
  55. and no terminal zero.
  56. (And of course, a name could now be much longer.)
  57. A similar format change has been made to
  58. <TT>stat</TT>
  59. buffers: they are no longer
  60. <TT>DIRLEN</TT>
  61. bytes long but instead have variable size prefixed by a two-byte count.
  62. And in fact the entire 9P message syntax has changed: every message
  63. now begins with a message length field that makes it trivial to break the
  64. string into messages without parsing them, so
  65. <TT>aux/fcall</TT>
  66. is gone.
  67. A new library entry point,
  68. <TT>read9pmsg</TT>,
  69. makes it easy for user-level servers to break the client data stream into 9P messages.
  70. All servers should switch from using
  71. <TT>read</TT>
  72. (or the now gone
  73. <TT>getS)</TT>
  74. to using
  75. <TT>read9pmsg</TT>.
  76. </P>
  77. <P>
  78. This change to 9P affects the way strings are handled by the kernel and throughout
  79. the system.
  80. The consequences are primarily that fixed-size arrays have been replaced
  81. by pointers and counts in a variety of system interfaces.
  82. Most programs will need at least some adjustment to the new style.
  83. In summary:
  84. <TT>NAMELEN</TT>
  85. is gone, except as a vestige in the authentication libraries, where it has been
  86. rechristened
  87. <TT>ANAMELEN</TT>.
  88. <TT>DIRLEN</TT>
  89. and
  90. <TT>ERRLEN</TT>
  91. are also gone.
  92. All programs that mention
  93. these constants
  94. will need to be fixed.
  95. </P>
  96. <P>
  97. The simplest place to see this change is in the
  98. <TT>errstr</TT>
  99. system call, which no longer assumes a buffer of length
  100. <TT>ERRLEN</TT>
  101. but now requires a byte-count argument:
  102. <DL><DT><DD><TT><PRE>
  103. char buf[...];
  104. errstr(buf, sizeof buf);
  105. </PRE></TT></DL>
  106. The buffer can be any size you like.
  107. For convenience, the kernel stores error strings internally as 256-byte arrays,
  108. so if you like &#173; but it's not required &#173; you can use the defined constant
  109. <TT>ERRMAX=</TT>256
  110. as a good buffer size.
  111. Unlike the old
  112. <TT>ERRLEN</TT>
  113. (which had value 64),
  114. <TT>ERRMAX</TT>
  115. is advisory, not mandatory, and is not part of the 9P specification.
  116. </P>
  117. <P>
  118. With names, stat buffers, and directories, there isn't even an echo of a fixed-size array any more.
  119. </P>
  120. <H4>Directories and wait messages
  121. </H4>
  122. <P>
  123. With strings now variable-length, a number of system calls needed to change:
  124. <TT>errstr</TT>,
  125. <TT>stat</TT>,
  126. <TT>fstat</TT>,
  127. <TT>wstat</TT>,
  128. <TT>fwstat</TT>,
  129. and
  130. <TT>wait</TT>
  131. are all affected, as is
  132. <TT>read</TT>
  133. when applied to directories.
  134. </P>
  135. <P>
  136. As far as directories are concerned, most programs don't use the system calls
  137. directly anyway, since they operate on the machine-independent form, but
  138. instead call the machine-dependent
  139. <TT>Dir</TT>
  140. routines
  141. <TT>dirstat</TT>,
  142. <TT>dirread</TT>,
  143. etc.
  144. These used to fill user-provided fixed-size buffers; now they return objects allocated
  145. by
  146. <TT>malloc</TT>
  147. (which must therefore be freed after use).
  148. To `stat' a file:
  149. <DL><DT><DD><TT><PRE>
  150. Dir *d;
  151. d = dirstat(filename);
  152. if(d == nil){
  153. fprint(2, "can't stat %s: %r\n", filename);
  154. exits("stat");
  155. }
  156. use(d);
  157. free(d);
  158. </PRE></TT></DL>
  159. A common new bug is to forget to free a
  160. <TT>Dir</TT>
  161. returned by
  162. <TT>dirstat</TT>.
  163. </P>
  164. <P>
  165. <TT>Dirfstat</TT>
  166. and
  167. <TT>Dirfwstat</TT>
  168. work pretty much as before, but changes to 9P make
  169. it possible to exercise finer-grained control on what fields
  170. of the
  171. <TT>Dir</TT>
  172. are to be changed; see
  173. <A href="/magic/man2html/2/stat"><I>stat</I>(2)
  174. </A>and
  175. <A href="/magic/man2html/5/stat"><I>stat</I>(5)
  176. </A>for details.
  177. </P>
  178. <P>
  179. Reading a directory works in a similar way to
  180. <TT>dirstat</TT>,
  181. with
  182. <TT>dirread</TT>
  183. allocating and filling in an array of
  184. <TT>Dir</TT>
  185. structures.
  186. The return value is the number of elements of the array.
  187. The arguments to
  188. <TT>dirread</TT>
  189. now include a pointer to a
  190. <TT>Dir*</TT>
  191. to be filled in with the address of the allocated array:
  192. <DL><DT><DD><TT><PRE>
  193. Dir *d;
  194. int i, n;
  195. while((n = dirread(fd, &amp;d)) &gt; 0){
  196. for(i=0; i&lt;n; i++)
  197. use(&amp;d[i]);
  198. free(d);
  199. }
  200. </PRE></TT></DL>
  201. A new library function,
  202. <TT>dirreadall</TT>,
  203. has the same form as
  204. <TT>dirread</TT>
  205. but returns the entire directory in one call:
  206. <DL><DT><DD><TT><PRE>
  207. n = dirreadall(fd, &amp;d)
  208. for(i=0; i&lt;n; i++)
  209. use(&amp;d[i]);
  210. free(d);
  211. </PRE></TT></DL>
  212. If your program insists on using the underlying
  213. <TT>stat</TT>
  214. system call or its relatives, or wants to operate directly on the
  215. machine-independent format returned by
  216. <TT>stat</TT>
  217. or
  218. <TT>read</TT>,
  219. it will need to be modified.
  220. Such programs are rare enough that we'll not discuss them here beyond referring to
  221. the man page
  222. <A href="/magic/man2html/2/stat"><I>stat</I>(2)
  223. </A>for details.
  224. Be aware, though, that it used to be possible to regard the buffer returned by
  225. <TT>stat</TT>
  226. as a byte array that began with the zero-terminated
  227. name of the file; this is no longer true.
  228. With very rare exceptions, programs that call
  229. <TT>stat</TT>
  230. would be better recast to use the
  231. <TT>dir</TT>
  232. routines or, if their goal is just to test the existence of a file,
  233. <TT>access</TT>.
  234. </P>
  235. <P>
  236. Similar changes have affected the
  237. <TT>wait</TT>
  238. system call. In fact,
  239. <TT>wait</TT>
  240. is no longer a system call but a library routine that calls the new
  241. <TT>await</TT>
  242. system call and returns a newly allocated machine-dependent
  243. <TT>Waitmsg</TT>
  244. structure:
  245. <DL><DT><DD><TT><PRE>
  246. Waitmsg *w;
  247. w = wait();
  248. if(w == nil)
  249. error("wait: %r");
  250. print("pid is %d; exit string %s\n", w-&gt;pid, w-&gt;msg);
  251. free(w);
  252. </PRE></TT></DL>
  253. The exit string
  254. <TT>w-&gt;msg</TT>
  255. may be empty but it will never be a nil pointer.
  256. Again, don't forget to free the structure returned by
  257. <TT>wait</TT>.
  258. If all you need is the pid, you can call
  259. <TT>waitpid</TT>,
  260. which reports just the pid and doesn't return an allocated structure:
  261. <DL><DT><DD><TT><PRE>
  262. int pid;
  263. pid = waitpid();
  264. if(pid &lt; 0)
  265. error("wait: %r");
  266. print("pid is %d\n", pid);
  267. </PRE></TT></DL>
  268. </P>
  269. <H4>Quoted strings and tokenize
  270. </H4>
  271. <P>
  272. <TT>Wait</TT>
  273. gives us a good opportunity to describe how the system copes with all this
  274. free-format data.
  275. Consider the text returned by the
  276. <TT>await</TT>
  277. system call, which includes a set of integers (pids and times) and a string (the exit status).
  278. This information is formatted free-form; here is the statement in the kernel that
  279. generates the message:
  280. <DL><DT><DD><TT><PRE>
  281. n = snprint(a, n, "%d %lud %lud %lud %q",
  282. wq-&gt;w.pid,
  283. wq-&gt;w.time[TUser], wq-&gt;w.time[TSys], wq-&gt;w.time[TReal],
  284. wq-&gt;w.msg);
  285. </PRE></TT></DL>
  286. Note the use of
  287. <TT>%q</TT>
  288. to produce a quoted-string representation of the exit status.
  289. The
  290. <TT>%q</TT>
  291. format is like %s but will wrap
  292. <TT>rc</TT>-style
  293. single quotes around the string if it contains white space or is otherwise ambiguous.
  294. The library routine
  295. <TT>tokenize</TT>
  296. can be used to parse data formatted this way: it splits white-space-separated
  297. fields but understands the
  298. <TT>%q</TT>
  299. quoting conventions.
  300. Here is how the
  301. <TT>wait</TT>
  302. library routine builds its
  303. <TT>Waitmsg</TT>
  304. from the data returned by
  305. <TT>await</TT>:
  306. <DL><DT><DD><TT><PRE>
  307. Waitmsg*
  308. wait(void)
  309. {
  310. int n, l;
  311. char buf[512], *fld[5];
  312. Waitmsg *w;
  313. n = await(buf, sizeof buf-1);
  314. if(n &lt; 0)
  315. return nil;
  316. buf[n] = ' ';
  317. if(tokenize(buf, fld, nelem(fld)) != nelem(fld)){
  318. werrstr("couldn't parse wait message");
  319. return nil;
  320. }
  321. l = strlen(fld[4])+1;
  322. w = malloc(sizeof(Waitmsg)+l);
  323. if(w == nil)
  324. return nil;
  325. w-&gt;pid = atoi(fld[0]);
  326. w-&gt;time[0] = atoi(fld[1]);
  327. w-&gt;time[1] = atoi(fld[2]);
  328. w-&gt;time[2] = atoi(fld[3]);
  329. w-&gt;msg = (char*)&amp;w[1];
  330. memmove(w-&gt;msg, fld[4], l);
  331. return w;
  332. }
  333. </PRE></TT></DL>
  334. </P>
  335. <P>
  336. This style of quoted-string and
  337. <TT>tokenize</TT>
  338. is used all through the system now.
  339. In particular, devices now
  340. <TT>tokenize</TT>
  341. the messages written to their
  342. <TT>ctl</TT>
  343. files, which means that you can send messages that contain white space, by quoting them,
  344. and that you no longer need to worry about whether or not the device accepts a newline.
  345. In other words, you can say
  346. <DL><DT><DD><TT><PRE>
  347. echo message &gt; /dev/xx/ctl
  348. </PRE></TT></DL>
  349. instead of
  350. <TT>echo</TT>
  351. <TT>-n</TT>
  352. because
  353. <TT>tokenize</TT>
  354. treats the newline character as white space and discards it.
  355. </P>
  356. <P>
  357. While we're on the subject of quotes and strings, note that the implementation of
  358. <TT>await</TT>
  359. used
  360. <TT>snprint</TT>
  361. rather than
  362. <TT>sprint</TT>.
  363. We now deprecate
  364. <TT>sprint</TT>
  365. because it has no protection against buffer overflow.
  366. We prefer
  367. <TT>snprint</TT>
  368. or
  369. <TT>seprint</TT>,
  370. to constrain the output.
  371. The
  372. <TT>%q</TT>
  373. format is cleverer than most in this regard:
  374. if the string is too long to be represented in full,
  375. <TT>%q</TT>
  376. is smart enough to produce a truncated but correctly quoted
  377. string within the available space.
  378. </P>
  379. <H4>Mount
  380. </H4>
  381. <P>
  382. Although strings in 9P are now variable-length and not zero-terminated,
  383. this has little direct effect in most of the system interfaces.
  384. File and user names are still zero-terminated strings as always;
  385. the kernel does the work of translating them as necessary for
  386. transport.
  387. And of course, they are now free to be as long as you might want;
  388. the only hard limit is that their length must be represented in 16 bits.
  389. </P>
  390. <P>
  391. One example where this matters is that the file system specification in the
  392. <TT>mount</TT>
  393. system call can now be much longer.
  394. Programs like
  395. <TT>rio</TT>
  396. that used the specification string in creative ways were limited by the
  397. <TT>NAMELEN</TT>
  398. restriction; now they can use the string more freely.
  399. <TT>Rio</TT>
  400. now accepts a simple but less cryptic specification language for the window
  401. to be created by the
  402. <TT>mount</TT>
  403. call, e.g.:
  404. <DL><DT><DD><TT><PRE>
  405. % mount $wsys /mnt/wsys 'new -dx 250 -dy 250 -pid 1234'
  406. </PRE></TT></DL>
  407. In the old system, this sort of control was impossible through the
  408. <TT>mount</TT>
  409. interface.
  410. </P>
  411. <P>
  412. While we're on the subject of
  413. <TT>mount</TT>,
  414. note that with the new security architecture
  415. (see
  416. <A href="/magic/man2html/4/factotum"><I>factotum</I>(4)),
  417. </A>9P has moved its authentication outside the protocol proper.
  418. (For a full description of this change to 9P, see
  419. <A href="/magic/man2html/2/fauth"><I>fauth</I>(2),
  420. </A><A href="/magic/man2html/5/attach"><I>attach</I>(5),
  421. </A>and the paper
  422. <I>Security in Plan 9.)</I>
  423. The most explicit effect of this change is that
  424. <TT>mount</TT>
  425. now takes another argument,
  426. <TT>afd</TT>,
  427. a file descriptor for the
  428. authentication file through which the authentication will be made.
  429. For most user-level file servers, which do not require authentication, it is
  430. sufficient to provide
  431. <TT>-1</TT>
  432. as the value of
  433. <TT>afd:</TT>
  434. <DL><DT><DD><TT><PRE>
  435. if(mount(fd, -1, "/mnt/wsys", MREPL,
  436. "new -dx 250 -dy 250 -pid 1234") &lt; 0)
  437. error("mount failed: %r");
  438. </PRE></TT></DL>
  439. To connect to servers that require authentication, use the new
  440. <TT>fauth</TT>
  441. system call or the reimplemented
  442. <TT>amount</TT>
  443. (authenticated mount) library call.
  444. In fact, since
  445. <TT>amount</TT>
  446. handles both authenticating and non-authenticating servers, it is often
  447. easiest just to replace calls to
  448. <TT>mount</TT>
  449. by calls to
  450. <TT>amount</TT>;
  451. see
  452. <A href="/magic/man2html/2/auth"><I>auth</I>(2)
  453. </A>for details.
  454. </P>
  455. <H4>Print
  456. </H4>
  457. <P>
  458. The C library has been heavily reworked in places.
  459. Besides the changes mentioned above, it
  460. now has a much more complete set of routines for handling
  461. <TT>Rune</TT>
  462. strings (that is, zero-terminated arrays of 16-bit character values).
  463. The most sweeping changes, however, are in the way formatted I/O is performed.
  464. </P>
  465. <P>
  466. The
  467. <TT>print</TT>
  468. routine and all its relatives have been reimplemented to offer a number
  469. of improvements:
  470. </P>
  471. <DL COMPACT>
  472. <DT>(1)<DD>
  473. Better buffer management, including the provision of an internal flush
  474. routine, makes it unnecessary to provide large buffers.
  475. For example,
  476. <TT>print</TT>
  477. uses a much smaller buffer now (reducing stack load) while simultaneously
  478. removing the need to truncate the output string if it doesn't fit in the buffer.
  479. <DT>(2)<DD>
  480. Global variables have been eliminated so no locking is necessary.
  481. <DT>(3)<DD>
  482. The combination of (1) and (2) means that the standard implementation of
  483. <TT>print</TT>
  484. now works fine in threaded programs, and
  485. <TT>threadprint</TT>
  486. is gone.
  487. <DT>(4)<DD>
  488. The new routine
  489. <TT>smprint</TT>
  490. prints into, and returns, storage allocated on demand by
  491. <TT>malloc</TT>.
  492. <DT>(5)<DD>
  493. It is now possible to print into a
  494. <TT>Rune</TT>
  495. string; for instance,
  496. <TT>runesmprint</TT>
  497. is the
  498. <TT>Rune</TT>
  499. analog of
  500. <TT>smprint</TT>.
  501. <DT>(6)<DD>
  502. There is improved support for custom
  503. print verbs and custom output routines such as error handlers.
  504. The routine
  505. <TT>doprint</TT>
  506. is gone, but
  507. <TT>vseprint</TT>
  508. can always be used instead.
  509. However, the new routines
  510. <TT>fmtfdinit</TT>,
  511. <TT>fmtstrinit</TT>,
  512. <TT>fmtprint</TT>,
  513. and friends
  514. are often a better replacement.
  515. The details are too long for exposition here;
  516. <A href="/magic/man2html/2/fmtinstall"><I>fmtinstall</I>(2)
  517. </A>explains the new interface and provides examples.
  518. <DT>(7)<DD>
  519. Two new format flags, space and comma, close somewhat the gap between
  520. Plan 9 and ANSI C.
  521. </dl>
  522. <P>
  523. Despite these changes, most programs will be unaffected;
  524. <TT>print</TT>
  525. is still
  526. <TT>print</TT>.
  527. Don't forget, though, that
  528. you should eliminate calls to
  529. <TT>sprint</TT>
  530. and use the
  531. <TT>%q</TT>
  532. format when appropriate.
  533. </P>
  534. <H4>Binary compatibility
  535. </H4>
  536. <P>
  537. The discussion so far has been about changes at the source level.
  538. Existing binaries will probably run without change in the new
  539. environment, since the kernel provides backward-compatible
  540. system calls for
  541. <TT>errstr</TT>,
  542. <TT>stat</TT>,
  543. <TT>wait</TT>,
  544. etc.
  545. The only exceptions are programs that do either a
  546. <TT>mount</TT>
  547. system call, because of the security changes and because
  548. the file descriptor in
  549. <TT>mount</TT>
  550. must point to a new 9P connection; or a
  551. <TT>read</TT>
  552. system call on a directory, since the returned data will
  553. be in the new format.
  554. A moment's reflection will discover that this means old
  555. user-level file servers will need to be fixed to run on the new system.
  556. </P>
  557. <H4>File servers
  558. </H4>
  559. <P>
  560. A full description of what user-level servers must do to provide service with
  561. the new 9P is beyond the scope of this paper.
  562. Your best source of information is section 5 of the manual,
  563. combined with study of a few examples.
  564. <TT>/sys/src/cmd/ramfs.c</TT>
  565. is a simple example; it has a counterpart
  566. <TT>/sys/src/lib9p/ramfs.c</TT>
  567. that implements the same service using the new
  568. <A href="/magic/man2html/2/9p"><I>9p</I>(2)
  569. </A>library.
  570. </P>
  571. <P>
  572. That said, it's worth summarizing what to watch for when converting a file server.
  573. The
  574. <TT>session</TT>
  575. message is gone, and there is a now a
  576. <TT>version</TT>
  577. message that is exchanged at the start of a connection to establish
  578. the version of the protocol to use (there's only one at the moment, identified by
  579. the string
  580. <TT>9P2000</TT>)
  581. and what the maximum message size will be.
  582. This negotiation makes it easier to handle 9P encapsulation, such as with
  583. <TT>exportfs</TT>,
  584. and also permits larger message sizes when appropriate.
  585. </P>
  586. <P>
  587. If your server wants to authenticate, it will need to implement an authentication file
  588. and implement the
  589. <TT>auth</TT>
  590. message; otherwise it should return a helpful error string to the
  591. <TT>Tauth</TT>
  592. request to signal that authentication is not required.
  593. </P>
  594. <P>
  595. The handling of
  596. <TT>stat</TT>
  597. and directory reads will require some changes but they should not be fundamental.
  598. Be aware that seeking on directories is forbidden, so it is fine if you disregard the
  599. file offset when implementing directory reads; this makes it a little easier to handle
  600. the variable-length entries.
  601. You should still never return a partial directory entry; if the I/O count is too small
  602. to return even one entry, you should return two bytes containing the byte count
  603. required to represent the next entry in the directory.
  604. User code can use this value to formulate a retry if it desires.
  605. See the
  606. DIAGNOSTICS section of
  607. <A href="/magic/man2html/2/stat"><I>stat</I>(2)
  608. </A>for a description of this process.
  609. </P>
  610. <P>
  611. The trickiest part of updating a file server is that the
  612. <TT>clone</TT>
  613. and
  614. <TT>walk</TT>
  615. messages have been merged into a single message, a sort of `clone-multiwalk'.
  616. The new message, still called
  617. <TT>walk</TT>,
  618. proposes a sequence of file name elements to be evaluated using a possibly
  619. cloned fid.
  620. The return message contains the qids of the files reached by
  621. walking to the sequential elements.
  622. If all the elements can be walked, the fid will be cloned if requested.
  623. If a non-zero number of elements are requested, but none
  624. can be walked, an error should be returned.
  625. If only some can be walked, the fid is not cloned, the original fid is left
  626. where it was, and the returned
  627. <TT>Rwalk</TT>
  628. message should contain the partial list of successfully reached qids.
  629. See
  630. <A href="/magic/man2html/5/walk"><I>walk</I>(5)
  631. </A>for a full description.
  632. </P>
  633. <br>&#32;<br>
  634. <A href=http://www.lucent.com/copyright.html>
  635. Copyright</A> &#169; 2002 Lucent Technologies Inc. All rights reserved.
  636. </body></html>