home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume30 / rc / part01 < prev    next >
Encoding:
Text File  |  1992-05-29  |  59.7 KB  |  2,110 lines

  1. Newsgroups: comp.sources.misc
  2. From: byron@archone.tamu.edu (Byron Rakitzis)
  3. Subject:  v30i024:  rc - A Plan 9 shell reimplementation, v1.4, Part01/07
  4. Message-ID: <csm-v30i024=rc.221510@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 0d082dcbc4b44b76c6cd8f0e6bd87559
  6. Date: Sat, 30 May 1992 03:15:47 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: byron@archone.tamu.edu (Byron Rakitzis)
  10. Posting-number: Volume 30, Issue 24
  11. Archive-name: rc/part01
  12. Environment: UNIX
  13. Supersedes: rc: Volume 23, Issue 61-66
  14.  
  15. This is version 1.4 of the rc shell.  rc is a command interpreter 
  16. and programming language similar to  sh(1).   It is  based on the 
  17. AT&T  plan 9 shell of the same  name.  The shell offers a  C-like 
  18. syntax (much more so than the C shell), and a  powerful mechanism 
  19. for manipulating variables. It is reasonably small and reasonably
  20. fast, especially when compared to contemporary shells. Its use is
  21. intended to be interactive, but the  language  lends  itself well 
  22. to scripts.  Please see the README and CHANGES files for more
  23. information on the changes made in this version.
  24.  
  25. Byron Rakitzis
  26. --------------
  27. #! /bin/sh
  28. # This is a shell archive.  Remove anything before this line, then feed it
  29. # into a shell via "sh file" or similar.  To overwrite existing files,
  30. # type "sh file -c".
  31. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  32. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  33. # Contents:  README builtins.c history plan9.ps.b
  34. # Wrapped by kent@sparky on Fri May 29 20:55:22 1992
  35. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  36. echo If this archive is complete, you will see the following message:
  37. echo '          "shar: End of archive 1 (of 7)."'
  38. if test -f 'README' -a "${1}" != "-c" ; then 
  39.   echo shar: Will not clobber existing file \"'README'\"
  40. else
  41.   echo shar: Extracting \"'README'\" \(4327 characters\)
  42.   sed "s/^X//" >'README' <<'END_OF_FILE'
  43. XThis is release 1.4 of rc.
  44. X
  45. XRead COPYRIGHT for copying information. All files are
  46. X
  47. XCopyright 1991, Byron Rakitzis.
  48. X
  49. XCOMPILING
  50. X
  51. Xrc was written in portable ANSI C. If you don't have an ANSI compiler
  52. Xlike gcc or something close (e.g., sgi's cc) read further down on
  53. Xhow to convert rc's source to old C.
  54. X
  55. XPlease read the Makefile, and copy config.h-dist to config.h and
  56. Xexamine the parameters in there; they let you customize rc to your
  57. XUnix. For example, some Unices support /dev/fd, or some have FIFOs.
  58. XIf you do not perform this step then the Makefile will automatically
  59. Xcopy config.h-dist to config.h and proceed assuming that everything
  60. Xis ok. Note that config.h-dist supplies default parameter configurations
  61. Xfor SunOS, NeXT-OS, Irix, Ultrix and some others. Finally, if you're
  62. Xhaving trouble you may want to look at proto.h and see if everything
  63. Xin there jibes with your system.
  64. X
  65. XAfter you've built rc, you may wish to run it through a test script
  66. Xto see that everything is ok. Type "make trip" for this. This will
  67. Xproduce some output, and end with "trip is complete". If the trip
  68. Xends with "trip took a wrong turn..." then drop me a line.
  69. X
  70. XTo compile the history program, go into the history subdirectory
  71. Xand type "make". This will create a binary called "history". However,
  72. Xin order for it to work as advertised it must be installed into
  73. Xyour bin as four files named -, --, -p and --p. (these can be soft
  74. Xor hard links to the same file)
  75. X
  76. Xrc may also be linked with either GNU readline (10,000+ lines of
  77. Xcode!) or a supplied readline-like system by Simmule Turner (1,000+
  78. Xlines of code). See the Makefile on how to do this.
  79. X
  80. XBUGS
  81. X
  82. XSend bug reports to byron@archone.tamu.edu. If a core dump is
  83. Xgenerated, sending me a backtrace will help me out a great deal. You
  84. Xcan get a backtrace like this:
  85. X
  86. X    ; gdb rc core
  87. X    (gdb) where
  88. X    <<<BACKTRACE INFO>>>
  89. X    (gdb)
  90. X
  91. XAlso, always report the machine, compiler and OS used to make rc.  It's
  92. Xpossible I may have access to a machine of that type, in which case it
  93. Xbecomes much easier for me to track the bug down.
  94. X
  95. XIf you are using gcc, please make sure that you have a recent version of
  96. Xthe compiler (1.39 and up) before you send me a note; I have found that
  97. Xolder versions of gcc choke over rc and generate bad code on several
  98. Xarchitectures. (this is especially relevant for the the MIPS architecture)
  99. X
  100. XFEEPING CREATURISM
  101. X
  102. XSee the end of the man page, under "INCOMPATABILITIES" for (known?)
  103. Xdifferences from the "real" rc. Most of these changes were necessary
  104. Xto get rc to work in a reasonable fashion on a real (i.e., commercial,
  105. Xnon-Labs) UNIX system; a few were changes motivated by concern
  106. Xabout some inadequacies in the original design.
  107. X
  108. XOLD C
  109. X
  110. XIf you need to convert rc's source into K&R C, you need to run the
  111. Xsource through a filter called "unproto", posted in comp.sources.misc.
  112. XA sample "cpp" shell script that I used to run unproto under SunOS
  113. Xis supplied with rc.
  114. X
  115. XCREDITS
  116. X
  117. XThis shell was written by me, Byron Rakitzis, but kudos go to Paul
  118. XHaahr for letting me know what a shell should do and for contributing
  119. Xcertain bits and pieces to rc (notably the limits code, print.c,
  120. Xmost of which.c and the backquote redirection code), and to Hugh
  121. XRedelmeier for running rc through his fussy ANSI compiler and
  122. Xthereby provoking interesting discussions about portability, and
  123. Xalso for providing many valuable suggestions for improving rc's
  124. Xcode in general. Finally, many thanks go to David Sanderson, for
  125. Xreworking the man page to format well with troff, and for providing
  126. Xmany suggestions both for rc and its man page.
  127. X
  128. XThanks to Boyd Roberts for the original history.c, and to Hugh
  129. Xagain for re-working parts of that code.
  130. X
  131. XOf course, without Tom Duff's design of the original rc, I could
  132. Xnot have written this shell (though I probably would have written
  133. X*a* shell). Almost of all of the features, with minor exceptions,
  134. Xhave been implemented as described in the Unix v10 manuals. Hats
  135. Xoff to td for designing a C-like, minimal but very useful shell.
  136. X
  137. XTom Duff has kindly given permission for the paper he wrote for
  138. XUKUUG to be distributed with this version of rc (called "plan9.ps"
  139. Xin the same ftp directory as the shell). Please read this paper
  140. Xbearing in mind that it describes a program that was written at
  141. XAT&T and that the version of rc presented here differs in some
  142. Xrespects.
  143. END_OF_FILE
  144.   if test 4327 -ne `wc -c <'README'`; then
  145.     echo shar: \"'README'\" unpacked with wrong size!
  146.   fi
  147.   # end of 'README'
  148. fi
  149. if test -f 'builtins.c' -a "${1}" != "-c" ; then 
  150.   echo shar: Will not clobber existing file \"'builtins.c'\"
  151. else
  152.   echo shar: Extracting \"'builtins.c'\" \(11075 characters\)
  153.   sed "s/^X//" >'builtins.c' <<'END_OF_FILE'
  154. X/* builtins.c: the collection of rc's builtin commands */
  155. X
  156. X/*
  157. X    NOTE: rc's builtins do not call "rc_error" because they are
  158. X    commands, and rc errors usually arise from syntax errors. e.g.,
  159. X    you probably don't want interpretation of a shell script to stop
  160. X    because of a bad umask.
  161. X*/
  162. X
  163. X#include <sys/ioctl.h>
  164. X#include <setjmp.h>
  165. X#include <errno.h>
  166. X#include "rc.h"
  167. X#include "jbwrap.h"
  168. X#ifndef NOLIMITS
  169. X#include <sys/time.h>
  170. X#include <sys/resource.h>
  171. X#endif
  172. X#include "addon.h"
  173. X
  174. Xextern int umask(int);
  175. X
  176. Xstatic void b_break(char **), b_cd(char **), b_eval(char **), b_exit(char **),
  177. X    b_newpgrp(char **), b_return(char **), b_shift(char **), b_umask(char **),
  178. X    b_wait(char **), b_whatis(char **);
  179. X
  180. X#ifndef NOLIMITS
  181. Xstatic void b_limit(char **);
  182. X#endif
  183. X#ifndef NOECHO
  184. Xstatic void b_echo(char **);
  185. X#endif
  186. X
  187. Xstatic struct {
  188. X    builtin_t *p;
  189. X    char *name;
  190. X} builtins[] = {
  191. X    { b_break,    "break" },
  192. X    { b_builtin,    "builtin" },
  193. X    { b_cd,        "cd" },
  194. X#ifndef NOECHO
  195. X    { b_echo,    "echo" },
  196. X#endif
  197. X    { b_eval,    "eval" },
  198. X    { b_exec,    "exec" },
  199. X    { b_exit,    "exit" },
  200. X#ifndef NOLIMITS
  201. X    { b_limit,    "limit" },
  202. X#endif
  203. X    { b_newpgrp,    "newpgrp" },
  204. X    { b_return,    "return" },
  205. X    { b_shift,    "shift" },
  206. X    { b_umask,    "umask" },
  207. X    { b_wait,    "wait" },
  208. X    { b_whatis,    "whatis" },
  209. X    { b_dot,    "." },
  210. X    ADDONS
  211. X};
  212. X
  213. Xextern builtin_t *isbuiltin(char *s) {
  214. X    int i;
  215. X    for (i = 0; i < arraysize(builtins); i++)
  216. X        if (streq(builtins[i].name, s))
  217. X            return builtins[i].p;
  218. X    return NULL;
  219. X}
  220. X
  221. X/* funcall() is the wrapper used to invoke shell functions. pushes $*, and "return" returns here. */
  222. X
  223. Xextern void funcall(char **av) {
  224. X    Jbwrap j;
  225. X    Estack e1, e2;
  226. X    Edata jreturn, star;
  227. X    if (setjmp(j.j))
  228. X        return;
  229. X    starassign(*av, av+1, TRUE);
  230. X    jreturn.jb = &j;
  231. X    star.name = "*";
  232. X    except(eReturn, jreturn, &e1);
  233. X    except(eVarstack, star, &e2);
  234. X    walk(treecpy(fnlookup(*av), nalloc), TRUE);
  235. X    varrm("*", TRUE);
  236. X    unexcept(); /* eVarstack */
  237. X    unexcept(); /* eReturn */
  238. X}
  239. X
  240. Xstatic void arg_count(char *name) {
  241. X    fprint(2, "too many arguments to %s\n", name);
  242. X    set(FALSE);
  243. X}
  244. X
  245. Xstatic void badnum(char *num) {
  246. X    fprint(2, "%s is a bad number\n", num);
  247. X    set(FALSE);
  248. X}
  249. X
  250. X/* a dummy command. (exec() performs "exec" simply by not forking) */
  251. X
  252. Xextern void b_exec(char **av) {
  253. X}
  254. X
  255. X#ifndef NOECHO
  256. X/* echo -n omits a newline. echo -- -n echos '-n' */
  257. X
  258. Xstatic void b_echo(char **av) {
  259. X    char *format = "%A\n";
  260. X    if (*++av != NULL) {
  261. X        if (streq(*av, "-n"))
  262. X                    format = "%A", av++;
  263. X        else if (streq(*av, "--"))
  264. X            av++;
  265. X    }
  266. X    fprint(1, format, av);
  267. X    set(TRUE);
  268. X}
  269. X#endif
  270. X
  271. X/* cd. traverse $cdpath if the directory given is not an absolute pathname */
  272. X
  273. Xstatic void b_cd(char **av) {
  274. X    List *s, nil;
  275. X    char *path = NULL;
  276. X    SIZE_T t, pathlen = 0;
  277. X    if (*++av == NULL) {
  278. X        s = varlookup("home");
  279. X        *av = (s == NULL) ? "/" : s->w;
  280. X    } else if (av[1] != NULL) {
  281. X        arg_count("cd");
  282. X        return;
  283. X    }
  284. X    if (isabsolute(*av) || streq(*av, ".") || streq(*av, "..")) { /* absolute pathname? */
  285. X        if (chdir(*av) < 0) {
  286. X            set(FALSE);
  287. X            uerror(*av);
  288. X        } else
  289. X            set(TRUE);
  290. X    } else {
  291. X        s = varlookup("cdpath");
  292. X        if (s == NULL) {
  293. X            s = &nil;
  294. X            nil.w = "";
  295. X            nil.n = NULL;
  296. X        }
  297. X        do {
  298. X            if (s != &nil && *s->w != '\0') {
  299. X                t = strlen(*av) + strlen(s->w) + 2;
  300. X                if (t > pathlen)
  301. X                    path = nalloc(pathlen = t);
  302. X                strcpy(path, s->w);
  303. X                if (!streq(s->w, "/")) /* "//" is special to POSIX */
  304. X                    strcat(path, "/");
  305. X                strcat(path, *av);
  306. X            } else {
  307. X                pathlen = 0;
  308. X                path = *av;
  309. X            }
  310. X            if (chdir(path) >= 0) {
  311. X                set(TRUE);
  312. X                if (interactive && *s->w != '\0' && !streq(s->w, "."))
  313. X                    fprint(1, "%s\n", path);
  314. X                return;
  315. X            }
  316. X            s = s->n;
  317. X        } while (s != NULL);
  318. X        fprint(2, "couldn't cd to %s\n", *av);
  319. X        set(FALSE);
  320. X    }
  321. X}
  322. X
  323. Xstatic void b_umask(char **av) {
  324. X    int i;
  325. X    if (*++av == NULL) {
  326. X        set(TRUE);
  327. X        i = umask(0);
  328. X        umask(i);
  329. X        fprint(1, "0%o\n", i);
  330. X    } else if (av[1] == NULL) {
  331. X        i = o2u(*av);
  332. X        if ((unsigned int) i > 0777) {
  333. X            fprint(2, "bad umask\n");
  334. X            set(FALSE);
  335. X        } else {
  336. X            umask(i);
  337. X            set(TRUE);
  338. X        }
  339. X    } else {
  340. X        arg_count("umask");
  341. X        return;
  342. X    }
  343. X}
  344. X
  345. Xstatic void b_exit(char **av) {
  346. X    if (*++av != NULL)
  347. X        ssetstatus(av);
  348. X    rc_exit(getstatus());
  349. X}
  350. X
  351. X/* raise a "return" exception, i.e., return from a function. if an integer argument is present, set $status to it */
  352. X
  353. Xstatic void b_return(char **av) {
  354. X    if (*++av != NULL)
  355. X        ssetstatus(av);
  356. X    rc_raise(eReturn);
  357. X}
  358. X
  359. X/* raise a "break" exception for breaking out of for and while loops */
  360. X
  361. Xstatic void b_break(char **av) {
  362. X    if (av[1] != NULL) {
  363. X        arg_count("break");
  364. X        return;
  365. X    }
  366. X    rc_raise(eBreak);
  367. X}
  368. X
  369. X/* shift $* n places (default 1) */
  370. X
  371. Xstatic void b_shift(char **av) {
  372. X    int shift = (av[1] == NULL ? 1 : a2u(av[1]));
  373. X    List *s, *dollarzero;
  374. X    if (av[1] != NULL && av[2] != NULL) {
  375. X        arg_count("shift");
  376. X        return;
  377. X    }
  378. X    if (shift < 0) {
  379. X        badnum(av[1]);
  380. X        return;
  381. X    }
  382. X    s = varlookup("*")->n;
  383. X    dollarzero = varlookup("0");
  384. X    while (s != NULL && shift != 0) {
  385. X        s = s->n;
  386. X        --shift;
  387. X    }
  388. X    if (s == NULL && shift != 0) {
  389. X        fprint(2, "cannot shift\n");
  390. X        set(FALSE);
  391. X    } else {
  392. X        varassign("*", append(dollarzero, s), FALSE);
  393. X        set(TRUE);
  394. X    }
  395. X}
  396. X
  397. X/* dud function */
  398. X
  399. Xextern void b_builtin(char **av) {
  400. X}
  401. X
  402. X/* wait for a given process, or all outstanding processes */
  403. X
  404. Xstatic void b_wait(char **av) {
  405. X    int stat, pid;
  406. X    if (av[1] == NULL) {
  407. X        waitforall();
  408. X        return;
  409. X    }
  410. X    if (av[2] != NULL) {
  411. X        arg_count("wait");
  412. X        return;
  413. X    }
  414. X    if ((pid = a2u(av[1])) < 0) {
  415. X        badnum(av[1]);
  416. X        return;
  417. X    }
  418. X    if (rc_wait4(pid, &stat, FALSE) > 0)
  419. X        setstatus(pid, stat);
  420. X    else
  421. X        set(FALSE);
  422. X    SIGCHK;
  423. X}
  424. X
  425. X/*
  426. X   whatis without arguments prints all variables and functions. Otherwise, check to see if a name
  427. X   is defined as a variable, function or pathname.
  428. X*/
  429. X
  430. Xstatic void b_whatis(char **av) {
  431. X    bool f, found;
  432. X    bool ess = FALSE;
  433. X    int i, ac, c;
  434. X    List *s;
  435. X    Node *n;
  436. X    char *e;
  437. X    for (rc_optind = ac = 0; av[ac] != NULL; ac++)
  438. X        ; /* count the arguments for getopt */
  439. X    while ((c = rc_getopt(ac, av, "s")) == 's')
  440. X        ess = TRUE;
  441. X    if (c != -1) {
  442. X        set(FALSE);
  443. X        return;
  444. X    }
  445. X    av += rc_optind;
  446. X    if (*av == NULL && !ess) {
  447. X        whatare_all_vars();
  448. X        set(TRUE);
  449. X        return;
  450. X    }
  451. X    if (ess)
  452. X        whatare_all_signals();
  453. X    found = TRUE;
  454. X    for (i = 0; av[i] != NULL; i++) {
  455. X        f = FALSE;
  456. X        errno = ENOENT;
  457. X        if ((s = varlookup(av[i])) != NULL) {
  458. X            f = TRUE;
  459. X            prettyprint_var(1, av[i], s);
  460. X        }
  461. X        if ((n = fnlookup(av[i])) != NULL) {
  462. X            f = TRUE;
  463. X            prettyprint_fn(1, av[i], n);
  464. X        } else if (isbuiltin(av[i]) != NULL) {
  465. X            f = TRUE;
  466. X            fprint(1, "builtin %s\n", av[i]);
  467. X        } else if ((e = which(av[i], FALSE)) != NULL) {
  468. X            f = TRUE;
  469. X            fprint(1, "%s\n", e);
  470. X        }
  471. X        if (!f) {
  472. X            found = FALSE;
  473. X            if (errno != ENOENT)
  474. X                uerror(av[i]);
  475. X            else
  476. X                fprint(2, "%s not found\n", av[i]);
  477. X        }
  478. X    }
  479. X    set(found);
  480. X}
  481. X
  482. X/* push a string to be eval'ed onto the input stack. evaluate it */
  483. X
  484. Xstatic void b_eval(char **av) {
  485. X    bool i = interactive;
  486. X    if (av[1] == NULL)
  487. X        return;
  488. X    interactive = FALSE;
  489. X    pushstring(av + 1, i); /* don't reset line numbers on noninteractive eval */
  490. X    doit(TRUE);
  491. X    interactive = i;
  492. X}
  493. X
  494. X/*
  495. X   push a file to be interpreted onto the input stack. with "-i" treat this as an interactive
  496. X   input source.
  497. X*/
  498. X
  499. Xextern void b_dot(char **av) {
  500. X    int fd;
  501. X    bool old_i = interactive, i = FALSE;
  502. X    Estack e;
  503. X    Edata star;
  504. X    av++;
  505. X    if (*av == NULL)
  506. X        return;
  507. X    if (streq(*av, "-i")) {
  508. X        av++;
  509. X        i = TRUE;
  510. X    }
  511. X    if (dasheye) { /* rc -i file has to do the right thing. reset the dasheye state to FALSE, though. */
  512. X        dasheye = FALSE;
  513. X        i = TRUE;
  514. X    }
  515. X    if (*av == NULL)
  516. X        return;
  517. X    fd = rc_open(*av, rFrom);
  518. X    if (fd < 0) {
  519. X        if (rcrc) /* on rc -l, don't flag nonexistence of .rcrc */
  520. X            rcrc = FALSE;
  521. X        else {
  522. X            uerror(*av);
  523. X            set(FALSE);
  524. X        }
  525. X        return;
  526. X    }
  527. X    rcrc = FALSE;
  528. X    starassign(*av, av+1, TRUE);
  529. X    pushfd(fd);
  530. X    interactive = i;
  531. X    star.name = "*";
  532. X    except(eVarstack, star, &e);
  533. X    doit(TRUE);
  534. X    varrm("*", TRUE);
  535. X    unexcept(); /* eVarstack */
  536. X    interactive = old_i;
  537. X}
  538. X
  539. X/* put rc into a new pgrp. Used on the NeXT where the Terminal program is broken (sigh) */
  540. X
  541. Xstatic void b_newpgrp(char **av) {
  542. X    if (av[1] != NULL) {
  543. X        arg_count("newpgrp");
  544. X        return;
  545. X    }
  546. X    setpgrp(rc_pid, rc_pid);
  547. X#ifdef TIOCSPGRP
  548. X    ioctl(2, TIOCSPGRP, &rc_pid);
  549. X#endif
  550. X}
  551. X
  552. X/* Berkeley limit support was cleaned up by Paul Haahr. */
  553. X
  554. X#ifndef NOLIMITS
  555. Xtypedef struct Suffix Suffix;
  556. Xstruct Suffix {
  557. X    const Suffix *next;
  558. X    long amount;
  559. X    char *name;
  560. X};
  561. X
  562. Xstatic const Suffix
  563. X    kbsuf = { NULL, 1024, "k" },
  564. X    mbsuf = { &kbsuf, 1024*1024, "m" },
  565. X    gbsuf = { &mbsuf, 1024*1024*1024, "g" },
  566. X    stsuf = { NULL, 1, "s" },
  567. X    mtsuf = { &stsuf, 60, "m" },
  568. X    htsuf = { &mtsuf, 60*60, "h" };
  569. X#define    SIZESUF &gbsuf
  570. X#define    TIMESUF &htsuf
  571. X#define    NOSUF ((Suffix *) NULL)  /* for RLIMIT_NOFILE on SunOS 4.1 */
  572. X
  573. Xtypedef struct {
  574. X    char *name;
  575. X    int flag;
  576. X    const Suffix *suffix;
  577. X} Limit;
  578. Xstatic const Limit limits[] = {
  579. X    { "cputime",        RLIMIT_CPU,    TIMESUF },
  580. X    { "filesize",        RLIMIT_FSIZE,    SIZESUF },
  581. X    { "datasize",        RLIMIT_DATA,    SIZESUF },
  582. X    { "stacksize",        RLIMIT_STACK,    SIZESUF },
  583. X    { "coredumpsize",    RLIMIT_CORE,    SIZESUF },
  584. X#ifdef RLIMIT_RSS /* SysVr4 does not have this */
  585. X    { "memoryuse",        RLIMIT_RSS,    SIZESUF },
  586. X#endif
  587. X#ifdef RLIMIT_VMEM /* instead, they have this! */
  588. X    { "vmemory",        RLIMIT_VMEM,    SIZESUF },
  589. X#endif
  590. X#ifdef RLIMIT_NOFILE  /* SunOS 4.1 adds a limit on file descriptors */
  591. X    { "descriptors",    RLIMIT_NOFILE,    NOSUF },
  592. X#endif
  593. X    { NULL, 0, NULL }
  594. X};
  595. X
  596. Xextern int getrlimit(int, struct rlimit *);
  597. Xextern int setrlimit(int, struct rlimit *);
  598. X
  599. Xstatic void printlimit(const Limit *limit, bool hard) {
  600. X    struct rlimit rlim;
  601. X    long lim;
  602. X    getrlimit(limit->flag, &rlim);
  603. X    if (hard)
  604. X        lim = rlim.rlim_max;
  605. X    else
  606. X        lim = rlim.rlim_cur;
  607. X    if (lim == RLIM_INFINITY)
  608. X        fprint(1, "%s \tunlimited\n", limit->name);
  609. X    else {
  610. X        const Suffix *suf;
  611. X        for (suf = limit->suffix; suf != NULL; suf = suf->next)
  612. X            if (lim % suf->amount == 0 && (lim != 0 || suf->amount > 1)) {
  613. X                lim /= suf->amount;
  614. X                break;
  615. X            }
  616. X        fprint(1, "%s \t%d%s\n", limit->name, lim, (suf == NULL || lim == 0) ? "" : suf->name);
  617. X    }
  618. X}
  619. X
  620. Xstatic long parselimit(const Limit *limit, char *s) {
  621. X    char *t;
  622. X    int len = strlen(s);
  623. X    long lim = 1;
  624. X    const Suffix *suf = limit->suffix;
  625. X    if (streq(s, "unlimited"))
  626. X        return RLIM_INFINITY;
  627. X    if (suf == TIMESUF && (t = strchr(s, ':')) != NULL) {
  628. X        *t++ = '\0';
  629. X        lim = 60 * a2u(s) + a2u(t);
  630. X    } else {
  631. X        for (; suf != NULL; suf = suf->next)
  632. X            if (streq(suf->name, s + len - strlen(suf->name))) {
  633. X                s[len - strlen(suf->name)] = '\0';
  634. X                lim *= suf->amount;
  635. X                break;
  636. X            }
  637. X        lim *= a2u(s);
  638. X    }
  639. X    return lim;
  640. X}
  641. X
  642. Xstatic void b_limit(char **av) {
  643. X    const Limit *lp = limits;
  644. X    bool hard = FALSE;
  645. X    if (*++av != NULL && streq(*av, "-h")) {
  646. X        av++;
  647. X        hard = TRUE;
  648. X    }
  649. X    if (*av == NULL) {
  650. X        for (; lp->name != NULL; lp++)
  651. X            printlimit(lp, hard);
  652. X        return;
  653. X    }
  654. X    for (;; lp++) {
  655. X        if (lp->name == NULL) {
  656. X            fprint(2, "no such limit\n");
  657. X            set(FALSE);
  658. X            return;
  659. X        }
  660. X        if (streq(*av, lp->name))
  661. X            break;
  662. X    }
  663. X    if (*++av == NULL)
  664. X        printlimit(lp, hard);
  665. X    else {
  666. X        struct rlimit rlim;
  667. X        long pl;
  668. X        getrlimit(lp->flag, &rlim);
  669. X        if ((pl = parselimit(lp, *av)) < 0) {
  670. X            fprint(2, "bad limit\n");
  671. X            set(FALSE);
  672. X            return;
  673. X        }
  674. X        if (hard)
  675. X            rlim.rlim_max = pl;
  676. X        else
  677. X            rlim.rlim_cur = pl;
  678. X        if (setrlimit(lp->flag, &rlim) == -1) {
  679. X            uerror("setrlimit");
  680. X            set(FALSE);
  681. X        } else
  682. X            set(TRUE);
  683. X    }
  684. X}
  685. X#endif
  686. END_OF_FILE
  687.   if test 11075 -ne `wc -c <'builtins.c'`; then
  688.     echo shar: \"'builtins.c'\" unpacked with wrong size!
  689.   fi
  690.   # end of 'builtins.c'
  691. fi
  692. if test ! -d 'history' ; then
  693.     echo shar: Creating directory \"'history'\"
  694.     mkdir 'history'
  695. fi
  696. if test -f 'plan9.ps.b' -a "${1}" != "-c" ; then 
  697.   echo shar: Will not clobber existing file \"'plan9.ps.b'\"
  698. else
  699.   echo shar: Extracting \"'plan9.ps.b'\" \(40176 characters\)
  700.   sed "s/^X//" >'plan9.ps.b' <<'END_OF_FILE'
  701. X(})1008 1976 w
  702. X10 R f
  703. X(defines)720 2156 w
  704. X10 CW f
  705. X(g)1033 2156 w
  706. X10 I f
  707. X(pattern)1118 2156 w
  708. X10 R f
  709. X(to look for occurrences of)4 1030 1 1432 2156 t
  710. X10 I f
  711. X(pattern)2487 2156 w
  712. X10 R f
  713. X(in all program source files in the current directory.)8 2015 1 2801 2156 t
  714. X(Function definitions are deleted by writing)5 1707 1 720 2312 t
  715. X9 CW f
  716. X(fn)1008 2482 w
  717. X9 I f
  718. X(name)1170 2482 w
  719. X10 R f
  720. X(with no function body.)3 911 1 720 2662 t
  721. X10 B f
  722. X( execution)1 430(17. Command)1 625 2 720 2902 t
  723. X10 R f
  724. X( very little about what)4 897(Up to now we've said)4 892 2 720 3058 t
  725. X10 I f
  726. X(rc)2539 3058 w
  727. X10 R f
  728. X( the command name)3 822( If)1 121(does to execute a simple command.)5 1445 3 2652 3058 t
  729. X(is the name of a function defined using)7 1570 1 720 3178 t
  730. X10 CW f
  731. X(fn)2317 3178 w
  732. X10 R f
  733. X( if it is the name of a built-)8 1082( Otherwise,)1 487(, the function is executed.)4 1034 3 2437 3178 t
  734. X(in command, the built-in is executed directly by)7 1964 1 720 3298 t
  735. X10 I f
  736. X(rc)2716 3298 w
  737. X10 R f
  738. X( if the name contains a)5 936(. Otherwise,)1 517 2 2799 3298 t
  739. X10 CW f
  740. X(/)4284 3298 w
  741. X10 R f
  742. X(, it is taken to be)5 696 1 4344 3298 t
  743. X(the name of a binary program and is executed using)9 2155 1 720 3418 t
  744. X10 I f
  745. X(exec)2910 3418 w
  746. X10 R f
  747. X( the name contains no)4 907(\(2\). If)1 267 2 3086 3418 t
  748. X10 CW f
  749. X(/)4294 3418 w
  750. X10 R f
  751. X(, then directories)2 686 1 4354 3418 t
  752. X(mentioned in the variable)3 1018 1 720 3538 t
  753. X10 CW f
  754. X($path)1763 3538 w
  755. X10 R f
  756. X(are searched until an executable file is found.)7 1806 1 2088 3538 t
  757. X10 B f
  758. X( commands)1 486(18. Built-in)1 504 2 720 3778 t
  759. X10 R f
  760. X( executed internally by)3 924(Several commands are)2 909 2 720 3934 t
  761. X10 I f
  762. X(rc)2582 3934 w
  763. X10 R f
  764. X(because they are difficult or impossible to implement oth-)8 2346 1 2694 3934 t
  765. X(erwise.)720 4054 w
  766. X10 CW f
  767. X(. [-i])1 360 1 720 4210 t
  768. X10 I f
  769. X(file ...)1 228 1 1140 4210 t
  770. X10 R f
  771. X(Execute commands from)2 1008 1 970 4330 t
  772. X10 I f
  773. X(file)2008 4330 w
  774. X10 R f
  775. X(.)2136 4330 w
  776. X10 CW f
  777. X($*)2216 4330 w
  778. X10 R f
  779. X( reminder of the argument list follow-)6 1545(is set for the duration to the)6 1129 2 2366 4330 t
  780. X(ing)970 4450 w
  781. X10 I f
  782. X(file)1125 4450 w
  783. X10 R f
  784. X(.)1253 4450 w
  785. X10 CW f
  786. X($path)1330 4450 w
  787. X10 R f
  788. X(is used to search for)4 806 1 1657 4450 t
  789. X10 I f
  790. X(file)2490 4450 w
  791. X10 R f
  792. X(. Option)1 354 1 2618 4450 t
  793. X10 CW f
  794. X(-i)2998 4450 w
  795. X10 R f
  796. X(indicates interactive input)2 1034 1 3144 4450 t
  797. X10 S f
  798. X(-)4204 4450 w
  799. X10 R f
  800. X(a prompt \(found in)3 755 1 4285 4450 t
  801. X10 CW f
  802. X($prompt)970 4570 w
  803. X10 R f
  804. X(\) is printed before each command is read.)7 1651 1 1390 4570 t
  805. X10 CW f
  806. X(builtin)720 4726 w
  807. X10 I f
  808. X(command ...)1 488 1 1200 4726 t
  809. X10 R f
  810. X(Execute)970 4846 w
  811. X10 I f
  812. X(command)1316 4846 w
  813. X10 R f
  814. X(as usual except that any function named)6 1597 1 1729 4846 t
  815. X10 I f
  816. X(command)3351 4846 w
  817. X10 R f
  818. X( example,)1 388( For)1 189(is ignored.)1 422 3 3764 4846 t
  819. X9 CW f
  820. X(fn cd{)1 324 1 1258 5016 t
  821. X(builtin cd $* && pwd)4 1080 1 1474 5126 t
  822. X(})1258 5236 w
  823. X10 R f
  824. X(defines a replacement for the)4 1177 1 970 5416 t
  825. X10 CW f
  826. X(cd)2177 5416 w
  827. X10 R f
  828. X(built-in \(see below\) that announces the full name of the new direc-)11 2713 1 2327 5416 t
  829. X(tory.)970 5536 w
  830. X10 CW f
  831. X(cd [)1 240 1 720 5692 t
  832. X10 I f
  833. X(dir)960 5692 w
  834. X10 CW f
  835. X(])1077 5692 w
  836. X10 R f
  837. X(Change the current directory to)4 1255 1 970 5812 t
  838. X10 I f
  839. X(dir)2252 5812 w
  840. X10 R f
  841. X( default argument is)3 802(. The)1 232 2 2369 5812 t
  842. X10 CW f
  843. X($home)3430 5812 w
  844. X10 R f
  845. X(.)3730 5812 w
  846. X10 CW f
  847. X($cdpath)3808 5812 w
  848. X10 R f
  849. X(is a list of places in)5 784 1 4256 5812 t
  850. X(which to search for)3 767 1 970 5932 t
  851. X10 I f
  852. X(dir)1762 5932 w
  853. X10 R f
  854. X(.)1879 5932 w
  855. X10 CW f
  856. X(eval [)1 360 1 720 6088 t
  857. X10 I f
  858. X(arg ...)1 239 1 1080 6088 t
  859. X10 CW f
  860. X(])1319 6088 w
  861. X10 R f
  862. X(The arguments are catenated separated by spaces into a string, read as input to)13 3159 1 970 6208 t
  863. X10 I f
  864. X(rc)4158 6208 w
  865. X10 R f
  866. X( For)1 193(, and executed.)2 606 2 4241 6208 t
  867. X(example,)970 6328 w
  868. X9 CW f
  869. X(x='$y')1258 6498 w
  870. X(y=Doody)1258 6608 w
  871. X(eval echo Howdy, $x)3 1026 1 1258 6718 t
  872. X10 R f
  873. X(would echo)1 463 1 970 6898 t
  874. X9 CW f
  875. X(Howdy, Doody)1 648 1 1258 7068 t
  876. X10 R f
  877. X(since the arguments of)3 901 1 970 7248 t
  878. X10 CW f
  879. X(eval)1896 7248 w
  880. X10 R f
  881. X(would be)1 369 1 2161 7248 t
  882. Xcleartomark
  883. Xshowpage
  884. Xsaveobj restore
  885. X%%EndPage: 6 6
  886. X%%Page: 7 7
  887. X/saveobj save def
  888. Xmark
  889. X7 pagesetup
  890. X10 R f
  891. X(- 7 -)2 166 1 2797 480 t
  892. X9 CW f
  893. X(echo Howdy, $y)2 756 1 1258 830 t
  894. X10 R f
  895. X(after substituting for)2 816 1 970 1010 t
  896. X10 CW f
  897. X($x)1811 1010 w
  898. X10 R f
  899. X(.)1931 1010 w
  900. X10 CW f
  901. X(shift [)1 420 1 720 1166 t
  902. X10 I f
  903. X(n)1140 1166 w
  904. X10 CW f
  905. X(])1190 1166 w
  906. X10 R f
  907. X(Delete the first)2 593 1 970 1286 t
  908. X10 I f
  909. X(n)1588 1286 w
  910. X10 R f
  911. X(\(default 1\) elements of)3 906 1 1663 1286 t
  912. X10 CW f
  913. X($*)2594 1286 w
  914. X10 R f
  915. X(.)2714 1286 w
  916. X10 CW f
  917. X(wait [)1 360 1 720 1442 t
  918. X10 I f
  919. X(pid)1080 1442 w
  920. X10 CW f
  921. X(])1208 1442 w
  922. X10 R f
  923. X( given)1 263(Wait for the process with the)5 1231 2 970 1562 t
  924. X10 I f
  925. X(pid)2505 1562 w
  926. X10 R f
  927. X( no)1 141( If)1 132(to exit.)1 294 3 2674 1562 t
  928. X10 I f
  929. X(pid)3282 1562 w
  930. X10 R f
  931. X(is given, all outstanding processes are)5 1589 1 3451 1562 t
  932. X(waited for.)1 432 1 970 1682 t
  933. X10 CW f
  934. X(whatis)720 1838 w
  935. X10 I f
  936. X(name ...)1 316 1 1140 1838 t
  937. X10 R f
  938. X( each)1 209(Print the value of)3 694 2 970 1958 t
  939. X10 I f
  940. X(name)1900 1958 w
  941. X10 R f
  942. X(in a form suitable for input to)6 1189 1 2143 1958 t
  943. X10 I f
  944. X(rc)3359 1958 w
  945. X10 R f
  946. X( output is an assignment to a vari-)7 1366(. The)1 232 2 3442 1958 t
  947. X(able, the definition of a function, a call to)8 1709 1 970 2078 t
  948. X10 CW f
  949. X(builtin)2711 2078 w
  950. X10 R f
  951. X( the path name of a)5 792(for a built-in command, or)4 1085 2 3163 2078 t
  952. X( example,)1 388( For)1 189(binary program.)1 643 3 970 2198 t
  953. X9 CW f
  954. X(whatis path g cd who)4 1080 1 1258 2368 t
  955. X10 R f
  956. X(might print)1 448 1 970 2548 t
  957. X9 CW f
  958. X(path=\(. /bin /usr/bin\))2 1188 1 1258 2718 t
  959. X(fn g {gre -e $1 *.[hycl]})5 1350 1 1258 2828 t
  960. X(builtin cd)1 540 1 1258 2938 t
  961. X(/bin/who)1258 3048 w
  962. X10 CW f
  963. X(\304)720 3264 w
  964. X10 I f
  965. X(subject pattern ...)2 697 1 840 3264 t
  966. X10 R f
  967. X(The)970 3384 w
  968. X10 I f
  969. X(subject)1150 3384 w
  970. X10 R f
  971. X(is matched against each)3 945 1 1458 3384 t
  972. X10 I f
  973. X(pattern)2428 3384 w
  974. X10 R f
  975. X( a match,)2 365( On)1 172(in turn.)1 289 3 2742 3384 t
  976. X10 CW f
  977. X($status)3594 3384 w
  978. X10 R f
  979. X( Otherwise,)1 486(is set to true.)3 514 2 4040 3384 t
  980. X(it is set to)3 396 1 970 3504 t
  981. X10 CW f
  982. X('no match')1 602 1 1393 3504 t
  983. X10 R f
  984. X( The)1 207( are the same as for filename matching.)7 1582(. Patterns)1 399 3 1995 3504 t
  985. X10 I f
  986. X(patterns)4210 3504 w
  987. X10 R f
  988. X(are not sub-)2 475 1 4565 3504 t
  989. X(jected to filename replacement before the)5 1698 1 970 3624 t
  990. X10 CW f
  991. X(\304)2702 3624 w
  992. X10 R f
  993. X(command is executed, so they need not be enclosed in)9 2244 1 2796 3624 t
  994. X(quotation marks, unless of course, a literal match for)8 2102 1 970 3744 t
  995. X10 CW f
  996. X(* [)1 145 1 3097 3744 t
  997. X10 R f
  998. X(or)3267 3744 w
  999. X10 CW f
  1000. X(?)3375 3744 w
  1001. X10 R f
  1002. X( example)1 363( For)1 189(is required.)1 449 3 3485 3744 t
  1003. X9 CW f
  1004. X(\304 $1 ?)2 324 1 1258 3914 t
  1005. X10 R f
  1006. X(matches any single character, whereas)4 1525 1 970 4094 t
  1007. X9 CW f
  1008. X(\304 $1 '?')2 432 1 1258 4264 t
  1009. X10 R f
  1010. X(only matches a literal question mark.)5 1476 1 970 4444 t
  1011. X10 B f
  1012. X( I/O Redirection)2 694(19. Advanced)1 603 2 720 4684 t
  1013. X10 I f
  1014. X(Rc)720 4840 w
  1015. X10 R f
  1016. X( of file descriptors other than 0 and 1 \(standard input and output\) by specifying the file)16 3472(allows redirection)1 718 2 850 4840 t
  1017. X(descriptor in square brackets)3 1144 1 720 4960 t
  1018. X10 CW f
  1019. X([ ])1 180 1 1889 4960 t
  1020. X10 R f
  1021. X(after the)1 329 1 2094 4960 t
  1022. X10 CW f
  1023. X(<)2448 4960 w
  1024. X10 R f
  1025. X(or)2533 4960 w
  1026. X10 CW f
  1027. X(>)2641 4960 w
  1028. X10 R f
  1029. X( example,)1 388(. For)1 214 2 2701 4960 t
  1030. X9 CW f
  1031. X(cc junk.c >[2]junk.diag)2 1242 1 1008 5130 t
  1032. X10 R f
  1033. X(saves the compiler's diagnostics in)4 1393 1 720 5310 t
  1034. X10 CW f
  1035. X(junk.diag)2138 5310 w
  1036. X10 R f
  1037. X(.)2678 5310 w
  1038. X( replaced by a copy, in the sense of)8 1471(File descriptors may be)3 959 2 720 5466 t
  1039. X10 I f
  1040. X(dup)3184 5466 w
  1041. X10 R f
  1042. X(\(2\), of an already-open file by typing, for)7 1706 1 3334 5466 t
  1043. X(example)720 5586 w
  1044. X9 CW f
  1045. X(cc junk.c >[2=1])2 864 1 1008 5756 t
  1046. X10 R f
  1047. X( in conjunction with other)4 1061( is more useful)3 609( It)1 117(This replaces file descriptor 2 with a copy of file descriptor 1.)11 2533 4 720 5936 t
  1048. X(redirections, like this)2 841 1 720 6056 t
  1049. X9 CW f
  1050. X(cc junk.c >junk.out >[2=1])3 1404 1 1008 6226 t
  1051. X10 R f
  1052. X( descriptor 1 to)3 629(Redirections are evaluated from left to right, so this redirects file)10 2667 2 720 6406 t
  1053. X10 CW f
  1054. X(junk.out)4050 6406 w
  1055. X10 R f
  1056. X(, then points)2 510 1 4530 6406 t
  1057. X( contrast,)1 366( By)1 167(file descriptor 2 at the same file.)6 1289 3 720 6526 t
  1058. X9 CW f
  1059. X(cc junk.c >[2=1] >junk.out)3 1404 1 1008 6696 t
  1060. X10 R f
  1061. X( \(presumably the terminal\), and then directs file)7 2000(Redirects file descriptor 2 to a copy of file descriptor 1)10 2320 2 720 6876 t
  1062. X( the first case, standard and diagnostic output will be intermixed in)11 2686( In)1 135( at a file.)3 355(descriptor 1)1 477 4 720 6996 t
  1063. X10 CW f
  1064. X(junk.out)4400 6996 w
  1065. X10 R f
  1066. X(. In)1 160 1 4880 6996 t
  1067. X(the second, diagnostic output will appear on the terminal, and standard output will be sent to the file.)17 4024 1 720 7116 t
  1068. X( For)1 211( using the duplication notation with an empty right-hand side.)9 2664(File descriptors may be closed by)5 1445 3 720 7272 t
  1069. Xcleartomark
  1070. Xshowpage
  1071. Xsaveobj restore
  1072. X%%EndPage: 7 7
  1073. X%%Page: 8 8
  1074. X/saveobj save def
  1075. Xmark
  1076. X8 pagesetup
  1077. X10 R f
  1078. X(- 8 -)2 166 1 2797 480 t
  1079. X(example,)720 840 w
  1080. X9 CW f
  1081. X(cc junk.c >[2=])2 810 1 1008 1010 t
  1082. X10 R f
  1083. X(will discard diagnostics from the compilation.)5 1838 1 720 1190 t
  1084. X(Arbitrary file descriptors may be sent through a pipe by typing, for example)12 3031 1 720 1346 t
  1085. X9 CW f
  1086. X(cc junk.c |[2] grep -v '\303$')5 1458 1 1008 1516 t
  1087. X10 R f
  1088. X( that the output of)4 779( Note)1 261( the C compiler's output.)4 1065(This deletes those ever-so-annoying blank lines from)6 2215 4 720 1696 t
  1089. X10 CW f
  1090. X(grep)720 1816 w
  1091. X10 R f
  1092. X(still appears on file descriptor 1.)5 1287 1 985 1816 t
  1093. X( a pipe to some file descriptor other than zero.)9 1871(Very occasionally you may wish to connect the input side of)10 2449 2 720 1972 t
  1094. X(The notation)1 508 1 720 2092 t
  1095. X9 CW f
  1096. X(cmd1 |[5=19] cmd2)2 918 1 1008 2262 t
  1097. X10 R f
  1098. X(creates a pipeline with)3 895 1 720 2442 t
  1099. X10 CW f
  1100. X(cmd1)1640 2442 w
  1101. X10 R f
  1102. X('s file descriptor 5 connected through a pipe to)8 1863 1 1880 2442 t
  1103. X10 CW f
  1104. X(cmd2)3768 2442 w
  1105. X10 R f
  1106. X('s file descriptor 19.)3 804 1 4008 2442 t
  1107. X10 B f
  1108. X( documents)1 486(20. Here)1 385 2 720 2682 t
  1109. X10 I f
  1110. X(Rc)720 2838 w
  1111. X10 R f
  1112. X( to commands, as in this)5 982(procedures may include data, called ``here documents'', to be provided as input)11 3206 2 852 2838 t
  1113. X(version of the)2 549 1 720 2958 t
  1114. X10 I f
  1115. X(tel)1294 2958 w
  1116. X10 R f
  1117. X(command)1419 2958 w
  1118. X9 CW f
  1119. X(for\(i\) grep $i <<!)3 972 1 1008 3128 t
  1120. X(...)1008 3238 w
  1121. X(nls 2T-402 2912)2 810 1 1008 3348 t
  1122. X(norman 2C-514 2842)2 972 1 1008 3458 t
  1123. X(pjw 2T-502 7214)2 810 1 1008 3568 t
  1124. X(...)1008 3678 w
  1125. X(!)1008 3788 w
  1126. X10 R f
  1127. X(A here document is introduced by the redirection symbol)8 2288 1 720 3968 t
  1128. X10 CW f
  1129. X(<<)3034 3968 w
  1130. X10 R f
  1131. X( by an arbitrary eof marker \()6 1141(, followed)1 406 2 3154 3968 t
  1132. X10 CW f
  1133. X(!)4701 3968 w
  1134. X10 R f
  1135. X(in the)1 227 1 4813 3968 t
  1136. X( to a line containing only the eof marker are saved in a tempo-)13 2507( following the command, up)4 1142(example\). Lines)1 671 3 720 4088 t
  1137. X(rary file that it connected to the command's standard input when it is run.)13 2935 1 720 4208 t
  1138. X10 I f
  1139. X(Rc)720 4364 w
  1140. X10 R f
  1141. X( following)1 414( The)1 205(does variable substitution in here documents.)5 1804 3 850 4364 t
  1142. X10 I f
  1143. X(subst)3298 4364 w
  1144. X10 R f
  1145. X(command:)3529 4364 w
  1146. X9 CW f
  1147. X(ed $3 <<EOF)2 594 1 1008 4534 t
  1148. X(g/$1/s//$2/g)1008 4644 w
  1149. X(w)1008 4754 w
  1150. X(EOF)1008 4864 w
  1151. X10 R f
  1152. X( of)1 113(changes all occurrences)2 954 2 720 5044 t
  1153. X10 CW f
  1154. X($1)1817 5044 w
  1155. X10 R f
  1156. X(to)1967 5044 w
  1157. X10 CW f
  1158. X($2)2075 5044 w
  1159. X10 R f
  1160. X(in file)1 241 1 2225 5044 t
  1161. X10 CW f
  1162. X($3)2496 5044 w
  1163. X10 R f
  1164. X( include a literal)3 661(. To)1 191 2 2616 5044 t
  1165. X10 CW f
  1166. X($)3498 5044 w
  1167. X10 R f
  1168. X(in a here document, type)4 1004 1 3588 5044 t
  1169. X10 CW f
  1170. X($$)4622 5044 w
  1171. X10 R f
  1172. X( the)1 152(. If)1 146 2 4742 5044 t
  1173. X(name of a variable is followed immediately by)7 1861 1 720 5164 t
  1174. X10 CW f
  1175. X(\303)2606 5164 w
  1176. X10 R f
  1177. X(, the caret is deleted.)4 820 1 2666 5164 t
  1178. X( by enclosing the eof marker following)6 1643(Variable substitution can be entirely suppressed)5 1981 2 720 5320 t
  1179. X10 CW f
  1180. X(<<)4384 5320 w
  1181. X10 R f
  1182. X(in quotation)1 496 1 4544 5320 t
  1183. X(marks.)720 5440 w
  1184. X(Here documents may be provided on file descriptors other than 0 by typing, for example)14 3530 1 720 5596 t
  1185. X9 CW f
  1186. X(cmd <<[4]End)1 648 1 1008 5766 t
  1187. X(...)1008 5876 w
  1188. X(End)1008 5986 w
  1189. X10 B f
  1190. X(21. Signals)1 482 1 720 6286 t
  1191. X10 I f
  1192. X(Rc)720 6442 w
  1193. X10 R f
  1194. X( function with the name of)5 1067( A)1 124( an interrupt is received from the terminal.)7 1705(scripts normally terminate when)3 1293 4 851 6442 t
  1195. X( the usual way, but called when)6 1268(a signal, in lower case, is defined in)7 1449 2 720 6562 t
  1196. X10 I f
  1197. X(rc)3464 6562 w
  1198. X10 R f
  1199. X( of inter-)2 353( Signals)1 347(receives the signal.)2 766 3 3574 6562 t
  1200. X(est are:)1 285 1 720 6682 t
  1201. X10 CW f
  1202. X(sighup)720 6838 w
  1203. X10 R f
  1204. X( controlling teletype has disconnected from)5 1728(Hangup. The)1 546 2 970 6958 t
  1205. X10 I f
  1206. X(rc)3269 6958 w
  1207. X10 R f
  1208. X(.)3352 6958 w
  1209. X10 CW f
  1210. X(sigint)720 7114 w
  1211. X10 R f
  1212. X(The interrupt character \(usually ASCII del\) was typed on the controlling terminal.)11 3272 1 970 7234 t
  1213. Xcleartomark
  1214. Xshowpage
  1215. Xsaveobj restore
  1216. X%%EndPage: 8 8
  1217. X%%Page: 9 9
  1218. X/saveobj save def
  1219. Xmark
  1220. X9 pagesetup
  1221. X10 R f
  1222. X(- 9 -)2 166 1 2797 480 t
  1223. X10 CW f
  1224. X(sigquit)720 840 w
  1225. X10 R f
  1226. X(The quit character \(usually ASCII fs, ctrl-\\\) was typed on the controlling terminal.)12 3278 1 970 960 t
  1227. X10 CW f
  1228. X(sigterm)720 1116 w
  1229. X10 R f
  1230. X(This signal is normally sent by)5 1231 1 970 1236 t
  1231. X10 I f
  1232. X(kill)2226 1236 w
  1233. X10 R f
  1234. X(\(1\).)2354 1236 w
  1235. X10 CW f
  1236. X(sigexit)720 1392 w
  1237. X10 R f
  1238. X(An artificial signal sent when)4 1176 1 970 1512 t
  1239. X10 I f
  1240. X(rc)2171 1512 w
  1241. X10 R f
  1242. X(is about to exit.)3 617 1 2279 1512 t
  1243. X(As an example,)2 618 1 720 1668 t
  1244. X9 CW f
  1245. X(fn sigint{)1 540 1 1008 1838 t
  1246. X(rm /tmp/junk)1 648 1 1224 1948 t
  1247. X(exit)1224 2058 w
  1248. X(})1008 2168 w
  1249. X10 R f
  1250. X(sets a trap for the keyboard interrupt that removes a temporary file before exiting.)13 3259 1 720 2348 t
  1251. X( routine is set to)4 651(Signals will be ignored if the signal)6 1434 2 720 2504 t
  1252. X10 CW f
  1253. X({})2833 2504 w
  1254. X10 R f
  1255. X( revert to their default behavior when their)7 1714(. Signals)1 373 2 2953 2504 t
  1256. X(handlers' definitions are deleted.)3 1308 1 720 2624 t
  1257. X10 B f
  1258. X(22. Environment)1 742 1 720 2864 t
  1259. X10 R f
  1260. X( Plan 9, the environ-)4 817( On)1 173( is a list of name-value pairs made available to executing binaries.)11 2645(The environment)1 685 4 720 3020 t
  1261. X( in a file system named)5 929(ment is stored)2 565 2 720 3140 t
  1262. X10 CW f
  1263. X(#e)2240 3140 w
  1264. X10 R f
  1265. X(, normally mounted on)3 914 1 2360 3140 t
  1266. X10 CW f
  1267. X(/env)3300 3140 w
  1268. X10 R f
  1269. X( value of each variable is stored)6 1269(. The)1 231 2 3540 3140 t
  1270. X( is not quite as horrendous as it sounds,)8 1577( \(This)1 262(in a separate file, with components terminated by ASCII nuls.)9 2481 3 720 3260 t
  1271. X( contents of)2 482( The)1 213( access is involved.\))3 828(the file system is maintained entirely in core, so no disk or network)12 2797 4 720 3380 t
  1272. X10 CW f
  1273. X(/env)720 3500 w
  1274. X10 R f
  1275. X(are shared on a per-process group basis)6 1579 1 987 3500 t
  1276. X10 S f
  1277. X(-)2593 3500 w
  1278. X10 R f
  1279. X( process group is created it effectively attaches)7 1885(when a new)2 480 2 2675 3500 t
  1280. X10 CW f
  1281. X(/env)720 3620 w
  1282. X10 R f
  1283. X( consequence of this organization is that)6 1603( A)1 122(to a new file system initialized with a copy of the old one.)12 2329 3 986 3620 t
  1284. X(commands can change environment entries and see the changes reflected in)10 3014 1 720 3740 t
  1285. X10 I f
  1286. X(rc)3759 3740 w
  1287. X10 R f
  1288. X(.)3842 3740 w
  1289. X( in the environment, although this could easily)7 1939(There is not currently a way on Plan 9 to place functions)11 2381 2 720 3896 t
  1290. X(done by mounting another instance of)5 1537 1 720 4016 t
  1291. X10 CW f
  1292. X(#e)2287 4016 w
  1293. X10 R f
  1294. X( can be)2 290( problem is that currently there)5 1259( The)1 210(on another directory.)2 844 4 2437 4016 t
  1295. X(only one instance of)3 807 1 720 4136 t
  1296. X10 CW f
  1297. X(#e)1552 4136 w
  1298. X10 R f
  1299. X(per process group.)2 734 1 1697 4136 t
  1300. X10 B f
  1301. X( Variables)1 436(23. Local)1 414 2 720 4376 t
  1302. X10 R f
  1303. X( assignment followed by a com-)5 1289( An)1 174( the duration of a single command.)6 1402(It is often useful to set a variable for)8 1455 4 720 4532 t
  1304. X( example)1 363( For)1 189(mand has this effect.)3 826 3 720 4652 t
  1305. X9 CW f
  1306. X(a=global)1008 4822 w
  1307. X(a=local echo $a)2 810 1 1008 4932 t
  1308. X(echo $a)1 378 1 1008 5042 t
  1309. X10 R f
  1310. X(will print)1 370 1 720 5222 t
  1311. X9 CW f
  1312. X(local)1008 5392 w
  1313. X(global)1008 5502 w
  1314. X10 R f
  1315. X(This works even for compound commands, like)6 1906 1 720 5682 t
  1316. X9 CW f
  1317. X(f=/fairly/long/file/name {)1 1404 1 1008 5852 t
  1318. X({ wc $f; spell $f; diff $f.old $f } |)9 1998 1 1224 5962 t
  1319. X(pr -h 'Facts about '$f | lp -ddp)7 1728 1 1332 6072 t
  1320. X(})1008 6182 w
  1321. X10 B f
  1322. X( \320)1 125(24. Examples)1 592 2 720 6482 t
  1323. X10 I f
  1324. X(cd, pwd)1 311 1 1462 6482 t
  1325. X10 R f
  1326. X(Here is a pair of functions that provide enhanced versions of the standard)12 2933 1 720 6638 t
  1327. X10 CW f
  1328. X(cd)3679 6638 w
  1329. X10 R f
  1330. X(and)3825 6638 w
  1331. X10 CW f
  1332. X(pwd)3996 6638 w
  1333. X10 R f
  1334. X(commands. \(Thanks)1 837 1 4203 6638 t
  1335. X(to Rob Pike for these.\))4 902 1 720 6758 t
  1336. Xcleartomark
  1337. Xshowpage
  1338. Xsaveobj restore
  1339. X%%EndPage: 9 9
  1340. X%%Page: 10 10
  1341. X/saveobj save def
  1342. Xmark
  1343. X10 pagesetup
  1344. X10 R f
  1345. X(- 10 -)2 216 1 2772 480 t
  1346. X9 CW f
  1347. X( default prompt)2 810( #)1 486(ps1='% ')1 432 3 1008 830 t
  1348. X( a tab character)3 864( #)1 432(tab=' ')1 486 3 1008 940 t
  1349. X(fn pbd{)1 378 1 1008 1050 t
  1350. X(/bin/pwd|sed 's;.*/;;')1 1188 1 1116 1160 t
  1351. X(})1008 1270 w
  1352. X(fn cd{)1 324 1 1008 1380 t
  1353. X(builtin cd $1 &&)3 864 1 1116 1490 t
  1354. X(switch\($#*\){)1116 1600 w
  1355. X(case 0)1 324 1 1116 1710 t
  1356. X(dir=$home)1224 1820 w
  1357. X(prompt=\($ps1 $tab\))1 972 1 1224 1930 t
  1358. X(case *)1 324 1 1116 2040 t
  1359. X(switch\($1\))1224 2150 w
  1360. X(case /*)1 378 1 1224 2260 t
  1361. X(dir=$1)1332 2370 w
  1362. X(prompt=\(`{pbd}\303$ps1 $tab\))1 1350 1 1332 2480 t
  1363. X(case */* ..*)2 648 1 1224 2590 t
  1364. X(dir=\(\))1332 2700 w
  1365. X(prompt=\(`{pbd}\303$ps1 $tab\))1 1350 1 1332 2810 t
  1366. X(case *)1 324 1 1224 2920 t
  1367. X(dir=\(\))1332 3030 w
  1368. X(prompt=\($1\303$ps1 $tab\))1 1134 1 1332 3140 t
  1369. X(})1224 3250 w
  1370. X(})1116 3360 w
  1371. X(})1008 3470 w
  1372. X(fn pwd{)1 378 1 1008 3580 t
  1373. X(if\(\304 $#dir 0\))2 702 1 1116 3690 t
  1374. X(dir=`{/bin/pwd})1224 3800 w
  1375. X(echo $dir)1 486 1 1116 3910 t
  1376. X(})1008 4020 w
  1377. X10 R f
  1378. X(Function)720 4200 w
  1379. X10 CW f
  1380. X(pwd)1104 4200 w
  1381. X10 R f
  1382. X(is a version of the standard)5 1088 1 1312 4200 t
  1383. X10 CW f
  1384. X(pwd)2428 4200 w
  1385. X10 R f
  1386. X(that caches its value in variable)5 1270 1 2636 4200 t
  1387. X10 CW f
  1388. X($dir)3935 4200 w
  1389. X10 R f
  1390. X(, because the genuine)3 865 1 4175 4200 t
  1391. X10 CW f
  1392. X(pwd)720 4320 w
  1393. X10 R f
  1394. X(can be quite slow to execute.)5 1153 1 925 4320 t
  1395. X(Function)720 4476 w
  1396. X10 CW f
  1397. X(pbd)1114 4476 w
  1398. X10 R f
  1399. X( Function)1 419(is a helper that prints the last component of a directory name.)11 2589 2 1332 4476 t
  1400. X10 CW f
  1401. X(cd)4378 4476 w
  1402. X10 R f
  1403. X(calls the)1 344 1 4537 4476 t
  1404. X10 CW f
  1405. X(cd)4920 4476 w
  1406. X10 R f
  1407. X( so, it sets)3 404( If)1 119( was successful.)2 646(built-in, and checks that it)4 1057 4 720 4596 t
  1408. X10 CW f
  1409. X($dir)2974 4596 w
  1410. X10 R f
  1411. X(and)3242 4596 w
  1412. X10 CW f
  1413. X($prompt)3414 4596 w
  1414. X10 R f
  1415. X( prompt will include the)4 973(. The)1 233 2 3834 4596 t
  1416. X(last component of the current directory \(except in the home directory, where it will be null\), and)16 3869 1 720 4716 t
  1417. X10 CW f
  1418. X($dir)4616 4716 w
  1419. X10 R f
  1420. X(will)4884 4716 w
  1421. X(be reset either to the correct value or to)8 1562 1 720 4836 t
  1422. X10 CW f
  1423. X(\(\))2307 4836 w
  1424. X10 R f
  1425. X(, so that the)3 461 1 2427 4836 t
  1426. X10 CW f
  1427. X(pwd)2913 4836 w
  1428. X10 R f
  1429. X(function will work correctly.)3 1148 1 3118 4836 t
  1430. X10 B f
  1431. X( \320)1 125(25. Examples)1 592 2 720 5076 t
  1432. X10 I f
  1433. X(man)1462 5076 w
  1434. X10 R f
  1435. X(The)720 5232 w
  1436. X10 I f
  1437. X(man)900 5232 w
  1438. X10 R f
  1439. X( is called, for example, as)5 1017( It)1 111(command prints pages from of the Programmer's Manual.)7 2324 3 1097 5232 t
  1440. X9 CW f
  1441. X(man 3 isatty)2 648 1 1008 5402 t
  1442. X(man rc)1 324 1 1008 5512 t
  1443. X(man -t cat)2 540 1 1008 5622 t
  1444. X10 R f
  1445. X(In the first case, the page for)6 1192 1 720 5802 t
  1446. X10 I f
  1447. X(isatty)1946 5802 w
  1448. X10 R f
  1449. X( second case, the manual page for)6 1403( the)1 156( In)1 142(in section 3 is printed.)4 922 4 2197 5802 t
  1450. X10 I f
  1451. X(rc)4855 5802 w
  1452. X10 R f
  1453. X(is)4973 5802 w
  1454. X( specified, all sections are searched for the page, and it is found in sec-)14 2871( no manual section is)4 864(printed. Since)1 585 3 720 5922 t
  1455. X( the third case, the page for)6 1083( In)1 133(tion 1.)1 256 3 720 6042 t
  1456. X10 I f
  1457. X(cat)2217 6042 w
  1458. X10 R f
  1459. X(is typeset \(the)2 555 1 2364 6042 t
  1460. X10 CW f
  1461. X(-t)2944 6042 w
  1462. X10 R f
  1463. X(option\).)3089 6042 w
  1464. Xcleartomark
  1465. Xshowpage
  1466. Xsaveobj restore
  1467. X%%EndPage: 10 10
  1468. X%%Page: 11 11
  1469. X/saveobj save def
  1470. Xmark
  1471. X11 pagesetup
  1472. X10 R f
  1473. X(- 11 -)2 216 1 2772 480 t
  1474. X9 CW f
  1475. X(cd /n/bowell/usr/man || {)3 1350 1 1008 830 t
  1476. X(echo $0: Manual not on line! >[1=2])6 1890 1 1116 940 t
  1477. X(exit 1)1 324 1 1116 1050 t
  1478. X(})1008 1160 w
  1479. X( default nroff)2 756(NT=n #)1 378 2 1008 1270 t
  1480. X(s='*' # section, default try all)5 1728 1 1008 1380 t
  1481. X(for\(i\) switch\($i\){)1 972 1 1008 1490 t
  1482. X(case -t)1 378 1 1008 1600 t
  1483. X(NT=t)1116 1710 w
  1484. X(case -n)1 378 1 1008 1820 t
  1485. X(NT=n)1116 1930 w
  1486. X(case -*)1 378 1 1008 2040 t
  1487. X(echo Usage: $0 '[-nt] [section] page ...' >[1=2])7 2592 1 1116 2150 t
  1488. X(exit 1)1 324 1 1116 2260 t
  1489. X(case [1-9] 10)2 702 1 1008 2370 t
  1490. X(s=$i)1116 2480 w
  1491. X(case *)1 324 1 1008 2590 t
  1492. X(eval 'pages=man'$s/$i'.*')1 1350 1 1116 2700 t
  1493. X(for\(page in $pages\){)2 1080 1 1116 2810 t
  1494. X(if\(test -f $page\))2 918 1 1224 2920 t
  1495. X($NT\303roff -man $page)2 1026 1 1332 3030 t
  1496. X(if not)1 324 1 1224 3140 t
  1497. X(echo $0: $i not found >[1=2])5 1512 1 1332 3250 t
  1498. X(})1116 3360 w
  1499. X(})1008 3470 w
  1500. X10 R f
  1501. X(Note the use of)3 619 1 720 3650 t
  1502. X10 CW f
  1503. X(eval)1368 3650 w
  1504. X10 R f
  1505. X( Without)1 382(to make a list of candidate manual pages.)7 1675 2 1637 3650 t
  1506. X10 CW f
  1507. X(eval)3723 3650 w
  1508. X10 R f
  1509. X(, the)1 176 1 3963 3650 t
  1510. X10 CW f
  1511. X(*)4168 3650 w
  1512. X10 R f
  1513. X(stored in)1 352 1 4258 3650 t
  1514. X10 CW f
  1515. X($s)4640 3650 w
  1516. X10 R f
  1517. X(would)4790 3650 w
  1518. X( if it weren't, it would be)6 1098(not trigger filename matching \320 it's enclosed in quotation marks, and even)11 3222 2 720 3770 t
  1519. X(expanded when assigned to)3 1098 1 720 3890 t
  1520. X10 CW f
  1521. X($s)1844 3890 w
  1522. X10 R f
  1523. X( causes its arguments to be re-processed by)7 1728(. Eval)1 259 2 1964 3890 t
  1524. X10 I f
  1525. X(rc)3977 3890 w
  1526. X10 R f
  1527. X('s parser and interpreter,)3 980 1 4060 3890 t
  1528. X(effectively delaying evaluation of the)4 1491 1 720 4010 t
  1529. X10 CW f
  1530. X(*)2236 4010 w
  1531. X10 R f
  1532. X(until the assignment to)3 909 1 2321 4010 t
  1533. X10 CW f
  1534. X($pages)3255 4010 w
  1535. X10 R f
  1536. X(.)3615 4010 w
  1537. X10 B f
  1538. X( \320)1 125(26. Examples)1 592 2 720 4250 t
  1539. X10 I f
  1540. X(holmdel)1462 4250 w
  1541. X10 R f
  1542. X(The following)1 575 1 720 4406 t
  1543. X10 I f
  1544. X(rc)1327 4406 w
  1545. X10 R f
  1546. X(script plays the deceptively simple game)5 1658 1 1442 4406 t
  1547. X10 I f
  1548. X(holmdel)3132 4406 w
  1549. X10 R f
  1550. X(, in which the players alternately name)6 1586 1 3454 4406 t
  1551. X(Bell Labs locations, the winner being the first to mention Holmdel.)10 2682 1 720 4526 t
  1552. X(This script is worth describing in detail \(rather, it would be if it weren't so silly.\))15 3222 1 720 4682 t
  1553. X(Variable)720 4838 w
  1554. X10 CW f
  1555. X($t)1097 4838 w
  1556. X10 R f
  1557. X( Including)1 443(is an abbreviation for the name of a temporary file.)9 2115 2 1251 4838 t
  1558. X10 CW f
  1559. X($pid)3844 4838 w
  1560. X10 R f
  1561. X(, initialized by)2 595 1 4084 4838 t
  1562. X10 I f
  1563. X(rc)4714 4838 w
  1564. X10 R f
  1565. X(to its)1 208 1 4832 4838 t
  1566. X( one)1 178(process-id, in the names of temporary files insures that their names won't collide, in case more than)16 4142 2 720 4958 t
  1567. X(instance of the script is running at a time.)8 1651 1 720 5078 t
  1568. X(Function)720 5234 w
  1569. X10 CW f
  1570. X(read)1102 5234 w
  1571. X10 R f
  1572. X( is the name of a variable into which a line gathered from standard input is read.)16 3223('s argument)1 475 2 1342 5234 t
  1573. X10 CW f
  1574. X($ifs)720 5354 w
  1575. X10 R f
  1576. X( Thus)1 252(is set to just a newline.)5 921 2 987 5354 t
  1577. X10 CW f
  1578. X(read)2187 5354 w
  1579. X10 R f
  1580. X( at spaces, but the terminating newline is)7 1633('s input is not split apart)5 980 2 2427 5354 t
  1581. X(deleted.)720 5474 w
  1582. X(A handler is set to catch)5 1012 1 720 5630 t
  1583. X10 CW f
  1584. X(sigint)1767 5630 w
  1585. X10 R f
  1586. X(,)2127 5630 w
  1587. X10 CW f
  1588. X(sigquit)2188 5630 w
  1589. X10 R f
  1590. X(, and)1 205 1 2608 5630 t
  1591. X10 CW f
  1592. X(sighup,)2849 5630 w
  1593. X10 R f
  1594. X(and the artificial)2 676 1 3305 5630 t
  1595. X10 CW f
  1596. X(sigexit)4017 5630 w
  1597. X10 R f
  1598. X( just)1 181(signal. It)1 386 2 4473 5630 t
  1599. X(removes the temporary file and exits.)5 1486 1 720 5750 t
  1600. X( file is initialized from a here document containing a list of Bell Labs locations, and the main)17 3730(The temporary)1 590 2 720 5906 t
  1601. X(loop starts.)1 439 1 720 6026 t
  1602. X( \(in)1 144(First, the program guesses a location)5 1500 2 720 6182 t
  1603. X10 CW f
  1604. X($lab)2397 6182 w
  1605. X10 R f
  1606. X(\) using the)2 438 1 2637 6182 t
  1607. X10 CW f
  1608. X(fortune)3108 6182 w
  1609. X10 R f
  1610. X(program to pick a random line from)6 1479 1 3561 6182 t
  1611. X( prints the location, and if it guessed Holmdel, prints a message and exits.)13 2942( It)1 111(the location list.)2 642 3 720 6302 t
  1612. X( the)1 149(Then it uses)2 485 2 720 6458 t
  1613. X10 CW f
  1614. X(read)1381 6458 w
  1615. X10 R f
  1616. X(function to get lines from standard input and validity-check them until it gets a legal)14 3392 1 1648 6458 t
  1617. X( that the condition part of a)6 1118(name. Note)1 491 2 720 6578 t
  1618. X10 CW f
  1619. X(while)2360 6578 w
  1620. X10 R f
  1621. X( the exit status of the)5 855( Only)1 255( compound command.)2 901(can be a)2 338 4 2691 6578 t
  1622. X(last command in the sequence is checked.)6 1666 1 720 6698 t
  1623. X( it goes back to the top of the loop.)9 1388( Otherwise)1 460(Again, if the result is Holmdel, it prints a message and exits.)11 2415 3 720 6854 t
  1624. Xcleartomark
  1625. Xshowpage
  1626. Xsaveobj restore
  1627. X%%EndPage: 11 11
  1628. X%%Page: 12 12
  1629. X/saveobj save def
  1630. Xmark
  1631. X12 pagesetup
  1632. X10 R f
  1633. X(- 12 -)2 216 1 2772 480 t
  1634. X9 CW f
  1635. X(t=/tmp/holmdel$pid)1008 890 w
  1636. X(fn read{)1 432 1 1008 1000 t
  1637. X($1=`{awk '{print;exit}'})1 1296 1 1440 1110 t
  1638. X(})1008 1220 w
  1639. X(ifs=')1008 1330 w
  1640. X( just a newline)3 810(' #)1 486 2 1008 1440 t
  1641. X(fn sigexit sigint sigquit sighup{)4 1782 1 1008 1550 t
  1642. X(rm -f $t)2 432 1 1440 1660 t
  1643. X(exit)1440 1770 w
  1644. X(})1008 1880 w
  1645. X(cat <<'!' >$t)2 702 1 1008 1990 t
  1646. X(Allentown)1008 2100 w
  1647. X(Atlanta)1008 2210 w
  1648. X(Cedar Crest)1 594 1 1008 2320 t
  1649. X(Chester)1008 2430 w
  1650. X(Columbus)1008 2540 w
  1651. X(Elmhurst)1008 2650 w
  1652. X(Fullerton)1008 2760 w
  1653. X(Holmdel)1008 2870 w
  1654. X(Indian Hill)1 594 1 1008 2980 t
  1655. X(Merrimack Valley)1 864 1 1008 3090 t
  1656. X(Morristown)1008 3200 w
  1657. X(Piscataway)1008 3310 w
  1658. X(Reading)1008 3420 w
  1659. X(Short Hills)1 594 1 1008 3530 t
  1660. X(South Plainfield)1 864 1 1008 3640 t
  1661. X(Summit)1008 3750 w
  1662. X(Whippany)1008 3860 w
  1663. X(West Long Branch)2 864 1 1008 3970 t
  1664. X(!)1008 4080 w
  1665. X(while\(true\){)1008 4190 w
  1666. X(lab=`{/usr/games/fortune $t})1 1512 1 1170 4300 t
  1667. X(echo $lab)1 486 1 1170 4410 t
  1668. X(if\(\304 $lab Holmdel\){)2 1026 1 1170 4520 t
  1669. X(echo You lose.)2 756 1 1332 4630 t
  1670. X(exit)1332 4740 w
  1671. X(})1170 4850 w
  1672. X(while\(read lab; ! grep -i -s $lab $t\) echo No such location.)11 3240 1 1170 4960 t
  1673. X(if\(\304 $lab [hH]olmdel\){)2 1188 1 1170 5070 t
  1674. X(echo You win.)2 702 1 1332 5180 t
  1675. X(exit)1332 5290 w
  1676. X(})1170 5400 w
  1677. X(})1008 5510 w
  1678. X10 B f
  1679. X(27. Discussion)1 626 1 720 5690 t
  1680. X10 R f
  1681. X(Steve Bourne's)1 622 1 720 5846 t
  1682. X10 CW f
  1683. X(/bin/sh)1376 5846 w
  1684. X10 R f
  1685. X( I)1 93( comparison.)1 526(is extremely well-designed; any successor is bound to suffer in)9 2591 3 1830 5846 t
  1686. X( things wherever possible, usually by)5 1512(have tried to fix its best-acknowledged shortcomings and to simplify)9 2808 2 720 5966 t
  1687. X( I)1 67( Obviously)1 475( when irresistibly tempted have I introduced novel ideas.)8 2330( Only)1 258(omitting unessential features.)2 1190 5 720 6086 t
  1688. X(have tinkered extensively with Bourne's syntax, that being where his work was most open to criticism.)15 4109 1 720 6206 t
  1689. X(The most important principle in)4 1284 1 720 6362 t
  1690. X10 I f
  1691. X(rc)2032 6362 w
  1692. X10 R f
  1693. X( is never scanned more)4 930( Input)1 265('s design is that it's not a macro processor.)8 1730 3 2115 6362 t
  1694. X( by the lexical and syntactic analysis code \(except, of course, by the)12 2885(than once)1 401 2 720 6482 t
  1695. X10 CW f
  1696. X(eval)4046 6482 w
  1697. X10 R f
  1698. X(command, whose)1 714 1 4326 6482 t
  1699. X10 I f
  1700. X(raison d'etre)1 519 1 720 6602 t
  1701. X10 R f
  1702. X(is to break the rule\).)4 801 1 1264 6602 t
  1703. X( These)1 298( arguments containing spaces.)3 1228(Bourne shell scripts can often be made to run wild by passing them)12 2794 3 720 6758 t
  1704. X(will be split into multiple arguments using)6 1780 1 720 6878 t
  1705. X10 CW f
  1706. X(IFS)2539 6878 w
  1707. X10 R f
  1708. X( In)1 146( inopportune times.)2 801(, often as)2 391 3 2719 6878 t
  1709. X10 I f
  1710. X(rc)4095 6878 w
  1711. X10 R f
  1712. X(, values of variables,)3 862 1 4178 6878 t
  1713. X( have)1 227( Arguments)1 508( when substituted into a command.)5 1464(including command line arguments, are not re-read)6 2121 4 720 6998 t
  1714. X(presumably been scanned in the parent process, and ought not to be re-read.)12 3026 1 720 7118 t
  1715. X( store lists of)3 571( needs to be able to)5 858( He)1 184(Why does Bourne re-scan commands after variable substitution?)7 2707 4 720 7274 t
  1716. Xcleartomark
  1717. Xshowpage
  1718. Xsaveobj restore
  1719. X%%EndPage: 12 12
  1720. X%%Page: 13 13
  1721. X/saveobj save def
  1722. Xmark
  1723. X13 pagesetup
  1724. X10 R f
  1725. X(- 13 -)2 216 1 2772 480 t
  1726. X( we eliminate re-scanning, we must change the)7 1875( If)1 117( character strings.)2 708(arguments in variables whose values are)5 1620 4 720 840 t
  1727. X(type of variables, so that they can explicitly carry lists of strings.)11 2583 1 720 960 t
  1728. X( are two dif-)3 505( There)1 287( for lists of words.)4 750( need a notation)3 647( We)1 192(This introduces some conceptual complications.)4 1939 6 720 1116 t
  1729. X(ferent kinds of concatenation, for strings \320)6 1798 1 720 1236 t
  1730. X10 CW f
  1731. X($a\303$b)2552 1236 w
  1732. X10 R f
  1733. X(, and lists \320)3 533 1 2852 1236 t
  1734. X10 CW f
  1735. X(\($a $b\))1 429 1 3419 1236 t
  1736. X10 R f
  1737. X( difference between)2 801(. The)1 238 2 3848 1236 t
  1738. X10 CW f
  1739. X(\(\))4920 1236 w
  1740. X10 R f
  1741. X(and)720 1356 w
  1742. X10 CW f
  1743. X('')895 1356 w
  1744. X10 R f
  1745. X( not the)2 314(is confusing to novices, although the distinction is arguably sensible \320 a null argument is)14 3680 2 1046 1356 t
  1746. X(same as no argument.)3 865 1 720 1476 t
  1747. X( the text enclosed in back-)5 1100( is because)2 452( This)1 238(Bourne also rescans input when doing command substitution.)7 2530 4 720 1632 t
  1748. X( it ought to be parsed when the enclosing com-)9 1939( Properly,)1 427(quotes is not properly a string, but a command.)8 1954 3 720 1752 t
  1749. X(mand is, but this makes it difficult to handle nested command substitutions, like this:)13 3393 1 720 1872 t
  1750. X9 CW f
  1751. X(size=`wc -l \\`ls -t|sed 1q\\``)4 1566 1 1008 2042 t
  1752. X10 R f
  1753. X( can get much worse)4 832( This)1 231( escaped to avoid terminating the outer command.)7 2018(The inner back-quotes must be)4 1239 4 720 2222 t
  1754. X(than the above example; the number of)6 1612 1 720 2342 t
  1755. X10 CW f
  1756. X(\\)2366 2342 w
  1757. X10 R f
  1758. X('s required is exponential in the nesting depth.)7 1911 1 2426 2342 t
  1759. X10 I f
  1760. X(Rc)4396 2342 w
  1761. X10 R f
  1762. X(fixes this by)2 505 1 4535 2342 t
  1763. X(making the backquote a unary operator whose argument is a command, like this:)12 3220 1 720 2462 t
  1764. X9 CW f
  1765. X(size=`{wc -l `{ls -t|sed 1q}})4 1566 1 1008 2632 t
  1766. X10 R f
  1767. X(No escapes are ever required, and the whole thing is parsed in one pass.)13 2862 1 720 2812 t
  1768. X(For similar reasons)2 772 1 720 2968 t
  1769. X10 I f
  1770. X(rc)1520 2968 w
  1771. X10 R f
  1772. X( associating a string)3 803(defines signal handlers as though they were functions, instead of)9 2606 2 1631 2968 t
  1773. X(with each signal, as Bourne does, with the attendant possibility of getting a syntax error message in)16 4320 1 720 3088 t
  1774. X( Since)1 285(response to typing the interrupt character.)5 1723 2 720 3208 t
  1775. X10 I f
  1776. X(rc)2766 3208 w
  1777. X10 R f
  1778. X(parses input when typed, it reports errors when you)8 2153 1 2887 3208 t
  1779. X(make them.)1 466 1 720 3328 t
  1780. X( need for the distinction)4 1029( is no)2 255( There)1 301(For all this trouble, we gain substantial semantic simplifications.)8 2735 4 720 3484 t
  1781. X(between)720 3604 w
  1782. X10 CW f
  1783. X($*)1080 3604 w
  1784. X10 R f
  1785. X(and)1228 3604 w
  1786. X10 CW f
  1787. X($@)1400 3604 w
  1788. X10 R f
  1789. X( rules that)2 398( is no need for four types of quotation, nor the extremely complicated)12 2812(. There)1 310 3 1520 3604 t
  1790. X( In)1 133(govern them.)1 527 2 720 3724 t
  1791. X10 I f
  1792. X(rc)1405 3724 w
  1793. X10 R f
  1794. X( to appear in an argu-)5 855(you use quotation marks exactly when you want a syntax character)10 2672 2 1513 3724 t
  1795. X(ment.)720 3844 w
  1796. X10 CW f
  1797. X(IFS)999 3844 w
  1798. X10 R f
  1799. X(is no longer used, except in the one case where it was indispensable: converting command out-)15 3833 1 1207 3844 t
  1800. X(put into argument lists during command substitution.)6 2121 1 720 3964 t
  1801. X( security hole [Ree88].)3 933(This also avoids an important)4 1211 2 720 4120 t
  1802. X10 I f
  1803. X(System)2922 4120 w
  1804. X10 R f
  1805. X(\(3\) and)1 293 1 3199 4120 t
  1806. X10 I f
  1807. X(popen)3525 4120 w
  1808. X10 R f
  1809. X(\(3\) call)1 293 1 3769 4120 t
  1810. X10 CW f
  1811. X(/bin/sh)4095 4120 w
  1812. X10 R f
  1813. X(to execute a)2 492 1 4548 4120 t
  1814. X( to use either of these routines with any assurance that the specified command)13 3212( is impossible)2 569(command. It)1 539 3 720 4240 t
  1815. X(will be executed, even if the caller of)7 1479 1 720 4360 t
  1816. X10 I f
  1817. X(system)2224 4360 w
  1818. X10 R f
  1819. X(or)2515 4360 w
  1820. X10 I f
  1821. X(popen)2623 4360 w
  1822. X10 R f
  1823. X( can)1 164( This)1 229( for the command.)3 735(specifies a full path name)4 1020 4 2892 4360 t
  1824. X( problem is that)3 643( The)1 211( a set-userid program.)3 888(be devastating if it occurs in)5 1164 4 720 4480 t
  1825. X10 CW f
  1826. X(IFS)3657 4480 w
  1827. X10 R f
  1828. X(is used to split the command)5 1172 1 3868 4480 t
  1829. X(into words, so an attacker can just set)7 1534 1 720 4600 t
  1830. X10 CW f
  1831. X(IFS=/)2285 4600 w
  1832. X10 R f
  1833. X( Trojan horse named)3 844(in his environment and leave a)5 1253 2 2616 4600 t
  1834. X10 CW f
  1835. X(usr)4745 4600 w
  1836. X10 R f
  1837. X(or)4957 4600 w
  1838. X10 CW f
  1839. X(bin)720 4720 w
  1840. X10 R f
  1841. X(in the current working directory before running the privileged program.)9 2891 1 929 4720 t
  1842. X10 I f
  1843. X(Rc)3874 4720 w
  1844. X10 R f
  1845. X(fixes this by not ever res-)5 1032 1 4008 4720 t
  1846. X(canning input for any reason.)4 1167 1 720 4840 t
  1847. X(Most of the other differences between)5 1565 1 720 4996 t
  1848. X10 I f
  1849. X(rc)2320 4996 w
  1850. X10 R f
  1851. X( eliminated Bourne's)2 860( I)1 94(and the Bourne shell are not so serious.)7 1647 3 2439 4996 t
  1852. X(peculiar forms of variable substitution, like)5 1726 1 720 5116 t
  1853. X9 CW f
  1854. X(echo ${a=b} ${c-d} ${e?error})3 1566 1 1008 5286 t
  1855. X10 R f
  1856. X( deleted the builtins)3 822( I)1 95(because they are little used, redundant and easily expressed in less abstruse terms.)12 3403 3 720 5466 t
  1857. X10 CW f
  1858. X(export)720 5586 w
  1859. X10 R f
  1860. X(,)1080 5586 w
  1861. X10 CW f
  1862. X(readonly)1131 5586 w
  1863. X10 R f
  1864. X(,)1611 5586 w
  1865. X10 CW f
  1866. X(break)1662 5586 w
  1867. X10 R f
  1868. X(,)1962 5586 w
  1869. X10 CW f
  1870. X(continue)2013 5586 w
  1871. X10 R f
  1872. X(,)2493 5586 w
  1873. X10 CW f
  1874. X(read)2544 5586 w
  1875. X10 R f
  1876. X(,)2784 5586 w
  1877. X10 CW f
  1878. X(return)2835 5586 w
  1879. X10 R f
  1880. X(,)3195 5586 w
  1881. X10 CW f
  1882. X(set)3246 5586 w
  1883. X10 R f
  1884. X(,)3426 5586 w
  1885. X10 CW f
  1886. X(times)3477 5586 w
  1887. X10 R f
  1888. X(and)3803 5586 w
  1889. X10 CW f
  1890. X(unset)3973 5586 w
  1891. X10 R f
  1892. X(because they seem)2 742 1 4298 5586 t
  1893. X(redundant or only marginally useful.)4 1462 1 720 5706 t
  1894. X(Where Bourne's syntax draws from Algol 68,)6 1917 1 720 5862 t
  1895. X10 I f
  1896. X(rc)2677 5862 w
  1897. X10 R f
  1898. X( I)1 99( is harder to defend.)4 859( This)1 244( C or Awk.)3 492('s is based on)3 586 5 2760 5862 t
  1899. X(believe that, for example)3 992 1 720 5982 t
  1900. X9 CW f
  1901. X(if\(test -f junk\) rm junk)4 1296 1 1008 6152 t
  1902. X10 R f
  1903. X(is better syntax than)3 802 1 720 6332 t
  1904. X9 CW f
  1905. X(if test -f junk; then rm junk; fi)7 1782 1 1008 6502 t
  1906. X10 R f
  1907. X( is less cluttered with keywords, it avoids the semicolons that Bourne requires in odd places, and)16 3921(because it)1 399 2 720 6682 t
  1908. X(the syntax characters better set off the active parts of the command.)11 2693 1 720 6802 t
  1909. X(The one bit of large-scale syntax that Bourne unquestionably does better than)11 3169 1 720 6958 t
  1910. X10 I f
  1911. X(rc)3922 6958 w
  1912. X10 R f
  1913. X(is the)1 222 1 4038 6958 t
  1914. X10 CW f
  1915. X(if)4293 6958 w
  1916. X10 R f
  1917. X(statement with)1 594 1 4446 6958 t
  1918. X10 CW f
  1919. X(else)720 7078 w
  1920. X10 R f
  1921. X(clause.)986 7078 w
  1922. X10 I f
  1923. X(Rc)1310 7078 w
  1924. X10 R f
  1925. X('s)1415 7078 w
  1926. X10 CW f
  1927. X(if)1512 7078 w
  1928. X10 R f
  1929. X(has no terminating)2 744 1 1657 7078 t
  1930. X10 CW f
  1931. X(fi)2426 7078 w
  1932. X10 R f
  1933. X( a result, the parser cannot tell whether or not)9 1807( As)1 161(-like bracket.)1 526 3 2546 7078 t
  1934. X(to expect an)2 482 1 720 7198 t
  1935. X10 CW f
  1936. X(else)1227 7198 w
  1937. X10 R f
  1938. X( problem is that after reading, for example)7 1685( The)1 205(clause without looking ahead in its input.)6 1647 3 1492 7198 t
  1939. Xcleartomark
  1940. Xshowpage
  1941. Xsaveobj restore
  1942. X%%EndPage: 13 13
  1943. X%%Page: 14 14
  1944. X/saveobj save def
  1945. Xmark
  1946. X14 pagesetup
  1947. X10 R f
  1948. X(- 14 -)2 216 1 2772 480 t
  1949. X9 CW f
  1950. X(if\(test -f junk\) echo junk found)5 1728 1 1008 830 t
  1951. X10 R f
  1952. X(in interactive mode,)2 824 1 720 1010 t
  1953. X10 I f
  1954. X(rc)1583 1010 w
  1955. X10 R f
  1956. X(cannot decide whether to execute it immediately and print)8 2430 1 1705 1010 t
  1957. X10 CW f
  1958. X($prompt\(1\))4174 1010 w
  1959. X10 R f
  1960. X(, or to)2 266 1 4774 1010 t
  1961. X(print)720 1130 w
  1962. X10 CW f
  1963. X($prompt\(2\))937 1130 w
  1964. X10 R f
  1965. X(and wait for the)3 638 1 1565 1130 t
  1966. X10 CW f
  1967. X(else)2231 1130 w
  1968. X10 R f
  1969. X( the Bourne shell, this is not a problem, because)9 1930( In)1 136(to be typed.)2 475 3 2499 1130 t
  1970. X(the)720 1250 w
  1971. X10 CW f
  1972. X(if)867 1250 w
  1973. X10 R f
  1974. X(command must end with)3 986 1 1012 1250 t
  1975. X10 CW f
  1976. X(fi)2023 1250 w
  1977. X10 R f
  1978. X(, regardless of whether it contains an)6 1466 1 2143 1250 t
  1979. X10 CW f
  1980. X(else)3634 1250 w
  1981. X10 R f
  1982. X(or not.)1 261 1 3899 1250 t
  1983. X10 I f
  1984. X(Rc)720 1406 w
  1985. X10 R f
  1986. X( is to declare that the)5 839('s admittedly feeble solution)3 1144 2 825 1406 t
  1987. X10 CW f
  1988. X(else)2835 1406 w
  1989. X10 R f
  1990. X(clause is a separate statement, with the semantic)7 1938 1 3102 1406 t
  1991. X(proviso that it must immediately follow an)6 1724 1 720 1526 t
  1992. X10 CW f
  1993. X(if)2472 1526 w
  1994. X10 R f
  1995. X(, and to call it)4 559 1 2592 1526 t
  1996. X10 CW f
  1997. X(if not)1 363 1 3179 1526 t
  1998. X10 R f
  1999. X(rather than)1 432 1 3570 1526 t
  2000. X10 CW f
  2001. X(else)4030 1526 w
  2002. X10 R f
  2003. X(, as a reminder that)4 770 1 4270 1526 t
  2004. X( the braces are required in the)6 1227( only noticeable consequence of this is that)7 1766( The)1 212(something odd is going on.)4 1115 4 720 1646 t
  2005. X(construction)720 1766 w
  2006. X9 CW f
  2007. X(for\(i\){)1008 1936 w
  2008. X(if\(test -f $i\) echo $i found)5 1512 1 1224 2046 t
  2009. X(if not echo $i not found)5 1296 1 1224 2156 t
  2010. X(})1008 2266 w
  2011. X10 R f
  2012. X(and that)1 319 1 720 2446 t
  2013. X10 I f
  2014. X(rc)1064 2446 w
  2015. X10 R f
  2016. X(resolves the ``dangling else'' ambiguity in opposition to most people's expectations.)10 3378 1 1172 2446 t
  2017. X( the UNIX system programmer's manual the Bourne)7 2120(It is remarkable that in the four most recent editions of)10 2200 2 720 2602 t
  2018. X( not admit the command)4 976(shell grammar described in the manual page does)7 1985 2 720 2722 t
  2019. X10 CW f
  2020. X(who|wc)3707 2722 w
  2021. X10 R f
  2022. X( is surely an over-)4 719(. This)1 254 2 4067 2722 t
  2023. X( Even)1 266( something darker: nobody really knows what the Bourne shell's grammar is.)11 3206(sight, but it suggests)3 848 3 720 2842 t
  2024. X( the rou-)2 346( parser is implemented by recursive descent, but)7 1959( The)1 210(examination of the source code is little help.)7 1805 4 720 2962 t
  2025. X( categories all have a flag argument that subtly changes their operation)11 2885(tines corresponding to the syntactic)4 1435 2 720 3082 t
  2026. X(depending on the context.)3 1041 1 720 3202 t
  2027. X10 I f
  2028. X(Rc)1814 3202 w
  2029. X10 R f
  2030. X('s parser is implemented using)4 1233 1 1919 3202 t
  2031. X10 I f
  2032. X(yacc)3180 3202 w
  2033. X10 R f
  2034. X(, so I can say precisely what the grammar)8 1678 1 3362 3202 t
  2035. X(is.)720 3322 w
  2036. X( is a)2 165( There)1 284( it considerably except for two things.)6 1524( would simplify)2 636( I)1 84(Its lexical structure is harder to describe.)6 1627 6 720 3478 t
  2037. X( distinguish between parentheses that immediately follow a word with no intervening)11 3614(lexical kludge to)2 706 2 720 3598 t
  2038. X( use for)2 319(spaces and those that don't that I would eliminate if there were a reasonable pair of characters to)17 4001 2 720 3718 t
  2039. X( could also eliminate the insertion of free carets if users were not adamant about it.)15 3299( I)1 83(subscript brackets.)1 743 3 720 3838 t
  2040. X10 B f
  2041. X(28. Acknowledgements)1 1002 1 720 4078 t
  2042. X10 R f
  2043. X( Plan 9 users have been insistent, incessant sources of good ideas and)12 2825(Rob Pike, Howard Trickey and other)5 1495 2 720 4234 t
  2044. X( examples in this document are plagiarized from [Bou78], as are most of)12 2892(criticism. Some)1 653 2 720 4354 t
  2045. X10 I f
  2046. X(rc)4290 4354 w
  2047. X10 R f
  2048. X('s good features.)2 662 1 4373 4354 t
  2049. X10 B f
  2050. X(29. References)1 639 1 720 4594 t
  2051. X10 R f
  2052. X( R. Bourne, ``U)3 678(Bou78. S.)1 423 2 720 4822 t
  2053. X8 R f
  2054. X(NIX)1821 4822 w
  2055. X10 R f
  2056. X(Time-Sharing System: The U)3 1234 1 2006 4822 t
  2057. X8 R f
  2058. X(NIX)3240 4822 w
  2059. X10 R f
  2060. X(Shell,'')3425 4822 w
  2061. X10 I f
  2062. X(Bell System Technical Journal)3 1275 1 3765 4822 t
  2063. X10 B f
  2064. X(57)970 4942 w
  2065. X10 R f
  2066. X(\(6\), pp. 1971-1990 \(July-August 1978\).)4 1579 1 1070 4942 t
  2067. X( Reeds, ``)2 409(Ree88. J.)1 394 2 720 5098 t
  2068. X10 CW f
  2069. X(/bin/sh)1523 5098 w
  2070. X10 R f
  2071. X( Bell)1 205( AT&T)1 334(: the biggest UNIX security loophole,'' 11217-840302-04TM,)6 2558 3 1943 5098 t
  2072. X(Laboratories \(1988\).)1 820 1 970 5218 t
  2073. Xcleartomark
  2074. Xshowpage
  2075. Xsaveobj restore
  2076. X%%EndPage: 14 14
  2077. X%%Trailer
  2078. Xdone
  2079. X%%Pages: 14
  2080. X%%DocumentFonts: Courier Times-Bold Times-Italic Times-Roman Symbol
  2081. END_OF_FILE
  2082.   if test 40176 -ne `wc -c <'plan9.ps.b'`; then
  2083.     echo shar: \"'plan9.ps.b'\" unpacked with wrong size!
  2084.   elif test -f plan9.ps.a; then
  2085.     echo shar: Creating \"'plan9.ps'\" \(67056 characters\)
  2086.     cat plan9.ps.a plan9.ps.b > plan9.ps
  2087.     if test -f plan9.ps ; then
  2088.       rm plan9.ps.a plan9.ps.b
  2089.     fi
  2090.   fi
  2091.   # end of 'plan9.ps.b'
  2092. fi
  2093. echo shar: End of archive 1 \(of 7\).
  2094. cp /dev/null ark1isdone
  2095. MISSING=""
  2096. for I in 1 2 3 4 5 6 7 ; do
  2097.     if test ! -f ark${I}isdone ; then
  2098.     MISSING="${MISSING} ${I}"
  2099.     fi
  2100. done
  2101. if test "${MISSING}" = "" ; then
  2102.     echo You have unpacked all 7 archives.
  2103.     rm -f ark[1-9]isdone
  2104. else
  2105.     echo You still must unpack the following archives:
  2106.     echo "        " ${MISSING}
  2107. fi
  2108. exit 0
  2109. exit 0 # Just in case...
  2110.