1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426 |
- .TL
- Plumbing and Other Utilities
- .AU
- Rob Pike
- .AI
- .MH
- .AB
- .LP
- Plumbing is a new mechanism for inter-process communication in Plan 9,
- specifically the passing of messages between interactive programs as part of
- the user interface.
- Although plumbing shares some properties with familiar notions
- such as cut and paste,
- it offers a more general data exchange mechanism without imposing
- a particular user interface.
- .LP
- The core of the plumbing system is a program called the
- .I plumber ,
- which handles all messages and dispatches and reformats them
- according to configuration rules written in a special-purpose language.
- This approach allows the contents and context of a piece of data to define how
- it is handled.
- Unlike with drag and drop or cut and paste,
- the user doesn't need to deliver the data;
- the contents of a plumbing message, as interpreted by the plumbing rules,
- determine its destination.
- .LP
- The plumber has an unusual architecture: it is a language-driven file server.
- This design has distinct advantages.
- It makes plumbing easy to add to an existing, Unix-like command environment;
- it guarantees uniform handling of inter-application messages;
- it off-loads from those applications most of the work of extracting and dispatching messages;
- and it works transparently across a network.
- .AE
- .SH
- Introduction
- .LP
- Data moves from program to program in myriad ways.
- Command-line arguments,
- shell pipe lines,
- cut and paste,
- drag and drop, and other user interface techniques all provide some form
- of interprocess communication.
- Then there are tricks associated with special domains,
- such as HTML hyperlinks or the heuristics mail readers
- use to highlight URLs embedded in mail messages.
- Some systems provide implicit ways to automate the attachment of program to data\(emthe
- best known examples are probably the resource forks in MacOS and the
- file name extension `associations' in Microsoft Windows\(embut in practice
- humans must too often carry their data from program to program.
- .LP
- Why should a human do the work?
- Usually there is one obvious thing to do with a piece of data,
- and the data itself suggests what this is.
- Resource forks and associations speak to this issue directly, but statically and narrowly and with
- little opportunity to control the behavior.
- Mechanisms with more generality,
- such as cut and paste or drag and drop, demand too much manipulation by
- the user and are (therefore) too error-prone.
- .LP
- We want a system that, given a piece of data,
- hands it to the appropriate application by default with little or no human intervention,
- while still permitting the user to override the defaults if desired.
- .LP
- The plumbing system is an attempt to address some of these issues in a single,
- coherent, central way.
- It provides a mechanism for
- formatting and sending arbitrary messages between applications,
- typically interactive programs such as text editors, web browsers, and the window system,
- under the control of a central message-handling server called the
- .I plumber .
- Interactive programs provide application-specific connections to the plumber,
- triggering with minimal user action the transfer of data or control to other programs.
- The result is similar to a hypertext system in which all the links are implicit,
- extracted automatically by examining the data and the user's actions.
- It obviates
- cut and paste and other such hand-driven interprocess communication mechanisms.
- Plumbing delivers the goods to the right place automatically.
- .SH
- Overview
- .LP
- The plumber is implemented as a Plan 9 file server [Pike93];
- programs send messages by writing them to the plumber's file
- .CW /mnt/plumb/send ,
- and receive messages by reading them from
- .I ports ,
- which are other plumber files in
- .CW /mnt/plumb .
- For example,
- .CW /mnt/plumb/edit
- is by convention the file from which a text editor reads messages requesting it to
- open and display a file for editing.
- (See Figure 1.)
- .KF
- .PS
- down
- P1: ellipse "ProgramA"
- move
- P2: ellipse "ProgramB"
- move
- P3: ellipse "ProgramC"
- right
- INVIS: box wid 1.3 invis at P2.e
- SEND: arrow from INVIS.e "\f(CWsend \fP" ""
- arrow -> right 0.2 from P1.e; spline -> right 0.2 then down 1 to SEND.w
- arrow -> right 0.2 from P2.e; arrow -> to SEND.w
- arrow -> right 0.2 from P3.e; spline -> right 0.2 then up 1 to SEND.w
- right
- PL: box height 1 "plumber" with .w at SEND.e
- A3: arrow 0.8 -> "\f(CWimage\fP" ""; arrow ->
- O3: ellipse "Viewer"
- O2: ellipse "Browser" with .s at O3.n + (0, 0.1)
- O1: ellipse "Editor" with .s at O2.n + (0, 0.1)
- O4: ellipse "Faces" with .n at O3.s + (0, -0.1)
- O5: ellipse "..." with .n at O4.s + (0, -0.1)
- right
- A1: arrow 0.8 -> "\f(CWedit\fP" "" from PL.e + (0, .4); spline -> right 0.15 then up 0.7 then to O1.w
- right
- A2: arrow 0.8 -> "\f(CWweb\fP" "" from PL.e + (0, .2); spline -> right 0.3 then up 0.3 then to O2.w
- right
- A4: arrow 0.8 -> "\f(CWnewmail\fP" "" from PL.e + (0, -.2); spline -> right 0.3 then down 0.3 then to O4.w
- right
- A5: arrow 0.8 -> "\f(CW...\fP" "" from PL.e + (0, -.4); spline -> right 0.15 then down 0.7 then to O5.w
- .PE
- .IP
- .ps -1
- Figure 1. The plumber controls the flow of messages between applications.
- Programs write to the file
- .CW send
- and receive on `ports' of various names representing services such as
- .CW edit
- or
- .CW web .
- Although the figure doesn't illustrate it, some programs may both send and receive messages,
- and some ports are read by multiple applications.
- .sp
- .KE
- .LP
- The plumber takes messages from the
- .CW send
- file and interprets their contents using rules defined by
- a special-purpose pattern-action language.
- The language specifies any rewriting of the message that is to be done by the plumber
- and defines how to dispose of a message, such as by sending it to a port or
- starting a new process to handle it.
- .LP
- The behavior is best described by example.
- Imagine that the user has, in a terminal emulator window,
- just run a compilation that has failed:
- .P1
- % make
- cc -c rmstar.c
- rmstar.c:32: syntax error
- \&...
- .P2
- The user points the typing cursor somewhere in the string
- .CW rmstar.c:32:
- and executes the
- .CW plumb
- menu entry.
- This causes the terminal emulator to format a plumbing message
- containing the entire string surrounding the cursor,
- .CW rmstar:32: ,
- and to write it to
- .CW /mnt/plumb/send .
- The plumber receives this message and compares it sequentially to the various
- patterns in its configuration.
- Eventually, it will find one that breaks the string into pieces,
- .CW rmstar.c ,
- a colon,
- .CW 32 ,
- and the final colon.
- Other associated patterns verify that
- .CW rmstar.c
- is a file in the current directory of the program generating
- the message, and that
- .CW 32
- looks like a line number within it.
- The plumber rewrites the message,
- setting the data to the string
- .CW rmstar.c
- and attaching an indication that
- .CW 32
- is a line number to display.
- Finally, it sends the resulting message to the
- .CW edit
- port.
- The text editor picks up the message, opens
- .CW rmstar.c
- (if it's not already open) and highlights line 32, the location of the syntax error.
- .LP
- From the user's point of view, this process is simple: the error message appears,
- it is `plumbed', and the editor jumps to the problem.
- .LP
- Of course, there are many different ways to cause compiler messages to
- pop up the source of an error,
- but the design of the plumber addresses more general issues than the specific
- goal of shortening the compile/debug/edit cycle.
- It facilitates the general exchange of data among programs, interactive or otherwise,
- throughout the environment, and its
- architecture\(ema central, language-driven file server\(emalthough
- unusual, has distinct advantages.
- It makes plumbing easy to add to an existing, Unix-like command environment;
- it guarantees uniform handling of inter-application messages;
- it off-loads from those applications most of the work of extracting and dispatching messages;
- and it works transparently and effortlessly across a network.
- .LP
- This paper is organized bottom-up, beginning with the format of the messages
- and proceeding through the plumbing language, the handling of messages,
- and the interactive user interface.
- The last sections discuss the implications of the design
- and compare the plumbing system to other environments that
- provide similar services.
- .SH
- Format of messages
- .LP
- Since the language that controls the plumber is defined in terms of the
- contents of plumbing messages, we begin by describing their layout.
- .LP
- Plumbing messages have a fixed-format textual
- header followed by a free-format data section.
- The header consists of six lines of text, in set order,
- each specifying a property of the message.
- Any line may be blank except the last, which is the length of the data portion of the
- message, as a decimal string.
- The lines are, in order:
- .IP
- The source application, the name of the program generating the message.
- .IP
- The destination port, the name of the port to which the messages should be sent.
- .IP
- The working directory in which the message was generated.
- .IP
- The type of the data, analogous to a MIME type, such as
- .CW text
- or
- .CW image/gif .
- .IP
- Attributes of the message, given as blank-separated
- .I name\f(CW=\fPvalue
- pairs.
- The values may be quoted to protect
- blanks or quotes; values may not contain newlines.
- .IP
- The length of the data section, in bytes.
- .LP
- Here is a sample message, one that (conventionally) tells the editor to open the file
- .CW /usr/rob/src/mem.c
- and display line
- 27 within it:
- .P1
- plumbtest
- edit
- /usr/rob/src
- text
- addr=27
- 5
- mem.c
- .P2
- Because in general it need not be text, the data section of the message has no terminating newline.
- .LP
- A library interface simplifies the processing of messages by translating them
- to and from a data structure,
- .CW Plumbmsg ,
- defined like this:
- .P1
- .ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n
- typedef struct Plumbattr Plumbattr;
- typedef struct Plumbmsg Plumbmsg;
- struct Plumbmsg
- {
- char *src; /* source application */
- char *dst; /* destination port */
- char *wdir; /* working directory */
- char *type; /* type of data */
- Plumbattr *attr; /* attribute list */
- int ndata; /* #bytes of data */
- char *data;
- };
- struct Plumbattr
- {
- char *name;
- char *value;
- Plumbattr *next;
- };
- .P2
- The library also includes routines to send a message, receive a message,
- manipulate the attribute list, and so on.
- .SH
- The Language
- .LP
- An instance of the plumber runs for each user on each terminal or workstation.
- It
- begins by reading its rules from the file
- .CW lib/plumbing
- in the user's home directory,
- which in turn may use
- .CW include
- statements to interpolate macro definitions and
- rules from standard plumbing rule libraries stored in
- .CW /sys/lib/plumb .
- .LP
- The rules control the processing of messages.
- They are written in
- a pattern-action language comprising a sequence of blank-line-separated
- .I rule
- .I sets ,
- each of which contains one or more
- .I patterns
- followed by one or more
- .I actions .
- Each incoming message is compared against the rule sets in order.
- If all the patterns within a rule set succeed,
- one of the associated actions is taken and processing completes.
- .LP
- The syntax of the language is straightforward.
- Each rule (pattern or action) has three components, separated by white space:
- an
- .I object ,
- a
- .I verb ,
- and optional
- .I arguments .
- The object
- identifies a part of the message, such as
- the source application
- .CW src ), (
- or the data
- portion of the message
- .CW data ), (
- or the rule's own arguments
- .CW arg ); (
- or it is the keyword
- .CW plumb ,
- which introduces an action.
- The verb specifies an operation to perform on the object, such as the word
- .CW is ' `
- to require precise equality between the object and the argument, or
- .CW isdir ' `
- to require that the object be the name of a directory.
- .LP
- For instance, this rule set sends messages containing the names of files
- ending in
- .CW .gif ,
- .CW .jpg ,
- etc. to a program,
- .CW page ,
- to display them; it is analogous to a Windows association rule:
- .P1
- # image files go to page
- type is text
- data matches '[a-zA-Z0-9_\e-./]+'
- data matches '([a-zA-Z0-9_\e-./]+)\e.(jpe?g|gif|bit|tiff|ppm)'
- arg isfile $0
- plumb to image
- plumb client page -wi
- .P2
- (Lines beginning with
- .CW #
- are commentary.)
- Consider how this rule handles the following message, annotated down the left column for clarity:
- .P1
- .ta 10n
- \f2src\fP plumbtest
- \f2dst\fP
- \f2wdir\fP /usr/rob/pics
- \f2type\fP text
- \f2attr\fP
- \f2ndata\fP 9
- \f2data\fP horse.gif
- .P2
- The
- .CW is
- verb specifies a precise match, and the
- .CW type
- field of the message is the string
- .CW text ,
- so the first pattern succeeds.
- The
- .CW matches
- verb invokes a regular expression pattern match of the object (here
- .CW data )
- against the argument pattern.
- Both
- .CW matches
- patterns in this rule set will succeed, and in the process set the variables
- .CW $0
- to the matched string,
- .CW $1
- to the first parenthesized submatch, and so on (analogous to
- .CW & ,
- .CW \e1 ,
- etc. in
- .CW ed 's
- regular expressions).
- The pattern
- .CW arg
- .CW isfile
- .CW $0
- verifies that the named file,
- .CW horse.gif ,
- is an actual file in the directory
- .CW /usr/rob/pics .
- If all the patterns succeed, one of the actions will be executed.
- .LP
- There are two actions in this rule set.
- The
- .CW plumb
- .CW to
- rule specifies
- .CW image
- as the destination port of the message.
- By convention, the plumber mounts its services in the directory
- .CW /mnt/plumb ,
- so in this case if the file
- .CW /mnt/plumb/image
- has been opened, the message will be made available to the program reading from it.
- Note that the message does not name a port, but the rule set that matches
- the message does, and that is sufficient to dispatch the message.
- If on the other hand a message matches no rule but has an explicit port mentioned,
- that too is sufficient.
- .LP
- If no client has opened the
- .CW image
- port,
- that is, if the program
- .CW page
- is not already running, the
- .CW plumb
- .CW client
- action gives the execution script to start the application
- and send the message on its way; the
- .CW -wi
- arguments tell
- .CW page
- to create a window and to receive its initial arguments from the plumbing port.
- The process by which the plumber starts a program is described in more detail in the next section.
- .LP
- It may seem odd that there are two
- .CW matches
- rules in this example.
- The reason is related to the way the plumber can use the rules themselves
- to refine the
- .I data
- in the message, somewhat in the manner of Structural Regular Expressions [Pike87a].
- For example, consider what happens if the cursor is at the last character of
- .P1
- % make nightmare>horse.gif
- .P2
- and the user asks to plumb what the cursor is pointing at.
- The program creating the plumbing
- message\(emin this case the terminal emulator running the window\(emcan send the
- entire white-space-delimited string
- .CW nightmare>horse.gif
- or even the entire line, and the combination of
- .CW matches
- rules can determine that the user was referring to the string
- .CW horse.gif .
- The user could of course select the entire string
- .CW horse.gif ,
- but it's more convenient just to point in the general location and let the machine
- figure out what should be done.
- The process is as follows.
- .LP
- The application generating the message adds a special attribute to the message, named
- .CW click ,
- whose numerical value is the offset of the cursor\(emthe selection point\(emwithin the data string.
- This attribute tells the plumber two things:
- first, that the regular expressions in
- .CW matches
- rules should be used to identify the relevant data;
- and second, approximately where the relevant data lies.
- The plumber
- will then use the first
- .CW matches
- pattern to identify the longest leftmost match that touches the cursor, which will extract the string
- .CW horse.gif ,
- and the second pattern will then verify that that names a picture file.
- The rule set succeeds and the data is winnowed to the matching substring
- before being sent to its destination.
- .LP
- Each
- .CW matches
- pattern within a given rule set must match the same portion of the string, which
- guarantees that the rule set fails to match a string for which the
- second pattern matches only a portion.
- For instance, our example rule set should not execute if the data is the string
- .CW horse.gift ,
- and although the first pattern will match
- .CW horse.gift ,
- the second will match only
- .CW horse.gif
- and the rule set will fail.
- .LP
- The same approach of multiple
- .CW matches
- rules can be used to exclude, for instance, a terminal period from
- a file name or URL, so a file name or URL at the end of a sentence is recognized properly.
- .LP
- If a
- .CW click
- attribute is not specified, all patterns must match the entire string,
- so the user has an option:
- he or she may select exactly what data to send,
- or may instead indicate where the data is by clicking the selection button on the mouse
- and letting the machine locate the URL or image file name within the text.
- In other words,
- the user can control the contents of the message precisely when required,
- but the default, simplest action in the user interface does the right thing most of the time.
- .SH
- How Messages are Handled in the Plumber
- .LP
- An application creates a message header, fills in whatever fields it wishes to define,
- attaches the data, and writes the result to the file
- .CW send
- in the plumber's service directory,
- .CW /mnt/plumb .
- The plumber receives the message and applies the plumbing rules successively to it.
- When a rule set matches, the message is dispatched as indicated by that rule set
- and processing continues with the next message.
- If no rule set matches the message, the plumber indicates this by returning a write
- error to the application, that is, the write to
- .CW /mnt/plumb/send
- fails, with the resulting error string
- describing the failure.
- (Plan 9 uses strings rather than pre-defined numbers to describe error conditions.)
- Thus a program can discover whether a plumbing message has been sent successfully.
- .LP
- After a matching rule set has been identified, the plumber applies a series of rewriting
- steps to the message. Some rewritings are defined by the rule set; others are implicit.
- For example, if the message does not specify a destination port, the outgoing message
- will be rewritten to identify it.
- If the message does specify the port, the rule set will only match if any
- .CW plumb
- .CW to
- action in the rule set names the same port.
- (If it matches no rule sets, but mentions a port, it will be sent there unmodified.)
- .LP
- The rule set may contain actions that explicitly rewrite components of the message.
- These may modify the attribute list or replace the data section of the message.
- Here is a sample rule set that does both.
- It matches strings of the form
- .CW plumb.h
- or
- .CW plumb.h:27 .
- If that string identifies a file in the standard C include directory,
- .CW /sys/include ,
- perhaps with an optional line number, the outgoing message
- is rewritten to contain the full path name and an attribute,
- .CW addr ,
- to hold the line number:
- .P1
- # .h files are looked up in /sys/include and passed to edit
- type is text
- data matches '([a-zA-Z0-9]+\e.h)(:([0-9]+))?'
- arg isfile /sys/include/$1
- data set /sys/include/$1
- attr add addr=$3
- plumb to edit
- .P2
- The
- .CW data
- .CW set
- rule replaces the contents of the data, and the
- .CW attr
- .CW add
- rule adds a new attribute to the message.
- The intent of this rule is to permit one to plumb an include file name in a C program
- to trigger the opening of that file, perhaps at a specified line, in the text editor.
- A variant of this rule, discussed below,
- tells the editor how to interpret syntax errors from the compiler,
- or the output of
- .CW grep
- .CW -n ,
- both of which use a fixed syntax
- .I file\f(CW:\fPline
- to identify a line of source.
- .LP
- The Plan 9 text editors interpret the
- .CW addr
- attribute as the definition of which portion of the file to display.
- In fact, the real rule includes a richer definition of the address syntax,
- so one may plumb strings such as
- .CW plumb.h:/plumbsend
- (using a regular expression after the
- .CW / )
- to pop up the declaration of a function in a C header file.
- .LP
- Another form of rewriting is that the plumber may modify the attribute list of
- the message to clarify how to handle the message.
- The primary example of this involves the treatment of the
- .CW click
- attribute, described in the previous section.
- If the message contains a
- .CW click
- attribute and the matching rule set uses it to extract the matching substring from the data,
- the plumber
- deletes the
- .CW click
- attribute and replaces the data with the matching substring.
- .LP
- Once the message is rewritten, the actions of the matching rule set are examined.
- If the rule set contains a
- .CW plumb
- .CW to
- action and the corresponding port is open\(emthat is, if a program is already reading
- from that port\(emthe message is delivered to the port.
- The application will receive the message and handle it as it sees fit.
- If the port is not open, a
- .CW plumb
- .CW start
- or
- .CW plumb
- .CW client
- action will start a new program to handle the message.
- .LP
- The
- .CW plumb
- .CW start
- action is the simpler: its argument specifies a command to run
- instead of passing on the message; the message is discarded.
- Here for instance is a rule that, given the process id (pid) of an existing process,
- starts the
- .CW acid
- debugger [Wint94] in a new window to examine that process:
- .P1
- # processes go to acid (assuming strlen(pid) >= 2)
- type is text
- data matches '[a-zA-Z0-9.:_\e-/]+'
- data matches '[0-9][0-9]+'
- arg isdir /proc/$0
- plumb start window acid $0
- .P2
- (Note the use of multiple
- .CW matches
- rules to avoid misfires from strings like
- .CW party.1999 .)
- The
- .CW arg
- .CW isdir
- rule checks that the pid represents a running process (or broken one; Plan 9 does not create
- .CW core
- files but leaves broken processes around for debugging) by checking that the process file
- system has a directory for that pid [Kill84].
- Using this rule, one may plumb the pid string printed by the
- .CW ps
- command or by the operating system when the program breaks;
- the debugger will then start automatically.
- .LP
- The other startup action,
- .CW plumb
- .CW client ,
- is used when a program will read messages from the plumbing port.
- For example,
- text editors can read files specified as command arguments, so one could use a
- .CW plumb
- .CW start
- rule to begin editing a file.
- If, however, the editor will read messages from the
- .CW edit
- plumbing port, letting it read the message
- from the port insures that it uses other information in the message,
- such as the line number to display.
- The
- .CW plumb
- .CW client
- action is therefore like
- .CW plumb
- .CW start ,
- but keeps the message around for delivery when the application opens the port.
- Here is the full rule set to pass a regular file to the text editor:
- .P1
- # existing files, possibly tagged by address, go to editor
- type is text
- data matches '([.a-zA-Z0-9_/\e-]*[a-zA-Z0-9_/\e-])('$addr')?'
- arg isfile $1
- data set $1
- attr add addr=$3
- plumb to edit
- plumb client window $editor
- .P2
- If the editor is already running, the
- .CW plumb
- .CW to
- rule causes it to receive the message on the port.
- If not,
- the command
- .CW window "" `
- .CW $editor '
- will create a new window (using the Plan 9 program
- .CW window )
- to run the editor, and once that starts it will open the
- .CW edit
- plumbing port as usual and discover this first message already waiting.
- .LP
- The variables
- .CW $editor
- and
- .CW $addr
- in this rule set
- are macros defined in the plumbing rules file; they specify the name of the user's favorite text editor
- and a regular expression
- that matches that editor's address syntax, such as line numbers and patterns.
- This rule set lives in a library of shared plumbing rules that
- users' private rules can build on,
- so the rule set needs to be adaptable to different editors and their address syntax.
- The macro definitions for Acme and Sam [Pike94,Pike87b] look like this:
- .P1
- editor=acme
- # or editor=sam
- addrelem='((#?[0-9]+)|(/[A-Za-z0-9_\e^]+/?)|[.$])'
- addr=:($addrelem([,;+\e-]$addrelem)*)
- .P2
- .LP
- Finally, the application reads the message from the appropriate port, such as
- .CW /mnt/plumb/edit ,
- unpacks it, and goes to work.
- .SH
- Message Delivery
- .LP
- In summary, a message is delivered by writing it to the
- .CW send
- file and having the plumber, perhaps after some rewriting, send it to the destination
- port or start a new application to handle it.
- If no destination can be found by the plumber, the original write to the
- .CW send
- file will fail, and the application will know the message could not be delivered.
- .LP
- If multiple applications are reading from the destination port, each will receive
- an identical copy of the message; that is, the plumber implements fan-out.
- The number of messages delivered is equal to the number of clients that have
- opened the destination port.
- The plumber queues the messages and makes sure that each application that opened
- the port before the message was written gets exactly one copy.
- .LP
- This design minimizes blocking in the sending applications, since the write to the
- .CW send
- file can complete as soon as the message has been queued for the appropriate port.
- If the plumber waited for the message to be read by the recipient, the sender could
- block unnecessarily.
- Unfortunately, this design also means that there is no way for a sender to know when
- the message has been handled; in fact, there are cases when
- the message will not be delivered at all, such as if the recipient exits while there are
- still messages in the queue.
- Since the plumber is part of a user interface, and not
- an autonomous message delivery system,
- the decision was made to give the
- non-blocking property priority over reliability of message delivery.
- In practice, this tradeoff has worked out well:
- applications almost always know when a message has failed to be delivered (the
- .CW write
- fails because no destination could be found),
- and those occasions when the sender believes incorrectly that the message has been delivered
- are both extremely rare and easily recognized by the user\(emusually because the recipient
- application has exited.
- .SH
- The Rules File
- .LP
- The plumber begins execution by reading the user's startup plumbing rules file,
- .CW lib/plumbing .
- Since the plumber is implemented as a file server, it can also present its current rules
- as a dynamic file, a design that provides an easily understood way to maintain the rules.
- .LP
- The file
- .CW /mnt/plumb/rules
- is the text of the rule set the plumber is currently using,
- and it may be edited like a regular file to update those rules.
- To clear the rules, truncate that file;
- to add a new rule set, append to it:
- .P1
- % echo 'type is text
- data is self-destruct
- plumb start rm -rf $HOME' >> /mnt/plumb/rules
- .P2
- This rule set will take effect immediately.
- If it has a syntax error, the write will fail with an error message from the plumber,
- such as `malformed rule' or 'undefined verb'.
- .LP
- To restore the plumber to its startup configuration,
- .P1
- % cp /usr/$user/lib/plumbing /mnt/plumb/rules
- .P2
- For more sophisticated changes,
- one can of course use a regular text editor to modify
- .CW /mnt/plumb/rules .
- .LP
- This simple way of maintaining an active service could profitably be adopted by other systems.
- It avoids the need to reboot, to update registries with special tools, or to send asynchronous signals
- to critical programs.
- .SH
- The User Interface
- .LP
- One unusual property of the plumbing system is that
- the user interface that programs provide to access it can vary considerably, yet
- the result is nonetheless a unifying force in the environment.
- Shells talk to editors, image viewers, and web browsers; debuggers talk to editors;
- editors talk to themselves; and the window system talks to everybody.
- .LP
- The plumber grew out of some of the ideas of the Acme editor/window-system/user interface [Pike94],
- in particular its `acquisition' feature.
- With a three-button mouse, clicking the right button in Acme on a piece of text tells Acme to
- get the thing being pointed to.
- If it is a file name, open the file;
- if it is a directory, open a viewer for its contents;
- if a line number, go to that line;
- if a regular expression, search for it.
- This one-click access to anything describable textually was very powerful but had several
- limitations, of which the most important were that Acme's rules for interpreting the
- text (that is, the implicit hyperlinks) were hard-wired and inflexible, and
- that they only applied to and within Acme itself.
- One could not, for example, use Acme's power to open an image file, since Acme is
- a text-only system.
- .LP
- The plumber addresses these limitations, even with Acme itself:
- Acme now uses the plumber to interpret the right button clicks for it.
- When the right button is clicked on some text,
- Acme constructs a plumbing message much as described above,
- using the
- .CW click
- attribute and the white-space-delimited text surrounding the click.
- It then writes the message to the plumber; if the write succeeds, all is well.
- If not, it falls back to its original, internal rules, which will result in a context search
- for the word within the current document.
- .LP
- If the message is sent successfully, the recipient is likely to be Acme itself, of course:
- the request may be to open a file, for example.
- Thus Acme has turned the plumber into an external component of its own operation,
- while expanding the possibilities; the operation might be to start an image viewer to
- open a picture file, something Acme cannot do itself.
- The plumber expands the power of Acme's original user interface.
- .LP
- Traditional menu-driven programs such as the text editor Sam [Pike87b] and the default
- shell window of the window
- system
- .CW 8½
- [Pike91] cannot dedicate a mouse button solely to plumbing, but they can certainly
- dedicate a menu entry.
- The editing menu for such programs now contains an entry,
- .CW plumb ,
- that creates a plumbing message using the current selection.
- (Acme manages to send a message by clicking on the text with one button;
- other programs require a click with the select button and then a menu operation.)
- For example, after this happens in a shell window:
- .P1
- % make
- cc -c shaney.c
- shaney.c:232: i undefined
- \&...
- .P2
- one can click anywhere on the string
- .CW shaney.c:232 ,
- execute the
- .CW plumb
- menu entry, and have line 232 appear in the text editor, be it Sam or Acme\(emwhichever has the
- .CW edit
- port open.
- (If this were an Acme shell window, it would be sufficient to right-click on the string.)
- .LP
- [An interesting side line is how the window system knows what directory the
- shell is running in; in other words, what value to place in the
- .CW wdir
- field of the plumb message.
- Recall that
- .CW 8½
- is, like many Plan 9 programs, a file server.
- It now serves a new file,
- .CW /dev/wdir ,
- that is private to each window.
- Programs, in particular the
- Plan 9 shell,
- .CW rc ,
- can write that file to inform the window system of its current directory.
- When a
- .CW cd
- command is executed in an interactive shell,
- .CW rc
- updates the contents of
- .CW /dev/wdir
- and plumbing can proceed with local file names.]
- .LP
- Of course, users can plumb image file names, process ids, URLs, and other items\(emany string
- whose syntax and disposition are defined in the plumbing rules file.
- An example of how the pieces fit together is the way Plan 9 now handles mail, particularly
- MIME-encoded messages.
- .LP
- When a new mail message arrives, the mail receiver process sends a plumbing message to the
- .CW newmail
- port, which notifies any interested process that new mail is here.
- The plumbing message contains information about the mail, including
- its sender, date, and current location in the file system.
- The interested processes include a program,
- .CW faces ,
- that gives a graphical display of the mail box using
- faces to represent the senders of messages [PiPr85],
- as well as interactive mail programs such as the Acme mail viewer [Pike94].
- The user can then click on the face that appears, and the
- .CW faces
- program will send another plumbing message, this time to the
- .CW showmail
- port.
- Here is the rule for that port:
- .P1
- # faces -> new mail window for message
- type is text
- data matches '[a-zA-Z0-9_\e-./]+'
- data matches '/mail/fs/[a-zA-Z0-9/]+/[0-9]+'
- plumb to showmail
- plumb start window edmail -s $0
- .P2
- If a program, such as the Acme mail reader, is reading that port, it will open a new window
- in which to display the message.
- If not, the
- .CW plumb
- .CW start
- rule will create a new window and run
- .CW edmail ,
- a conventional mail reading process, to examine it.
- Notice how the plumbing connects the components of the interface together the same way
- regardless of which components are actually being used to view mail.
- .LP
- There is more to the mail story.
- Naturally, mail boxes in Plan 9 are treated as little file systems, which are synthesized
- on demand by a special-purpose file server that takes a flat mail box file and converts
- it into a set of directories, one per message, with component files containing the header,
- body, MIME information, and so on.
- Multi-part MIME messages are unpacked into multi-level directories, like this:
- .P1
- % ls -l /mail/fs/mbox/25
- d-r-xr-xr-x M 20 rob rob 0 Nov 21 13:06 /mail/fs/mbox/25/1
- d-r-xr-xr-x M 20 rob rob 0 Nov 21 13:06 /mail/fs/mbox/25/2
- --r--r--r-- M 20 rob rob 28678 Nov 21 13:06 /mail/fs/mbox/25/body
- --r--r--r-- M 20 rob rob 0 Nov 21 13:06 /mail/fs/mbox/25/cc
- \&...
- % mail
- 25 messages
- : 25
- From: presotto
- Date: Sun Nov 21 13:05:51 EST 1999
- To: rob
- Check this out.
- ===> 2/ (image/jpeg) [inline]
- /mail/fs/mbox/25/2/fabio.jpg
- :
- .P2
- Since the components are all (synthetic) files, the user can plumb the pieces
- to view embedded pictures, URLs, and so on.
- Note that the mail program can plumb the contents of
- .CW inline
- attachments automatically, without user interaction;
- in other words, plumbing lets the mailer handle multimedia data
- without itself interpreting it.
- .LP
- At a more mundane level, a shell command,
- .CW plumb ,
- can be used to send messages:
- .P1
- % cd /usr/rob/src
- % plumb mem.c
- .P2
- will send the appropriate message to the
- .CW edit
- port.
- A surprising use of the
- .CW plumb
- command is in actions within the plumbing rules file.
- In our lab, we commonly receive Microsoft Word documents by mail,
- but we do not run Microsoft operating systems on our machines so we cannot
- view them without at least rebooting.
- Therefore, when a Word document arrives in mail, we could plumb the
- .CW .doc
- file but the text editor could not decode it.
- However, we have a program,
- .CW doc2txt ,
- that decodes the Word file format to extract and format the embedded text.
- The solution is to use
- .CW plumb
- in a
- .CW plumb
- .CW start
- action to invoke
- .CW doc2txt
- on
- .CW .doc
- files and synthesize a plain text file:
- .P1
- # rule set for microsoft word documents
- type is text
- data matches '[a-zA-Z0-9_\e-./]+'
- data matches '([a-zA-Z0-9_\e-./]+)\e.doc'
- arg isfile $0
- plumb start doc2txt $data | \e
- plumb -i -d edit -a action=showdata -a filename=$0
- .P2
- The arguments to
- .CW plumb
- tell it to take standard input as its data rather than the text of the arguments
- .CW -i ), (
- define the destination port
- .CW -d "" (
- .CW edit ),
- and set a conventional attribute so the editor knows to show the message data
- itself rather than interpret it as a file name
- .CW -a "" (
- .CW action=showdata )
- and provide the original file name
- .CW -a "" (
- .CW filename=$0 ).
- Now when a user plumbs a
- .CW .doc
- file the plumbing rules run a process to extract the text and send it as a
- temporary file to the editor for viewing.
- It's imperfect, but it's easy and it beats rebooting.
- .LP
- Another simple example is a rule that turns man pages into hypertext.
- Manual page entries of the form
- .CW plumber(1)
- can be clicked on to pop up a window containing the formatted `man page'.
- That man page will in turn contain more such citations, which will also be clickable.
- The rule is a little like that for Word documents:
- .P1
- # man index entries are synthesized
- type is text
- data matches '([a-zA-Z0-9_\e-./]+)\e(([0-9])\e)'
- plumb start man $2 $1 | \e
- plumb -i -d edit -a action=showdata -a filename=/man/$1($2)
- .P2
- .LP
- There are many other inventive uses of plumbing.
- One more should give some of the flavor.
- We have a shell script,
- .CW src ,
- that takes as argument the name of an executable binary file.
- It examines the symbol table of the binary to find the source file
- from which it was compiled.
- Since the Plan 9 compilers place full source path names in the symbol table,
- .CW src
- can discover the complete file name.
- That is then passed to
- .CW plumb ,
- complete with the line number to find the
- symbol
- .CW main .
- For example,
- .P1
- % src plumb
- .P2
- is all it takes to pop up an editor window on the
- .CW main
- routine of the
- .CW plumb
- command, beginning at line 39 of
- .CW /sys/src/cmd/plumb/plumb.c .
- Like most uses of plumbing,
- this is not a breakthrough in functionality, but it is a great convenience.
- .SH
- Why This Architecture?
- .LP
- The design of the plumbing system is peculiar:
- a centralized language-based file server does most of the work,
- while compared to other systems the applications themselves
- contribute relatively little.
- This architecture is deliberate, of course.
- .LP
- That the plumber's behavior is derived from a linguistic description
- gives the system great flexibility and dynamism\(emrules can be added
- and changed at will, without rebooting\(embut the existence of a central library of rules
- ensures that, for most users, the environment behaves in well-established ways.
- .LP
- That the plumber is a file server is perhaps the most unusual aspect of its design,
- but is also one of the most important.
- Messages are passed by regular I/O operations on files, so no extra technology
- such as remote procedure call or request brokers needs to be provided;
- messages are transmitted by familiar means.
- Almost every service in Plan 9 is a file server, so services can be exported
- trivially using the system's remote file system operations [Pike93].
- The plumber is no exception;
- plumbing messages pass routinely across the network to remote applications without
- any special provision,
- in contrast to some commercial IPC mechanisms that become
- significantly more complex when they involve multiple machines.
- As I write this, my window system is talking to applications running on three
- different machines, but they all share a single instance of the plumber and so
- can interoperate to integrate my environment.
- Plan 9 uses a shared file name space
- to combine multiple networked machines\(emcompute servers,
- file servers, and interactive workstations\(eminto a single
- computing environment; plumbing's design as a file server
- is a natural by-product of, and contributor to, the overall system architecture
- [Pike92].
- .LP
- The centrality of the plumber is also unusual.
- Other systems tend to let the applications determine where messages will go;
- consider mail readers that recognize and highlight URLs in the messages.
- Why should just the mail readers do this, and why should they just do it for URLs?
- (Acme was guilty of similar crimes.)
- The plumber, by removing such decisions to a central authority,
- guarantees that all applications behave the same and simultaneously
- frees them all from figuring out what's important.
- The ability for the plumber to excerpt useful data from within a message
- is critical to the success of this model.
- .LP
- The entire system is remarkably small.
- The plumber itself is only about two thousand lines of C code.
- Most applications work fine in a plumbing environment without knowing about it at all;
- some need trivial changes such as to standardize their error output;
- a few need to generate and receive plumbing messages.
- But even to add the ability to send and receive messages in a program such as text editor is short work,
- involving typically a few dozen lines of code.
- Plumbing fits well into the existing environment.
- .LP
- But plumbing is new and it hasn't been pushed far enough yet.
- Most of the work so far has been with textual messages, although
- the underlying system is capable of handling general data.
- We plan to reimplement some of the existing data movement operations,
- such as cut and paste or drag and drop, to use plumbing as their exchange mechanism.
- Since the plumber is a central message handler, it is an obvious place to store the `clipboard'.
- The clipboard could be built as a special port that holds onto messages rather than
- deleting them after delivery.
- Since the clipboard would then be holding a plumbing
- message rather than plain text, as in the current Plan 9 environment,
- it would become possible to cut and paste arbitrary data without
- providing new mechanism.
- In effect, we would be providing a new user interface to the existing plumbing facilities.
- .LP
- Another possible extension is the ability to override plumbing operations interactively.
- Originally, the plan was to provide a mechanism, perhaps a pop-up menu, that one could
- use to direct messages, for example to send a PostScript file to the editor rather than the
- PostScript viewer by naming an explicit destination in the message.
- Although this deficiency should one day be addressed, it should be done without
- complicating the interface for invoking the default behavior.
- Meanwhile, in practice the default behavior seems to work very well in practice\(emas it
- must if plumbing is to be successful\(emso the lack of
- overrides is not keenly felt.
- .SH
- Comparison with Other Systems
- .LP
- The ideas of the plumbing system grew from an
- attempt to generalize the way Acme acquires files and data.
- Systems further from that lineage also share some properties with plumbing.
- Most, however, require explicit linking or message passing rather than
- plumbing's implicit, context-based pattern matching, and none
- has the plumber's design of a language-based file server.
- .LP
- Reiss's FIELD system [Reis95] probably comes the closest to providing the facilities of the plumber.
- It has a central message-passing mechanism that connects applications together through
- a combination of a library and a pattern-matching central message dispatcher that handles
- message send and reply.
- The main differences between FIELD's message dispatcher and the plumber are first
- that the plumber is based on a special-purpose language while the FIELD
- system uses an object-oriented library, second that the plumber has no concept
- of a reply to a message, and finally that the FIELD system
- has no concept of port.
- But the key distinction is probably in the level of use.
- In FIELD, the message dispatcher is a critical integrating force of the underlying
- programming environment, handling everything from debugging events to
- changing the working directory of a program.
- Plumbing, by contrast, is intended primarily for integrating the user interface
- of existing tools; it is more modest and very much simpler.
- The central advantage of the plumber is its convenience and dynamism;
- the FIELD system does not share the ease with which
- message dispatch rules can be added or modified.
- .LP
- The inspiration for Acme was
- the user interface to the object-oriented Oberon system [WiGu92].
- Oberon's user interface interprets mouse clicks on strings such as
- .CW Obj.meth
- to invoke calls to the method
- .CW meth
- of the object
- .CW Obj .
- This was the starting point for Acme's middle-button execution [Pike94],
- but nothing in Oberon is much like Acme's right-button `acquisition',
- which was the starting point for the plumber.
- Oberon's implicit method-based linking is not nearly as general as the pattern-matched
- linking of the plumber, nor does its style of user-triggered method call
- correspond well to the more general idea of inter-application communication
- of plumbing messages.
- .LP
- Microsoft's OLE interface is another relative.
- It allows one application to
- .I embed
- its own data within another's,
- for example to place an Excel spreadsheet within a Frame document;
- when Frame needs to format the page, it will start Excel itself, or at least some of its
- DLLs, to format the spreadsheet.
- OLE data can only be understood by the application that created it;
- plumbing messages, by contrast, contain arbitrary data with a rigidly formatted header
- that will be interpreted by the pattern matcher and the destination application.
- The plumber's simplified message format may limit its
- flexibility but makes messages easy and efficient to dispatch and to interpret.
- At least for the cut-and-paste style of exchange OLE encourages,
- plumbing gives up some power in return for simplicity, while avoiding
- the need to invoke a vestigial program (if Excel can be called a vestige) every time
- the pasted data is examined.
- Plumbing is also better suited to
- other styles of data exchange, such as connecting compiler errors to the
- text editor.
- .LP
- The Hyperbole [Wein] package for Emacs adds hypertext facilities to existing documents.
- It includes explicit links and, like plumbing, a rule-driven way to form implicit links.
- Since Emacs is purely textual, like Acme, Hyperbole does not easily extend to driving
- graphical applications, nor does it provide a general interprocess communication method.
- For instance, although Hyperbole provides some integration for mail applications,
- it cannot provide the glue that allows a click on a face icon in an external program to open a
- mail message within the viewer.
- Moreover, since it is not implemented as a file server,
- Hyperbole does not share the advantages of that architecture.
- .LP
- Henry's
- .CW error
- program in 4BSD echoes a small but common use of plumbing.
- It takes the error messages produced by a compiler and drives a text editor
- through the steps of looking at each one in turn; the notion is to quicken the
- compile/edit/debug cycle.
- Similar results are achieved in EMACS by writing special M-LISP
- macros to parse the error messages from various compilers.
- Although for this particular purpose they may be more convenient than plumbing,
- these are specific solutions to a specific problem and lack plumbing's generality.
- .LP
- Of course, the resource forks in MacOS and the association rules for
- file name extensions in Windows also provide some of the functionality of
- the plumber, although again without the generality or dynamic nature.
- .LP
- Closer to home, Ousterhout's Tcl (Tool Command Language) [Oust90]
- was originally designed to embed a little command interpreter
- in each application to control interprocess communication and
- provide a level of integration.
- Plumbing, on the other hand, provides minimal support within
- the application, offloading most of the message handling and all the
- command execution to the central plumber.
- .LP
- The most obvious relative to plumbing is perhaps the hypertext links of a web browser.
- Plumbing differs by synthesizing
- the links on demand.
- Rather than constructing links within a document as in HTML,
- plumbing uses the context of a button click to derive what it should link to.
- That the rules for this decision can be modified dynamically gives it a more
- fluid feel than a standard web browsing world.
- One possibility for future work is to adapt a web browser to use
- plumbing as its link-following engine, much as Acme used plumbing to offload
- its acquisition rules.
- This would connect the web browser to the existing tools, rather than the
- current trend in most systems of replacing the tools by a browser.
- .LP
- Each of these prior systems\(emand there are others, e.g. [Pasa93, Free93]\(emaddresses
- a particular need or subset of the
- issues of system integration.
- Plumbing differs because its particular choices were different.
- It focuses on two key issues:
- centralizing and automating the handling of interprocess communication
- among interactive programs,
- and maximizing the convenience (or minimizing the trouble) for the human user
- of its services.
- Moreover, the plumber's implementation as a file server, with messages
- passed over files it controls,
- permits the architecture to work transparently across a network.
- None of the other systems discussed here integrates distributed systems
- as smoothly as local ones without the addition of significant extra technology.
- .SH
- Discussion
- .LP
- There were a few surprises during the development of plumbing.
- The first version of plumbing was done for the Inferno system [Dorw97a,Dorw97b],
- using its file-to-channel mechanism to mediate the IPC.
- Although it was very simple to build, it encountered difficulties because
- the plumber was too disconnected from its clients; in particular, there was
- no way to discover whether a port was in use.
- When plumbing was implemented afresh for Plan 9, it was provided through a true file server.
- Although this was much more work, it paid off handsomely.
- The plumber now knows whether a port is open, which makes it easy to decide whether
- a new program must be started to handle a message,
- and the ability to edit the rules file dynamically is a major advantage.
- Other advantages arise from the file-server design,
- such as
- the ease of exporting plumbing ports across the network to remote machines
- and the implicit security model a file-based interface provides: no one has
- permission to open my private plumbing files.
- .LP
- On the other hand, Inferno was an all-new environment and the user interface for plumbing was
- able to be made uniform for all applications.
- This was impractical for Plan 9, so more
- .I "ad hoc
- interfaces had to be provided for that environment.
- Yet even in Plan 9 the advantages of efficient,
- convenient, dynamic interprocess communication outweigh the variability of
- the user interface.
- In fact, it is perhaps a telling point that the system works well for a variety of interfaces;
- the provision of a central, convenient message-passing
- service is a good idea regardless of how the programs use it.
- .LP
- Plumbing's rule language uses only regular expressions and a few special
- rules such as
- .CW isfile
- for matching text.
- There is much more that could be done. For example, in the current system a JPEG
- file can be recognized by a
- .CW .jpg
- suffix but not by its contents, since the plumbing language has no facility
- for examining the
- .I contents
- of files named in its messages.
- To address this issue without adding more special rules requires rethinking
- the language itself.
- Although the current system seems a good balance of complexity
- and functionality,
- perhaps a richer, more general-purpose language would
- permit more exotic applications of the plumbing model.
- .LP
- In conclusion, plumbing adds an effective, easy-to-use inter-application
- communication mechanism to the Plan 9
- user interface.
- Its unusual design as a language-driven file server makes it easy to add
- context-dependent, dynamically interpreted, general-purpose hyperlinks
- to the desktop, for both existing tools and new ones.
- .SH
- Acknowledgements
- .LP
- Dave Presotto wrote the mail file system and
- .CW edmail .
- He, Russ Cox, Sape Mullender, and Cliff Young influenced the design, offered useful suggestions,
- and suffered early versions of the software.
- They also made helpful comments on this paper, as did Dennis Ritchie and Brian Kernighan.
- .SH
- References
- .LP
- [Dorw97a]
- Sean Dorward, Rob Pike, David Leo Presotto, Dennis M. Ritchie,
- Howard W. Trickey, and Philip Winterbottom,
- ``Inferno'',
- .I "Proceedings of the IEEE Compcon 97 Conference" ,
- San Jose, 1997, pp. 241-244.
- .LP
- [Dorw97b]
- Sean Dorward, Rob Pike, David Leo Presotto, Dennis M. Ritchie,
- Howard W. Trickey, and Philip Winterbottom,
- ``The Inferno Operating System'',
- .I "Bell Labs Technical Journal" ,
- .B 2 ,
- 1, Winter, 1997.
- .LP
- [Free93]
- FreeBSD,
- Syslog configuration file manual
- .I syslog.conf (0).
- .LP
- [Kill84]
- T. J. Killian,
- ``Processes as Files'',
- .I "Proceedings of the Summer 1984 USENIX Conference" ,
- Salt Lake City, 1984, pp. 203-207.
- .LP
- [Oust90]
- John K. Ousterhout,
- ``Tcl: An Embeddable Command Languages'',
- .I "Proceedings of the Winter 1990 USENIX Conference" ,
- Washington, 1990, pp. 133-146.
- .LP
- [Pasa93]
- Vern Paxson and Chris Saltmarsh,
- "Glish: A User-Level Software Bus for Loosely-Coupled Distributed Systems" ,
- .I "Proceedings of the Winter 1993 USENIX Conference" ,
- San Diego, 1993, pp. 141-155.
- .LP
- [Pike87a]
- Rob Pike,
- ``Structural Regular Expressions'',
- .I "EUUG Spring 1987 Conference Proceedings" ,
- Helsinki, May 1987, pp. 21-28.
- .LP
- [Pike87b]
- Rob Pike,
- ``The Text Editor sam'',
- .I "Software - Practice and Experience" ,
- .B 17 ,
- 5, Nov. 1987, pp. 813-845.
- .LP
- [Pike91]
- Rob Pike,
- ``8½, the Plan 9 Window System'',
- .I "Proceedings of the Summer 1991 USENIX Conference" ,
- Nashville, 1991, pp. 257-265.
- .LP
- [Pike93]
- Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom,
- ``The Use of Name Spaces in Plan 9'',
- .I "Operating Systems Review" ,
- .B 27 ,
- 2, April 1993, pp. 72-76.
- .LP
- [Pike94]
- Rob Pike,
- ``Acme: A User Interface for Programmers'',
- .I "Proceedings of the Winter 1994 USENIX Conference",
- San Francisco, 1994, pp. 223-234.
- .LP
- [PiPr85]
- Rob Pike and Dave Presotto,
- ``Face the Nation'',
- .I "Proceedings of the USENIX Summer 1985 Conference" ,
- Portland, 1985, pg. 81.
- .LP
- [Reis95]
- Steven P. Reiss,
- .I "The FIELD Programming Environment: A Friendly Integrated Environment for Learning and Development" ,
- Kluwer, Boston, 1995.
- .LP
- [Wein]
- Bob Weiner,
- .I "Hyperbole User Manual" ,
- .CW http://www.cs.indiana.edu/elisp/hyperbole/hyperbole_1.html
- .LP
- [Wint94]
- Philip Winterbottom,
- ``ACID: A Debugger based on a Language'',
- .I "Proceedings of the USENIX Winter Conference" ,
- San Francisco, CA, 1994.
- .LP
- [WiGu92]
- Niklaus Wirth and Jurg Gutknecht,
- .I "Project Oberon: The Design of an Operating System and Compilers" ,
- Addison-Wesley, Reading, 1992.
|