1*426d2b71SDavid du Colombier.HTML "Plumbing and Other Utilities 27dd7cddfSDavid du Colombier.TL 37dd7cddfSDavid du ColombierPlumbing and Other Utilities 47dd7cddfSDavid du Colombier.AU 57dd7cddfSDavid du ColombierRob Pike 67dd7cddfSDavid du Colombier.AI 77dd7cddfSDavid du Colombier.MH 87dd7cddfSDavid du Colombier.AB 97dd7cddfSDavid du Colombier.LP 107dd7cddfSDavid du ColombierPlumbing is a new mechanism for inter-process communication in Plan 9, 117dd7cddfSDavid du Colombierspecifically the passing of messages between interactive programs as part of 127dd7cddfSDavid du Colombierthe user interface. 137dd7cddfSDavid du ColombierAlthough plumbing shares some properties with familiar notions 147dd7cddfSDavid du Colombiersuch as cut and paste, 157dd7cddfSDavid du Colombierit offers a more general data exchange mechanism without imposing 167dd7cddfSDavid du Colombiera particular user interface. 177dd7cddfSDavid du Colombier.LP 187dd7cddfSDavid du ColombierThe core of the plumbing system is a program called the 197dd7cddfSDavid du Colombier.I plumber , 207dd7cddfSDavid du Colombierwhich handles all messages and dispatches and reformats them 217dd7cddfSDavid du Colombieraccording to configuration rules written in a special-purpose language. 227dd7cddfSDavid du ColombierThis approach allows the contents and context of a piece of data to define how 237dd7cddfSDavid du Colombierit is handled. 247dd7cddfSDavid du ColombierUnlike with drag and drop or cut and paste, 257dd7cddfSDavid du Colombierthe user doesn't need to deliver the data; 267dd7cddfSDavid du Colombierthe contents of a plumbing message, as interpreted by the plumbing rules, 277dd7cddfSDavid du Colombierdetermine its destination. 287dd7cddfSDavid du Colombier.LP 297dd7cddfSDavid du ColombierThe plumber has an unusual architecture: it is a language-driven file server. 307dd7cddfSDavid du ColombierThis design has distinct advantages. 317dd7cddfSDavid du ColombierIt makes plumbing easy to add to an existing, Unix-like command environment; 327dd7cddfSDavid du Colombierit guarantees uniform handling of inter-application messages; 337dd7cddfSDavid du Colombierit off-loads from those applications most of the work of extracting and dispatching messages; 347dd7cddfSDavid du Colombierand it works transparently across a network. 357dd7cddfSDavid du Colombier.AE 367dd7cddfSDavid du Colombier.SH 377dd7cddfSDavid du ColombierIntroduction 387dd7cddfSDavid du Colombier.LP 397dd7cddfSDavid du ColombierData moves from program to program in myriad ways. 407dd7cddfSDavid du ColombierCommand-line arguments, 417dd7cddfSDavid du Colombiershell pipe lines, 427dd7cddfSDavid du Colombiercut and paste, 437dd7cddfSDavid du Colombierdrag and drop, and other user interface techniques all provide some form 447dd7cddfSDavid du Colombierof interprocess communication. 457dd7cddfSDavid du ColombierThen there are tricks associated with special domains, 467dd7cddfSDavid du Colombiersuch as HTML hyperlinks or the heuristics mail readers 477dd7cddfSDavid du Colombieruse to highlight URLs embedded in mail messages. 487dd7cddfSDavid du ColombierSome systems provide implicit ways to automate the attachment of program to data\(emthe 497dd7cddfSDavid du Colombierbest known examples are probably the resource forks in MacOS and the 507dd7cddfSDavid du Colombierfile name extension `associations' in Microsoft Windows\(embut in practice 517dd7cddfSDavid du Colombierhumans must too often carry their data from program to program. 527dd7cddfSDavid du Colombier.LP 537dd7cddfSDavid du ColombierWhy should a human do the work? 547dd7cddfSDavid du ColombierUsually there is one obvious thing to do with a piece of data, 557dd7cddfSDavid du Colombierand the data itself suggests what this is. 567dd7cddfSDavid du ColombierResource forks and associations speak to this issue directly, but statically and narrowly and with 577dd7cddfSDavid du Colombierlittle opportunity to control the behavior. 587dd7cddfSDavid du ColombierMechanisms with more generality, 597dd7cddfSDavid du Colombiersuch as cut and paste or drag and drop, demand too much manipulation by 607dd7cddfSDavid du Colombierthe user and are (therefore) too error-prone. 617dd7cddfSDavid du Colombier.LP 627dd7cddfSDavid du ColombierWe want a system that, given a piece of data, 637dd7cddfSDavid du Colombierhands it to the appropriate application by default with little or no human intervention, 647dd7cddfSDavid du Colombierwhile still permitting the user to override the defaults if desired. 657dd7cddfSDavid du Colombier.LP 667dd7cddfSDavid du ColombierThe plumbing system is an attempt to address some of these issues in a single, 677dd7cddfSDavid du Colombiercoherent, central way. 687dd7cddfSDavid du ColombierIt provides a mechanism for 697dd7cddfSDavid du Colombierformatting and sending arbitrary messages between applications, 707dd7cddfSDavid du Colombiertypically interactive programs such as text editors, web browsers, and the window system, 717dd7cddfSDavid du Colombierunder the control of a central message-handling server called the 727dd7cddfSDavid du Colombier.I plumber . 737dd7cddfSDavid du ColombierInteractive programs provide application-specific connections to the plumber, 747dd7cddfSDavid du Colombiertriggering with minimal user action the transfer of data or control to other programs. 757dd7cddfSDavid du ColombierThe result is similar to a hypertext system in which all the links are implicit, 767dd7cddfSDavid du Colombierextracted automatically by examining the data and the user's actions. 777dd7cddfSDavid du ColombierIt obviates 787dd7cddfSDavid du Colombiercut and paste and other such hand-driven interprocess communication mechanisms. 797dd7cddfSDavid du ColombierPlumbing delivers the goods to the right place automatically. 807dd7cddfSDavid du Colombier.SH 817dd7cddfSDavid du ColombierOverview 827dd7cddfSDavid du Colombier.LP 837dd7cddfSDavid du ColombierThe plumber is implemented as a Plan 9 file server [Pike93]; 847dd7cddfSDavid du Colombierprograms send messages by writing them to the plumber's file 857dd7cddfSDavid du Colombier.CW /mnt/plumb/send , 867dd7cddfSDavid du Colombierand receive messages by reading them from 877dd7cddfSDavid du Colombier.I ports , 887dd7cddfSDavid du Colombierwhich are other plumber files in 897dd7cddfSDavid du Colombier.CW /mnt/plumb . 907dd7cddfSDavid du ColombierFor example, 917dd7cddfSDavid du Colombier.CW /mnt/plumb/edit 927dd7cddfSDavid du Colombieris by convention the file from which a text editor reads messages requesting it to 937dd7cddfSDavid du Colombieropen and display a file for editing. 947dd7cddfSDavid du Colombier(See Figure 1.) 95*426d2b71SDavid du Colombier.if h .B1 10 60 967dd7cddfSDavid du Colombier.KF 977dd7cddfSDavid du Colombier.PS 987dd7cddfSDavid du Colombierdown 997dd7cddfSDavid du ColombierP1: ellipse "ProgramA" 1007dd7cddfSDavid du Colombiermove 1017dd7cddfSDavid du ColombierP2: ellipse "ProgramB" 1027dd7cddfSDavid du Colombiermove 1037dd7cddfSDavid du ColombierP3: ellipse "ProgramC" 1047dd7cddfSDavid du Colombierright 1057dd7cddfSDavid du ColombierINVIS: box wid 1.3 invis at P2.e 1067dd7cddfSDavid du ColombierSEND: arrow from INVIS.e "\f(CWsend \fP" "" 1077dd7cddfSDavid du Colombierarrow -> right 0.2 from P1.e; spline -> right 0.2 then down 1 to SEND.w 1087dd7cddfSDavid du Colombierarrow -> right 0.2 from P2.e; arrow -> to SEND.w 1097dd7cddfSDavid du Colombierarrow -> right 0.2 from P3.e; spline -> right 0.2 then up 1 to SEND.w 1107dd7cddfSDavid du Colombierright 1117dd7cddfSDavid du ColombierPL: box height 1 "plumber" with .w at SEND.e 1127dd7cddfSDavid du ColombierA3: arrow 0.8 -> "\f(CWimage\fP" ""; arrow -> 1137dd7cddfSDavid du ColombierO3: ellipse "Viewer" 1147dd7cddfSDavid du ColombierO2: ellipse "Browser" with .s at O3.n + (0, 0.1) 1157dd7cddfSDavid du ColombierO1: ellipse "Editor" with .s at O2.n + (0, 0.1) 1167dd7cddfSDavid du ColombierO4: ellipse "Faces" with .n at O3.s + (0, -0.1) 1177dd7cddfSDavid du ColombierO5: ellipse "..." with .n at O4.s + (0, -0.1) 1187dd7cddfSDavid du Colombierright 1197dd7cddfSDavid du ColombierA1: arrow 0.8 -> "\f(CWedit\fP" "" from PL.e + (0, .4); spline -> right 0.15 then up 0.7 then to O1.w 1207dd7cddfSDavid du Colombierright 1217dd7cddfSDavid du ColombierA2: arrow 0.8 -> "\f(CWweb\fP" "" from PL.e + (0, .2); spline -> right 0.3 then up 0.3 then to O2.w 1227dd7cddfSDavid du Colombierright 1237dd7cddfSDavid du ColombierA4: arrow 0.8 -> "\f(CWnewmail\fP" "" from PL.e + (0, -.2); spline -> right 0.3 then down 0.3 then to O4.w 1247dd7cddfSDavid du Colombierright 1257dd7cddfSDavid du ColombierA5: arrow 0.8 -> "\f(CW...\fP" "" from PL.e + (0, -.4); spline -> right 0.15 then down 0.7 then to O5.w 1267dd7cddfSDavid du Colombier.PE 1277dd7cddfSDavid du Colombier.IP 1287dd7cddfSDavid du Colombier.ps -1 1297dd7cddfSDavid du ColombierFigure 1. The plumber controls the flow of messages between applications. 1307dd7cddfSDavid du ColombierPrograms write to the file 1317dd7cddfSDavid du Colombier.CW send 1327dd7cddfSDavid du Colombierand receive on `ports' of various names representing services such as 1337dd7cddfSDavid du Colombier.CW edit 1347dd7cddfSDavid du Colombieror 1357dd7cddfSDavid du Colombier.CW web . 1367dd7cddfSDavid du ColombierAlthough the figure doesn't illustrate it, some programs may both send and receive messages, 1377dd7cddfSDavid du Colombierand some ports are read by multiple applications. 1387dd7cddfSDavid du Colombier.sp 1397dd7cddfSDavid du Colombier.KE 140*426d2b71SDavid du Colombier.if h .B2 1417dd7cddfSDavid du Colombier.LP 1427dd7cddfSDavid du ColombierThe plumber takes messages from the 1437dd7cddfSDavid du Colombier.CW send 1447dd7cddfSDavid du Colombierfile and interprets their contents using rules defined by 1457dd7cddfSDavid du Colombiera special-purpose pattern-action language. 1467dd7cddfSDavid du ColombierThe language specifies any rewriting of the message that is to be done by the plumber 1477dd7cddfSDavid du Colombierand defines how to dispose of a message, such as by sending it to a port or 1487dd7cddfSDavid du Colombierstarting a new process to handle it. 1497dd7cddfSDavid du Colombier.LP 1507dd7cddfSDavid du ColombierThe behavior is best described by example. 1517dd7cddfSDavid du ColombierImagine that the user has, in a terminal emulator window, 1527dd7cddfSDavid du Colombierjust run a compilation that has failed: 1537dd7cddfSDavid du Colombier.P1 1547dd7cddfSDavid du Colombier% make 1557dd7cddfSDavid du Colombiercc -c rmstar.c 1567dd7cddfSDavid du Colombierrmstar.c:32: syntax error 1577dd7cddfSDavid du Colombier\&... 1587dd7cddfSDavid du Colombier.P2 1597dd7cddfSDavid du ColombierThe user points the typing cursor somewhere in the string 1607dd7cddfSDavid du Colombier.CW rmstar.c:32: 1617dd7cddfSDavid du Colombierand executes the 1627dd7cddfSDavid du Colombier.CW plumb 1637dd7cddfSDavid du Colombiermenu entry. 1647dd7cddfSDavid du ColombierThis causes the terminal emulator to format a plumbing message 1657dd7cddfSDavid du Colombiercontaining the entire string surrounding the cursor, 1667dd7cddfSDavid du Colombier.CW rmstar:32: , 1677dd7cddfSDavid du Colombierand to write it to 1687dd7cddfSDavid du Colombier.CW /mnt/plumb/send . 1697dd7cddfSDavid du ColombierThe plumber receives this message and compares it sequentially to the various 1707dd7cddfSDavid du Colombierpatterns in its configuration. 1717dd7cddfSDavid du ColombierEventually, it will find one that breaks the string into pieces, 1727dd7cddfSDavid du Colombier.CW rmstar.c , 1737dd7cddfSDavid du Colombiera colon, 1747dd7cddfSDavid du Colombier.CW 32 , 1757dd7cddfSDavid du Colombierand the final colon. 1767dd7cddfSDavid du ColombierOther associated patterns verify that 1777dd7cddfSDavid du Colombier.CW rmstar.c 1787dd7cddfSDavid du Colombieris a file in the current directory of the program generating 1797dd7cddfSDavid du Colombierthe message, and that 1807dd7cddfSDavid du Colombier.CW 32 1817dd7cddfSDavid du Colombierlooks like a line number within it. 1827dd7cddfSDavid du ColombierThe plumber rewrites the message, 1837dd7cddfSDavid du Colombiersetting the data to the string 1847dd7cddfSDavid du Colombier.CW rmstar.c 1857dd7cddfSDavid du Colombierand attaching an indication that 1867dd7cddfSDavid du Colombier.CW 32 1877dd7cddfSDavid du Colombieris a line number to display. 1887dd7cddfSDavid du ColombierFinally, it sends the resulting message to the 1897dd7cddfSDavid du Colombier.CW edit 1907dd7cddfSDavid du Colombierport. 1917dd7cddfSDavid du ColombierThe text editor picks up the message, opens 1927dd7cddfSDavid du Colombier.CW rmstar.c 1937dd7cddfSDavid du Colombier(if it's not already open) and highlights line 32, the location of the syntax error. 1947dd7cddfSDavid du Colombier.LP 1957dd7cddfSDavid du ColombierFrom the user's point of view, this process is simple: the error message appears, 1967dd7cddfSDavid du Colombierit is `plumbed', and the editor jumps to the problem. 1977dd7cddfSDavid du Colombier.LP 1987dd7cddfSDavid du ColombierOf course, there are many different ways to cause compiler messages to 1997dd7cddfSDavid du Colombierpop up the source of an error, 2007dd7cddfSDavid du Colombierbut the design of the plumber addresses more general issues than the specific 2017dd7cddfSDavid du Colombiergoal of shortening the compile/debug/edit cycle. 2027dd7cddfSDavid du ColombierIt facilitates the general exchange of data among programs, interactive or otherwise, 2037dd7cddfSDavid du Colombierthroughout the environment, and its 2047dd7cddfSDavid du Colombierarchitecture\(ema central, language-driven file server\(emalthough 2057dd7cddfSDavid du Colombierunusual, has distinct advantages. 2067dd7cddfSDavid du ColombierIt makes plumbing easy to add to an existing, Unix-like command environment; 2077dd7cddfSDavid du Colombierit guarantees uniform handling of inter-application messages; 2087dd7cddfSDavid du Colombierit off-loads from those applications most of the work of extracting and dispatching messages; 2097dd7cddfSDavid du Colombierand it works transparently and effortlessly across a network. 2107dd7cddfSDavid du Colombier.LP 2117dd7cddfSDavid du ColombierThis paper is organized bottom-up, beginning with the format of the messages 2127dd7cddfSDavid du Colombierand proceeding through the plumbing language, the handling of messages, 2137dd7cddfSDavid du Colombierand the interactive user interface. 2147dd7cddfSDavid du ColombierThe last sections discuss the implications of the design 2157dd7cddfSDavid du Colombierand compare the plumbing system to other environments that 2167dd7cddfSDavid du Colombierprovide similar services. 2177dd7cddfSDavid du Colombier.SH 2187dd7cddfSDavid du ColombierFormat of messages 2197dd7cddfSDavid du Colombier.LP 2207dd7cddfSDavid du ColombierSince the language that controls the plumber is defined in terms of the 2217dd7cddfSDavid du Colombiercontents of plumbing messages, we begin by describing their layout. 2227dd7cddfSDavid du Colombier.LP 2237dd7cddfSDavid du ColombierPlumbing messages have a fixed-format textual 2247dd7cddfSDavid du Colombierheader followed by a free-format data section. 2257dd7cddfSDavid du ColombierThe header consists of six lines of text, in set order, 2267dd7cddfSDavid du Colombiereach specifying a property of the message. 2277dd7cddfSDavid du ColombierAny line may be blank except the last, which is the length of the data portion of the 2287dd7cddfSDavid du Colombiermessage, as a decimal string. 2297dd7cddfSDavid du ColombierThe lines are, in order: 2307dd7cddfSDavid du Colombier.IP 2317dd7cddfSDavid du ColombierThe source application, the name of the program generating the message. 2327dd7cddfSDavid du Colombier.IP 2337dd7cddfSDavid du ColombierThe destination port, the name of the port to which the messages should be sent. 2347dd7cddfSDavid du Colombier.IP 2357dd7cddfSDavid du ColombierThe working directory in which the message was generated. 2367dd7cddfSDavid du Colombier.IP 2377dd7cddfSDavid du ColombierThe type of the data, analogous to a MIME type, such as 2387dd7cddfSDavid du Colombier.CW text 2397dd7cddfSDavid du Colombieror 2407dd7cddfSDavid du Colombier.CW image/gif . 2417dd7cddfSDavid du Colombier.IP 2427dd7cddfSDavid du ColombierAttributes of the message, given as blank-separated 2437dd7cddfSDavid du Colombier.I name\f(CW=\fPvalue 2447dd7cddfSDavid du Colombierpairs. 2457dd7cddfSDavid du ColombierThe values may be quoted to protect 2467dd7cddfSDavid du Colombierblanks or quotes; values may not contain newlines. 2477dd7cddfSDavid du Colombier.IP 2487dd7cddfSDavid du ColombierThe length of the data section, in bytes. 2497dd7cddfSDavid du Colombier.LP 2507dd7cddfSDavid du ColombierHere is a sample message, one that (conventionally) tells the editor to open the file 2517dd7cddfSDavid du Colombier.CW /usr/rob/src/mem.c 2527dd7cddfSDavid du Colombierand display line 2537dd7cddfSDavid du Colombier27 within it: 2547dd7cddfSDavid du Colombier.P1 2557dd7cddfSDavid du Colombierplumbtest 2567dd7cddfSDavid du Colombieredit 2577dd7cddfSDavid du Colombier/usr/rob/src 2587dd7cddfSDavid du Colombiertext 2597dd7cddfSDavid du Colombieraddr=27 2607dd7cddfSDavid du Colombier5 2617dd7cddfSDavid du Colombiermem.c 2627dd7cddfSDavid du Colombier.P2 2637dd7cddfSDavid du ColombierBecause in general it need not be text, the data section of the message has no terminating newline. 2647dd7cddfSDavid du Colombier.LP 2657dd7cddfSDavid du ColombierA library interface simplifies the processing of messages by translating them 2667dd7cddfSDavid du Colombierto and from a data structure, 2677dd7cddfSDavid du Colombier.CW Plumbmsg , 2687dd7cddfSDavid du Colombierdefined like this: 2697dd7cddfSDavid du Colombier.P1 2707dd7cddfSDavid du Colombier.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n 2717dd7cddfSDavid du Colombiertypedef struct Plumbattr Plumbattr; 2727dd7cddfSDavid du Colombiertypedef struct Plumbmsg Plumbmsg; 2737dd7cddfSDavid du Colombier 2747dd7cddfSDavid du Colombierstruct Plumbmsg 2757dd7cddfSDavid du Colombier{ 2767dd7cddfSDavid du Colombier char *src; /* source application */ 2777dd7cddfSDavid du Colombier char *dst; /* destination port */ 2787dd7cddfSDavid du Colombier char *wdir; /* working directory */ 2797dd7cddfSDavid du Colombier char *type; /* type of data */ 2807dd7cddfSDavid du Colombier Plumbattr *attr; /* attribute list */ 2817dd7cddfSDavid du Colombier int ndata; /* #bytes of data */ 2827dd7cddfSDavid du Colombier char *data; 2837dd7cddfSDavid du Colombier}; 2847dd7cddfSDavid du Colombier 2857dd7cddfSDavid du Colombierstruct Plumbattr 2867dd7cddfSDavid du Colombier{ 2877dd7cddfSDavid du Colombier char *name; 2887dd7cddfSDavid du Colombier char *value; 2897dd7cddfSDavid du Colombier Plumbattr *next; 2907dd7cddfSDavid du Colombier}; 2917dd7cddfSDavid du Colombier.P2 2927dd7cddfSDavid du ColombierThe library also includes routines to send a message, receive a message, 2937dd7cddfSDavid du Colombiermanipulate the attribute list, and so on. 2947dd7cddfSDavid du Colombier.SH 2957dd7cddfSDavid du ColombierThe Language 2967dd7cddfSDavid du Colombier.LP 2977dd7cddfSDavid du ColombierAn instance of the plumber runs for each user on each terminal or workstation. 2987dd7cddfSDavid du ColombierIt 2997dd7cddfSDavid du Colombierbegins by reading its rules from the file 3007dd7cddfSDavid du Colombier.CW lib/plumbing 3017dd7cddfSDavid du Colombierin the user's home directory, 3027dd7cddfSDavid du Colombierwhich in turn may use 3037dd7cddfSDavid du Colombier.CW include 3047dd7cddfSDavid du Colombierstatements to interpolate macro definitions and 3057dd7cddfSDavid du Colombierrules from standard plumbing rule libraries stored in 3067dd7cddfSDavid du Colombier.CW /sys/lib/plumb . 3077dd7cddfSDavid du Colombier.LP 3087dd7cddfSDavid du ColombierThe rules control the processing of messages. 3097dd7cddfSDavid du ColombierThey are written in 3107dd7cddfSDavid du Colombiera pattern-action language comprising a sequence of blank-line-separated 3117dd7cddfSDavid du Colombier.I rule 3127dd7cddfSDavid du Colombier.I sets , 3137dd7cddfSDavid du Colombiereach of which contains one or more 3147dd7cddfSDavid du Colombier.I patterns 3157dd7cddfSDavid du Colombierfollowed by one or more 3167dd7cddfSDavid du Colombier.I actions . 3177dd7cddfSDavid du ColombierEach incoming message is compared against the rule sets in order. 3187dd7cddfSDavid du ColombierIf all the patterns within a rule set succeed, 3197dd7cddfSDavid du Colombierone of the associated actions is taken and processing completes. 3207dd7cddfSDavid du Colombier.LP 3217dd7cddfSDavid du ColombierThe syntax of the language is straightforward. 3227dd7cddfSDavid du ColombierEach rule (pattern or action) has three components, separated by white space: 3237dd7cddfSDavid du Colombieran 3247dd7cddfSDavid du Colombier.I object , 3257dd7cddfSDavid du Colombiera 3267dd7cddfSDavid du Colombier.I verb , 3277dd7cddfSDavid du Colombierand optional 3287dd7cddfSDavid du Colombier.I arguments . 3297dd7cddfSDavid du ColombierThe object 3307dd7cddfSDavid du Colombieridentifies a part of the message, such as 3317dd7cddfSDavid du Colombierthe source application 3327dd7cddfSDavid du Colombier.CW src ), ( 3337dd7cddfSDavid du Colombieror the data 3347dd7cddfSDavid du Colombierportion of the message 3357dd7cddfSDavid du Colombier.CW data ), ( 3367dd7cddfSDavid du Colombieror the rule's own arguments 3377dd7cddfSDavid du Colombier.CW arg ); ( 3387dd7cddfSDavid du Colombieror it is the keyword 3397dd7cddfSDavid du Colombier.CW plumb , 3407dd7cddfSDavid du Colombierwhich introduces an action. 3417dd7cddfSDavid du ColombierThe verb specifies an operation to perform on the object, such as the word 3427dd7cddfSDavid du Colombier.CW is ' ` 3437dd7cddfSDavid du Colombierto require precise equality between the object and the argument, or 3447dd7cddfSDavid du Colombier.CW isdir ' ` 3457dd7cddfSDavid du Colombierto require that the object be the name of a directory. 3467dd7cddfSDavid du Colombier.LP 3477dd7cddfSDavid du ColombierFor instance, this rule set sends messages containing the names of files 3487dd7cddfSDavid du Colombierending in 3497dd7cddfSDavid du Colombier.CW .gif , 3507dd7cddfSDavid du Colombier.CW .jpg , 3517dd7cddfSDavid du Colombieretc. to a program, 3527dd7cddfSDavid du Colombier.CW page , 3537dd7cddfSDavid du Colombierto display them; it is analogous to a Windows association rule: 3547dd7cddfSDavid du Colombier.P1 3557dd7cddfSDavid du Colombier# image files go to page 3567dd7cddfSDavid du Colombiertype is text 3577dd7cddfSDavid du Colombierdata matches '[a-zA-Z0-9_\e-./]+' 3587dd7cddfSDavid du Colombierdata matches '([a-zA-Z0-9_\e-./]+)\e.(jpe?g|gif|bit|tiff|ppm)' 3597dd7cddfSDavid du Colombierarg isfile $0 3607dd7cddfSDavid du Colombierplumb to image 3617dd7cddfSDavid du Colombierplumb client page -wi 3627dd7cddfSDavid du Colombier.P2 3637dd7cddfSDavid du Colombier(Lines beginning with 3647dd7cddfSDavid du Colombier.CW # 3657dd7cddfSDavid du Colombierare commentary.) 3667dd7cddfSDavid du ColombierConsider how this rule handles the following message, annotated down the left column for clarity: 3677dd7cddfSDavid du Colombier.P1 3687dd7cddfSDavid du Colombier.ta 10n 3697dd7cddfSDavid du Colombier\f2src\fP plumbtest 3707dd7cddfSDavid du Colombier\f2dst\fP 3717dd7cddfSDavid du Colombier\f2wdir\fP /usr/rob/pics 3727dd7cddfSDavid du Colombier\f2type\fP text 3737dd7cddfSDavid du Colombier\f2attr\fP 3747dd7cddfSDavid du Colombier\f2ndata\fP 9 3757dd7cddfSDavid du Colombier\f2data\fP horse.gif 3767dd7cddfSDavid du Colombier.P2 3777dd7cddfSDavid du ColombierThe 3787dd7cddfSDavid du Colombier.CW is 3797dd7cddfSDavid du Colombierverb specifies a precise match, and the 3807dd7cddfSDavid du Colombier.CW type 3817dd7cddfSDavid du Colombierfield of the message is the string 3827dd7cddfSDavid du Colombier.CW text , 3837dd7cddfSDavid du Colombierso the first pattern succeeds. 3847dd7cddfSDavid du ColombierThe 3857dd7cddfSDavid du Colombier.CW matches 3867dd7cddfSDavid du Colombierverb invokes a regular expression pattern match of the object (here 3877dd7cddfSDavid du Colombier.CW data ) 3887dd7cddfSDavid du Colombieragainst the argument pattern. 3897dd7cddfSDavid du ColombierBoth 3907dd7cddfSDavid du Colombier.CW matches 3917dd7cddfSDavid du Colombierpatterns in this rule set will succeed, and in the process set the variables 3927dd7cddfSDavid du Colombier.CW $0 3937dd7cddfSDavid du Colombierto the matched string, 3947dd7cddfSDavid du Colombier.CW $1 3957dd7cddfSDavid du Colombierto the first parenthesized submatch, and so on (analogous to 3967dd7cddfSDavid du Colombier.CW & , 3977dd7cddfSDavid du Colombier.CW \e1 , 3987dd7cddfSDavid du Colombieretc. in 3997dd7cddfSDavid du Colombier.CW ed 's 4007dd7cddfSDavid du Colombierregular expressions). 4017dd7cddfSDavid du ColombierThe pattern 4027dd7cddfSDavid du Colombier.CW arg 4037dd7cddfSDavid du Colombier.CW isfile 4047dd7cddfSDavid du Colombier.CW $0 4057dd7cddfSDavid du Colombierverifies that the named file, 4067dd7cddfSDavid du Colombier.CW horse.gif , 4077dd7cddfSDavid du Colombieris an actual file in the directory 4087dd7cddfSDavid du Colombier.CW /usr/rob/pics . 4097dd7cddfSDavid du ColombierIf all the patterns succeed, one of the actions will be executed. 4107dd7cddfSDavid du Colombier.LP 4117dd7cddfSDavid du ColombierThere are two actions in this rule set. 4127dd7cddfSDavid du ColombierThe 4137dd7cddfSDavid du Colombier.CW plumb 4147dd7cddfSDavid du Colombier.CW to 4157dd7cddfSDavid du Colombierrule specifies 4167dd7cddfSDavid du Colombier.CW image 4177dd7cddfSDavid du Colombieras the destination port of the message. 4187dd7cddfSDavid du ColombierBy convention, the plumber mounts its services in the directory 4197dd7cddfSDavid du Colombier.CW /mnt/plumb , 4207dd7cddfSDavid du Colombierso in this case if the file 4217dd7cddfSDavid du Colombier.CW /mnt/plumb/image 4227dd7cddfSDavid du Colombierhas been opened, the message will be made available to the program reading from it. 4237dd7cddfSDavid du ColombierNote that the message does not name a port, but the rule set that matches 4247dd7cddfSDavid du Colombierthe message does, and that is sufficient to dispatch the message. 4257dd7cddfSDavid du ColombierIf on the other hand a message matches no rule but has an explicit port mentioned, 4267dd7cddfSDavid du Colombierthat too is sufficient. 4277dd7cddfSDavid du Colombier.LP 4287dd7cddfSDavid du ColombierIf no client has opened the 4297dd7cddfSDavid du Colombier.CW image 4307dd7cddfSDavid du Colombierport, 4317dd7cddfSDavid du Colombierthat is, if the program 4327dd7cddfSDavid du Colombier.CW page 4337dd7cddfSDavid du Colombieris not already running, the 4347dd7cddfSDavid du Colombier.CW plumb 4357dd7cddfSDavid du Colombier.CW client 4367dd7cddfSDavid du Colombieraction gives the execution script to start the application 4377dd7cddfSDavid du Colombierand send the message on its way; the 4387dd7cddfSDavid du Colombier.CW -wi 4397dd7cddfSDavid du Colombierarguments tell 4407dd7cddfSDavid du Colombier.CW page 4417dd7cddfSDavid du Colombierto create a window and to receive its initial arguments from the plumbing port. 4427dd7cddfSDavid du ColombierThe process by which the plumber starts a program is described in more detail in the next section. 4437dd7cddfSDavid du Colombier.LP 4447dd7cddfSDavid du ColombierIt may seem odd that there are two 4457dd7cddfSDavid du Colombier.CW matches 4467dd7cddfSDavid du Colombierrules in this example. 4477dd7cddfSDavid du ColombierThe reason is related to the way the plumber can use the rules themselves 4487dd7cddfSDavid du Colombierto refine the 4497dd7cddfSDavid du Colombier.I data 4507dd7cddfSDavid du Colombierin the message, somewhat in the manner of Structural Regular Expressions [Pike87a]. 4517dd7cddfSDavid du ColombierFor example, consider what happens if the cursor is at the last character of 4527dd7cddfSDavid du Colombier.P1 4537dd7cddfSDavid du Colombier% make nightmare>horse.gif 4547dd7cddfSDavid du Colombier.P2 4557dd7cddfSDavid du Colombierand the user asks to plumb what the cursor is pointing at. 4567dd7cddfSDavid du ColombierThe program creating the plumbing 4577dd7cddfSDavid du Colombiermessage\(emin this case the terminal emulator running the window\(emcan send the 4587dd7cddfSDavid du Colombierentire white-space-delimited string 4597dd7cddfSDavid du Colombier.CW nightmare>horse.gif 4607dd7cddfSDavid du Colombieror even the entire line, and the combination of 4617dd7cddfSDavid du Colombier.CW matches 4627dd7cddfSDavid du Colombierrules can determine that the user was referring to the string 4637dd7cddfSDavid du Colombier.CW horse.gif . 4647dd7cddfSDavid du ColombierThe user could of course select the entire string 4657dd7cddfSDavid du Colombier.CW horse.gif , 4667dd7cddfSDavid du Colombierbut it's more convenient just to point in the general location and let the machine 4677dd7cddfSDavid du Colombierfigure out what should be done. 4687dd7cddfSDavid du ColombierThe process is as follows. 4697dd7cddfSDavid du Colombier.LP 4707dd7cddfSDavid du ColombierThe application generating the message adds a special attribute to the message, named 4717dd7cddfSDavid du Colombier.CW click , 4727dd7cddfSDavid du Colombierwhose numerical value is the offset of the cursor\(emthe selection point\(emwithin the data string. 4737dd7cddfSDavid du ColombierThis attribute tells the plumber two things: 4747dd7cddfSDavid du Colombierfirst, that the regular expressions in 4757dd7cddfSDavid du Colombier.CW matches 4767dd7cddfSDavid du Colombierrules should be used to identify the relevant data; 4777dd7cddfSDavid du Colombierand second, approximately where the relevant data lies. 4787dd7cddfSDavid du ColombierThe plumber 4797dd7cddfSDavid du Colombierwill then use the first 4807dd7cddfSDavid du Colombier.CW matches 4817dd7cddfSDavid du Colombierpattern to identify the longest leftmost match that touches the cursor, which will extract the string 4827dd7cddfSDavid du Colombier.CW horse.gif , 4837dd7cddfSDavid du Colombierand the second pattern will then verify that that names a picture file. 4847dd7cddfSDavid du ColombierThe rule set succeeds and the data is winnowed to the matching substring 4857dd7cddfSDavid du Colombierbefore being sent to its destination. 4867dd7cddfSDavid du Colombier.LP 4877dd7cddfSDavid du ColombierEach 4887dd7cddfSDavid du Colombier.CW matches 4897dd7cddfSDavid du Colombierpattern within a given rule set must match the same portion of the string, which 4907dd7cddfSDavid du Colombierguarantees that the rule set fails to match a string for which the 4917dd7cddfSDavid du Colombiersecond pattern matches only a portion. 4927dd7cddfSDavid du ColombierFor instance, our example rule set should not execute if the data is the string 4937dd7cddfSDavid du Colombier.CW horse.gift , 4947dd7cddfSDavid du Colombierand although the first pattern will match 4957dd7cddfSDavid du Colombier.CW horse.gift , 4967dd7cddfSDavid du Colombierthe second will match only 4977dd7cddfSDavid du Colombier.CW horse.gif 4987dd7cddfSDavid du Colombierand the rule set will fail. 4997dd7cddfSDavid du Colombier.LP 5007dd7cddfSDavid du ColombierThe same approach of multiple 5017dd7cddfSDavid du Colombier.CW matches 5027dd7cddfSDavid du Colombierrules can be used to exclude, for instance, a terminal period from 5037dd7cddfSDavid du Colombiera file name or URL, so a file name or URL at the end of a sentence is recognized properly. 5047dd7cddfSDavid du Colombier.LP 5057dd7cddfSDavid du ColombierIf a 5067dd7cddfSDavid du Colombier.CW click 5077dd7cddfSDavid du Colombierattribute is not specified, all patterns must match the entire string, 5087dd7cddfSDavid du Colombierso the user has an option: 5097dd7cddfSDavid du Colombierhe or she may select exactly what data to send, 5107dd7cddfSDavid du Colombieror may instead indicate where the data is by clicking the selection button on the mouse 5117dd7cddfSDavid du Colombierand letting the machine locate the URL or image file name within the text. 5127dd7cddfSDavid du ColombierIn other words, 5137dd7cddfSDavid du Colombierthe user can control the contents of the message precisely when required, 5147dd7cddfSDavid du Colombierbut the default, simplest action in the user interface does the right thing most of the time. 5157dd7cddfSDavid du Colombier.SH 5167dd7cddfSDavid du ColombierHow Messages are Handled in the Plumber 5177dd7cddfSDavid du Colombier.LP 5187dd7cddfSDavid du ColombierAn application creates a message header, fills in whatever fields it wishes to define, 5197dd7cddfSDavid du Colombierattaches the data, and writes the result to the file 5207dd7cddfSDavid du Colombier.CW send 5217dd7cddfSDavid du Colombierin the plumber's service directory, 5227dd7cddfSDavid du Colombier.CW /mnt/plumb . 5237dd7cddfSDavid du ColombierThe plumber receives the message and applies the plumbing rules successively to it. 5247dd7cddfSDavid du ColombierWhen a rule set matches, the message is dispatched as indicated by that rule set 5257dd7cddfSDavid du Colombierand processing continues with the next message. 5267dd7cddfSDavid du ColombierIf no rule set matches the message, the plumber indicates this by returning a write 5277dd7cddfSDavid du Colombiererror to the application, that is, the write to 5287dd7cddfSDavid du Colombier.CW /mnt/plumb/send 5297dd7cddfSDavid du Colombierfails, with the resulting error string 5307dd7cddfSDavid du Colombierdescribing the failure. 5317dd7cddfSDavid du Colombier(Plan 9 uses strings rather than pre-defined numbers to describe error conditions.) 5327dd7cddfSDavid du ColombierThus a program can discover whether a plumbing message has been sent successfully. 5337dd7cddfSDavid du Colombier.LP 5347dd7cddfSDavid du ColombierAfter a matching rule set has been identified, the plumber applies a series of rewriting 5357dd7cddfSDavid du Colombiersteps to the message. Some rewritings are defined by the rule set; others are implicit. 5367dd7cddfSDavid du ColombierFor example, if the message does not specify a destination port, the outgoing message 5377dd7cddfSDavid du Colombierwill be rewritten to identify it. 5387dd7cddfSDavid du ColombierIf the message does specify the port, the rule set will only match if any 5397dd7cddfSDavid du Colombier.CW plumb 5407dd7cddfSDavid du Colombier.CW to 5417dd7cddfSDavid du Colombieraction in the rule set names the same port. 5427dd7cddfSDavid du Colombier(If it matches no rule sets, but mentions a port, it will be sent there unmodified.) 5437dd7cddfSDavid du Colombier.LP 5447dd7cddfSDavid du ColombierThe rule set may contain actions that explicitly rewrite components of the message. 5457dd7cddfSDavid du ColombierThese may modify the attribute list or replace the data section of the message. 5467dd7cddfSDavid du ColombierHere is a sample rule set that does both. 5477dd7cddfSDavid du ColombierIt matches strings of the form 5487dd7cddfSDavid du Colombier.CW plumb.h 5497dd7cddfSDavid du Colombieror 5507dd7cddfSDavid du Colombier.CW plumb.h:27 . 5517dd7cddfSDavid du ColombierIf that string identifies a file in the standard C include directory, 5527dd7cddfSDavid du Colombier.CW /sys/include , 5537dd7cddfSDavid du Colombierperhaps with an optional line number, the outgoing message 5547dd7cddfSDavid du Colombieris rewritten to contain the full path name and an attribute, 5557dd7cddfSDavid du Colombier.CW addr , 5567dd7cddfSDavid du Colombierto hold the line number: 5577dd7cddfSDavid du Colombier.P1 5587dd7cddfSDavid du Colombier# .h files are looked up in /sys/include and passed to edit 5597dd7cddfSDavid du Colombiertype is text 5607dd7cddfSDavid du Colombierdata matches '([a-zA-Z0-9]+\e.h)(:([0-9]+))?' 5617dd7cddfSDavid du Colombierarg isfile /sys/include/$1 5627dd7cddfSDavid du Colombierdata set /sys/include/$1 5637dd7cddfSDavid du Colombierattr add addr=$3 5647dd7cddfSDavid du Colombierplumb to edit 5657dd7cddfSDavid du Colombier.P2 5667dd7cddfSDavid du ColombierThe 5677dd7cddfSDavid du Colombier.CW data 5687dd7cddfSDavid du Colombier.CW set 5697dd7cddfSDavid du Colombierrule replaces the contents of the data, and the 5707dd7cddfSDavid du Colombier.CW attr 5717dd7cddfSDavid du Colombier.CW add 5727dd7cddfSDavid du Colombierrule adds a new attribute to the message. 5737dd7cddfSDavid du ColombierThe intent of this rule is to permit one to plumb an include file name in a C program 5747dd7cddfSDavid du Colombierto trigger the opening of that file, perhaps at a specified line, in the text editor. 5757dd7cddfSDavid du ColombierA variant of this rule, discussed below, 5767dd7cddfSDavid du Colombiertells the editor how to interpret syntax errors from the compiler, 5777dd7cddfSDavid du Colombieror the output of 5787dd7cddfSDavid du Colombier.CW grep 5797dd7cddfSDavid du Colombier.CW -n , 5807dd7cddfSDavid du Colombierboth of which use a fixed syntax 5817dd7cddfSDavid du Colombier.I file\f(CW:\fPline 5827dd7cddfSDavid du Colombierto identify a line of source. 5837dd7cddfSDavid du Colombier.LP 5847dd7cddfSDavid du ColombierThe Plan 9 text editors interpret the 5857dd7cddfSDavid du Colombier.CW addr 5867dd7cddfSDavid du Colombierattribute as the definition of which portion of the file to display. 5877dd7cddfSDavid du ColombierIn fact, the real rule includes a richer definition of the address syntax, 5887dd7cddfSDavid du Colombierso one may plumb strings such as 5897dd7cddfSDavid du Colombier.CW plumb.h:/plumbsend 5907dd7cddfSDavid du Colombier(using a regular expression after the 5917dd7cddfSDavid du Colombier.CW / ) 5927dd7cddfSDavid du Colombierto pop up the declaration of a function in a C header file. 5937dd7cddfSDavid du Colombier.LP 5947dd7cddfSDavid du ColombierAnother form of rewriting is that the plumber may modify the attribute list of 5957dd7cddfSDavid du Colombierthe message to clarify how to handle the message. 5967dd7cddfSDavid du ColombierThe primary example of this involves the treatment of the 5977dd7cddfSDavid du Colombier.CW click 5987dd7cddfSDavid du Colombierattribute, described in the previous section. 5997dd7cddfSDavid du ColombierIf the message contains a 6007dd7cddfSDavid du Colombier.CW click 6017dd7cddfSDavid du Colombierattribute and the matching rule set uses it to extract the matching substring from the data, 6027dd7cddfSDavid du Colombierthe plumber 6037dd7cddfSDavid du Colombierdeletes the 6047dd7cddfSDavid du Colombier.CW click 6057dd7cddfSDavid du Colombierattribute and replaces the data with the matching substring. 6067dd7cddfSDavid du Colombier.LP 6077dd7cddfSDavid du ColombierOnce the message is rewritten, the actions of the matching rule set are examined. 6087dd7cddfSDavid du ColombierIf the rule set contains a 6097dd7cddfSDavid du Colombier.CW plumb 6107dd7cddfSDavid du Colombier.CW to 6117dd7cddfSDavid du Colombieraction and the corresponding port is open\(emthat is, if a program is already reading 6127dd7cddfSDavid du Colombierfrom that port\(emthe message is delivered to the port. 6137dd7cddfSDavid du ColombierThe application will receive the message and handle it as it sees fit. 6147dd7cddfSDavid du ColombierIf the port is not open, a 6157dd7cddfSDavid du Colombier.CW plumb 6167dd7cddfSDavid du Colombier.CW start 6177dd7cddfSDavid du Colombieror 6187dd7cddfSDavid du Colombier.CW plumb 6197dd7cddfSDavid du Colombier.CW client 6207dd7cddfSDavid du Colombieraction will start a new program to handle the message. 6217dd7cddfSDavid du Colombier.LP 6227dd7cddfSDavid du ColombierThe 6237dd7cddfSDavid du Colombier.CW plumb 6247dd7cddfSDavid du Colombier.CW start 6257dd7cddfSDavid du Colombieraction is the simpler: its argument specifies a command to run 6267dd7cddfSDavid du Colombierinstead of passing on the message; the message is discarded. 6277dd7cddfSDavid du ColombierHere for instance is a rule that, given the process id (pid) of an existing process, 6287dd7cddfSDavid du Colombierstarts the 6297dd7cddfSDavid du Colombier.CW acid 6307dd7cddfSDavid du Colombierdebugger [Wint94] in a new window to examine that process: 6317dd7cddfSDavid du Colombier.P1 6327dd7cddfSDavid du Colombier# processes go to acid (assuming strlen(pid) >= 2) 6337dd7cddfSDavid du Colombiertype is text 6347dd7cddfSDavid du Colombierdata matches '[a-zA-Z0-9.:_\e-/]+' 6357dd7cddfSDavid du Colombierdata matches '[0-9][0-9]+' 6367dd7cddfSDavid du Colombierarg isdir /proc/$0 6377dd7cddfSDavid du Colombierplumb start window acid $0 6387dd7cddfSDavid du Colombier.P2 6397dd7cddfSDavid du Colombier(Note the use of multiple 6407dd7cddfSDavid du Colombier.CW matches 6417dd7cddfSDavid du Colombierrules to avoid misfires from strings like 6427dd7cddfSDavid du Colombier.CW party.1999 .) 6437dd7cddfSDavid du ColombierThe 6447dd7cddfSDavid du Colombier.CW arg 6457dd7cddfSDavid du Colombier.CW isdir 6467dd7cddfSDavid du Colombierrule checks that the pid represents a running process (or broken one; Plan 9 does not create 6477dd7cddfSDavid du Colombier.CW core 6487dd7cddfSDavid du Colombierfiles but leaves broken processes around for debugging) by checking that the process file 6497dd7cddfSDavid du Colombiersystem has a directory for that pid [Kill84]. 6507dd7cddfSDavid du ColombierUsing this rule, one may plumb the pid string printed by the 6517dd7cddfSDavid du Colombier.CW ps 6527dd7cddfSDavid du Colombiercommand or by the operating system when the program breaks; 6537dd7cddfSDavid du Colombierthe debugger will then start automatically. 6547dd7cddfSDavid du Colombier.LP 6557dd7cddfSDavid du ColombierThe other startup action, 6567dd7cddfSDavid du Colombier.CW plumb 6577dd7cddfSDavid du Colombier.CW client , 6587dd7cddfSDavid du Colombieris used when a program will read messages from the plumbing port. 6597dd7cddfSDavid du ColombierFor example, 6607dd7cddfSDavid du Colombiertext editors can read files specified as command arguments, so one could use a 6617dd7cddfSDavid du Colombier.CW plumb 6627dd7cddfSDavid du Colombier.CW start 6637dd7cddfSDavid du Colombierrule to begin editing a file. 6647dd7cddfSDavid du ColombierIf, however, the editor will read messages from the 6657dd7cddfSDavid du Colombier.CW edit 6667dd7cddfSDavid du Colombierplumbing port, letting it read the message 6677dd7cddfSDavid du Colombierfrom the port insures that it uses other information in the message, 6687dd7cddfSDavid du Colombiersuch as the line number to display. 6697dd7cddfSDavid du ColombierThe 6707dd7cddfSDavid du Colombier.CW plumb 6717dd7cddfSDavid du Colombier.CW client 6727dd7cddfSDavid du Colombieraction is therefore like 6737dd7cddfSDavid du Colombier.CW plumb 6747dd7cddfSDavid du Colombier.CW start , 6757dd7cddfSDavid du Colombierbut keeps the message around for delivery when the application opens the port. 6767dd7cddfSDavid du ColombierHere is the full rule set to pass a regular file to the text editor: 6777dd7cddfSDavid du Colombier.P1 6787dd7cddfSDavid du Colombier# existing files, possibly tagged by address, go to editor 6797dd7cddfSDavid du Colombiertype is text 6807dd7cddfSDavid du Colombierdata matches '([.a-zA-Z0-9_/\e-]*[a-zA-Z0-9_/\e-])('$addr')?' 6817dd7cddfSDavid du Colombierarg isfile $1 6827dd7cddfSDavid du Colombierdata set $1 6837dd7cddfSDavid du Colombierattr add addr=$3 6847dd7cddfSDavid du Colombierplumb to edit 6857dd7cddfSDavid du Colombierplumb client window $editor 6867dd7cddfSDavid du Colombier.P2 6877dd7cddfSDavid du ColombierIf the editor is already running, the 6887dd7cddfSDavid du Colombier.CW plumb 6897dd7cddfSDavid du Colombier.CW to 6907dd7cddfSDavid du Colombierrule causes it to receive the message on the port. 6917dd7cddfSDavid du ColombierIf not, 6927dd7cddfSDavid du Colombierthe command 6937dd7cddfSDavid du Colombier.CW window "" ` 6947dd7cddfSDavid du Colombier.CW $editor ' 6957dd7cddfSDavid du Colombierwill create a new window (using the Plan 9 program 6967dd7cddfSDavid du Colombier.CW window ) 6977dd7cddfSDavid du Colombierto run the editor, and once that starts it will open the 6987dd7cddfSDavid du Colombier.CW edit 6997dd7cddfSDavid du Colombierplumbing port as usual and discover this first message already waiting. 7007dd7cddfSDavid du Colombier.LP 7017dd7cddfSDavid du ColombierThe variables 7027dd7cddfSDavid du Colombier.CW $editor 7037dd7cddfSDavid du Colombierand 7047dd7cddfSDavid du Colombier.CW $addr 7057dd7cddfSDavid du Colombierin this rule set 7067dd7cddfSDavid du Colombierare macros defined in the plumbing rules file; they specify the name of the user's favorite text editor 7077dd7cddfSDavid du Colombierand a regular expression 7087dd7cddfSDavid du Colombierthat matches that editor's address syntax, such as line numbers and patterns. 7097dd7cddfSDavid du ColombierThis rule set lives in a library of shared plumbing rules that 7107dd7cddfSDavid du Colombierusers' private rules can build on, 7117dd7cddfSDavid du Colombierso the rule set needs to be adaptable to different editors and their address syntax. 7127dd7cddfSDavid du ColombierThe macro definitions for Acme and Sam [Pike94,Pike87b] look like this: 7137dd7cddfSDavid du Colombier.P1 7147dd7cddfSDavid du Colombiereditor=acme 7157dd7cddfSDavid du Colombier# or editor=sam 7167dd7cddfSDavid du Colombieraddrelem='((#?[0-9]+)|(/[A-Za-z0-9_\e^]+/?)|[.$])' 7177dd7cddfSDavid du Colombieraddr=:($addrelem([,;+\e-]$addrelem)*) 7187dd7cddfSDavid du Colombier.P2 7197dd7cddfSDavid du Colombier.LP 7207dd7cddfSDavid du ColombierFinally, the application reads the message from the appropriate port, such as 7217dd7cddfSDavid du Colombier.CW /mnt/plumb/edit , 7227dd7cddfSDavid du Colombierunpacks it, and goes to work. 7237dd7cddfSDavid du Colombier.SH 7247dd7cddfSDavid du ColombierMessage Delivery 7257dd7cddfSDavid du Colombier.LP 7267dd7cddfSDavid du ColombierIn summary, a message is delivered by writing it to the 7277dd7cddfSDavid du Colombier.CW send 7287dd7cddfSDavid du Colombierfile and having the plumber, perhaps after some rewriting, send it to the destination 7297dd7cddfSDavid du Colombierport or start a new application to handle it. 7307dd7cddfSDavid du ColombierIf no destination can be found by the plumber, the original write to the 7317dd7cddfSDavid du Colombier.CW send 7327dd7cddfSDavid du Colombierfile will fail, and the application will know the message could not be delivered. 7337dd7cddfSDavid du Colombier.LP 7347dd7cddfSDavid du ColombierIf multiple applications are reading from the destination port, each will receive 7357dd7cddfSDavid du Colombieran identical copy of the message; that is, the plumber implements fan-out. 7367dd7cddfSDavid du ColombierThe number of messages delivered is equal to the number of clients that have 7377dd7cddfSDavid du Colombieropened the destination port. 7387dd7cddfSDavid du ColombierThe plumber queues the messages and makes sure that each application that opened 7397dd7cddfSDavid du Colombierthe port before the message was written gets exactly one copy. 7407dd7cddfSDavid du Colombier.LP 7417dd7cddfSDavid du ColombierThis design minimizes blocking in the sending applications, since the write to the 7427dd7cddfSDavid du Colombier.CW send 7437dd7cddfSDavid du Colombierfile can complete as soon as the message has been queued for the appropriate port. 7447dd7cddfSDavid du ColombierIf the plumber waited for the message to be read by the recipient, the sender could 7457dd7cddfSDavid du Colombierblock unnecessarily. 7467dd7cddfSDavid du ColombierUnfortunately, this design also means that there is no way for a sender to know when 7477dd7cddfSDavid du Colombierthe message has been handled; in fact, there are cases when 7487dd7cddfSDavid du Colombierthe message will not be delivered at all, such as if the recipient exits while there are 7497dd7cddfSDavid du Colombierstill messages in the queue. 7507dd7cddfSDavid du ColombierSince the plumber is part of a user interface, and not 7517dd7cddfSDavid du Colombieran autonomous message delivery system, 7527dd7cddfSDavid du Colombierthe decision was made to give the 7537dd7cddfSDavid du Colombiernon-blocking property priority over reliability of message delivery. 7547dd7cddfSDavid du ColombierIn practice, this tradeoff has worked out well: 7557dd7cddfSDavid du Colombierapplications almost always know when a message has failed to be delivered (the 7567dd7cddfSDavid du Colombier.CW write 7577dd7cddfSDavid du Colombierfails because no destination could be found), 7587dd7cddfSDavid du Colombierand those occasions when the sender believes incorrectly that the message has been delivered 7597dd7cddfSDavid du Colombierare both extremely rare and easily recognized by the user\(emusually because the recipient 7607dd7cddfSDavid du Colombierapplication has exited. 7617dd7cddfSDavid du Colombier.SH 7627dd7cddfSDavid du ColombierThe Rules File 7637dd7cddfSDavid du Colombier.LP 7647dd7cddfSDavid du ColombierThe plumber begins execution by reading the user's startup plumbing rules file, 7657dd7cddfSDavid du Colombier.CW lib/plumbing . 7667dd7cddfSDavid du ColombierSince the plumber is implemented as a file server, it can also present its current rules 7677dd7cddfSDavid du Colombieras a dynamic file, a design that provides an easily understood way to maintain the rules. 7687dd7cddfSDavid du Colombier.LP 7697dd7cddfSDavid du ColombierThe file 7707dd7cddfSDavid du Colombier.CW /mnt/plumb/rules 7717dd7cddfSDavid du Colombieris the text of the rule set the plumber is currently using, 7727dd7cddfSDavid du Colombierand it may be edited like a regular file to update those rules. 7737dd7cddfSDavid du ColombierTo clear the rules, truncate that file; 7747dd7cddfSDavid du Colombierto add a new rule set, append to it: 7757dd7cddfSDavid du Colombier.P1 7767dd7cddfSDavid du Colombier% echo 'type is text 7777dd7cddfSDavid du Colombierdata is self-destruct 7787dd7cddfSDavid du Colombierplumb start rm -rf $HOME' >> /mnt/plumb/rules 7797dd7cddfSDavid du Colombier.P2 7807dd7cddfSDavid du ColombierThis rule set will take effect immediately. 7817dd7cddfSDavid du ColombierIf it has a syntax error, the write will fail with an error message from the plumber, 7827dd7cddfSDavid du Colombiersuch as `malformed rule' or 'undefined verb'. 7837dd7cddfSDavid du Colombier.LP 7847dd7cddfSDavid du ColombierTo restore the plumber to its startup configuration, 7857dd7cddfSDavid du Colombier.P1 7867dd7cddfSDavid du Colombier% cp /usr/$user/lib/plumbing /mnt/plumb/rules 7877dd7cddfSDavid du Colombier.P2 7887dd7cddfSDavid du ColombierFor more sophisticated changes, 7897dd7cddfSDavid du Colombierone can of course use a regular text editor to modify 7907dd7cddfSDavid du Colombier.CW /mnt/plumb/rules . 7917dd7cddfSDavid du Colombier.LP 7927dd7cddfSDavid du ColombierThis simple way of maintaining an active service could profitably be adopted by other systems. 7937dd7cddfSDavid du ColombierIt avoids the need to reboot, to update registries with special tools, or to send asynchronous signals 7947dd7cddfSDavid du Colombierto critical programs. 7957dd7cddfSDavid du Colombier.SH 7967dd7cddfSDavid du ColombierThe User Interface 7977dd7cddfSDavid du Colombier.LP 7987dd7cddfSDavid du ColombierOne unusual property of the plumbing system is that 7997dd7cddfSDavid du Colombierthe user interface that programs provide to access it can vary considerably, yet 8007dd7cddfSDavid du Colombierthe result is nonetheless a unifying force in the environment. 8017dd7cddfSDavid du ColombierShells talk to editors, image viewers, and web browsers; debuggers talk to editors; 8027dd7cddfSDavid du Colombiereditors talk to themselves; and the window system talks to everybody. 8037dd7cddfSDavid du Colombier.LP 8047dd7cddfSDavid du ColombierThe plumber grew out of some of the ideas of the Acme editor/window-system/user interface [Pike94], 8057dd7cddfSDavid du Colombierin particular its `acquisition' feature. 8067dd7cddfSDavid du ColombierWith a three-button mouse, clicking the right button in Acme on a piece of text tells Acme to 8077dd7cddfSDavid du Colombierget the thing being pointed to. 8087dd7cddfSDavid du ColombierIf it is a file name, open the file; 8097dd7cddfSDavid du Colombierif it is a directory, open a viewer for its contents; 8107dd7cddfSDavid du Colombierif a line number, go to that line; 8117dd7cddfSDavid du Colombierif a regular expression, search for it. 8127dd7cddfSDavid du ColombierThis one-click access to anything describable textually was very powerful but had several 8137dd7cddfSDavid du Colombierlimitations, of which the most important were that Acme's rules for interpreting the 8147dd7cddfSDavid du Colombiertext (that is, the implicit hyperlinks) were hard-wired and inflexible, and 8157dd7cddfSDavid du Colombierthat they only applied to and within Acme itself. 8167dd7cddfSDavid du ColombierOne could not, for example, use Acme's power to open an image file, since Acme is 8177dd7cddfSDavid du Colombiera text-only system. 8187dd7cddfSDavid du Colombier.LP 8197dd7cddfSDavid du ColombierThe plumber addresses these limitations, even with Acme itself: 8207dd7cddfSDavid du ColombierAcme now uses the plumber to interpret the right button clicks for it. 8217dd7cddfSDavid du ColombierWhen the right button is clicked on some text, 8227dd7cddfSDavid du ColombierAcme constructs a plumbing message much as described above, 8237dd7cddfSDavid du Colombierusing the 8247dd7cddfSDavid du Colombier.CW click 8257dd7cddfSDavid du Colombierattribute and the white-space-delimited text surrounding the click. 8267dd7cddfSDavid du ColombierIt then writes the message to the plumber; if the write succeeds, all is well. 8277dd7cddfSDavid du ColombierIf not, it falls back to its original, internal rules, which will result in a context search 8287dd7cddfSDavid du Colombierfor the word within the current document. 8297dd7cddfSDavid du Colombier.LP 8307dd7cddfSDavid du ColombierIf the message is sent successfully, the recipient is likely to be Acme itself, of course: 8317dd7cddfSDavid du Colombierthe request may be to open a file, for example. 8327dd7cddfSDavid du ColombierThus Acme has turned the plumber into an external component of its own operation, 8337dd7cddfSDavid du Colombierwhile expanding the possibilities; the operation might be to start an image viewer to 8347dd7cddfSDavid du Colombieropen a picture file, something Acme cannot do itself. 8357dd7cddfSDavid du ColombierThe plumber expands the power of Acme's original user interface. 8367dd7cddfSDavid du Colombier.LP 8377dd7cddfSDavid du ColombierTraditional menu-driven programs such as the text editor Sam [Pike87b] and the default 8387dd7cddfSDavid du Colombiershell window of the window 8397dd7cddfSDavid du Colombiersystem 8407dd7cddfSDavid du Colombier.CW 8½ 8417dd7cddfSDavid du Colombier[Pike91] cannot dedicate a mouse button solely to plumbing, but they can certainly 8427dd7cddfSDavid du Colombierdedicate a menu entry. 8437dd7cddfSDavid du ColombierThe editing menu for such programs now contains an entry, 8447dd7cddfSDavid du Colombier.CW plumb , 8457dd7cddfSDavid du Colombierthat creates a plumbing message using the current selection. 8467dd7cddfSDavid du Colombier(Acme manages to send a message by clicking on the text with one button; 8477dd7cddfSDavid du Colombierother programs require a click with the select button and then a menu operation.) 8487dd7cddfSDavid du ColombierFor example, after this happens in a shell window: 8497dd7cddfSDavid du Colombier.P1 8507dd7cddfSDavid du Colombier% make 8517dd7cddfSDavid du Colombiercc -c shaney.c 8527dd7cddfSDavid du Colombiershaney.c:232: i undefined 8537dd7cddfSDavid du Colombier\&... 8547dd7cddfSDavid du Colombier.P2 8557dd7cddfSDavid du Colombierone can click anywhere on the string 8567dd7cddfSDavid du Colombier.CW shaney.c:232 , 8577dd7cddfSDavid du Colombierexecute the 8587dd7cddfSDavid du Colombier.CW plumb 8597dd7cddfSDavid du Colombiermenu entry, and have line 232 appear in the text editor, be it Sam or Acme\(emwhichever has the 8607dd7cddfSDavid du Colombier.CW edit 8617dd7cddfSDavid du Colombierport open. 8627dd7cddfSDavid du Colombier(If this were an Acme shell window, it would be sufficient to right-click on the string.) 8637dd7cddfSDavid du Colombier.LP 8647dd7cddfSDavid du Colombier[An interesting side line is how the window system knows what directory the 8657dd7cddfSDavid du Colombiershell is running in; in other words, what value to place in the 8667dd7cddfSDavid du Colombier.CW wdir 8677dd7cddfSDavid du Colombierfield of the plumb message. 8687dd7cddfSDavid du ColombierRecall that 8697dd7cddfSDavid du Colombier.CW 8½ 8707dd7cddfSDavid du Colombieris, like many Plan 9 programs, a file server. 8717dd7cddfSDavid du ColombierIt now serves a new file, 8727dd7cddfSDavid du Colombier.CW /dev/wdir , 8737dd7cddfSDavid du Colombierthat is private to each window. 8747dd7cddfSDavid du ColombierPrograms, in particular the 8757dd7cddfSDavid du ColombierPlan 9 shell, 8767dd7cddfSDavid du Colombier.CW rc , 8777dd7cddfSDavid du Colombiercan write that file to inform the window system of its current directory. 8787dd7cddfSDavid du ColombierWhen a 8797dd7cddfSDavid du Colombier.CW cd 8807dd7cddfSDavid du Colombiercommand is executed in an interactive shell, 8817dd7cddfSDavid du Colombier.CW rc 8827dd7cddfSDavid du Colombierupdates the contents of 8837dd7cddfSDavid du Colombier.CW /dev/wdir 8847dd7cddfSDavid du Colombierand plumbing can proceed with local file names.] 8857dd7cddfSDavid du Colombier.LP 8867dd7cddfSDavid du ColombierOf course, users can plumb image file names, process ids, URLs, and other items\(emany string 8877dd7cddfSDavid du Colombierwhose syntax and disposition are defined in the plumbing rules file. 8887dd7cddfSDavid du ColombierAn example of how the pieces fit together is the way Plan 9 now handles mail, particularly 8897dd7cddfSDavid du ColombierMIME-encoded messages. 8907dd7cddfSDavid du Colombier.LP 8917dd7cddfSDavid du ColombierWhen a new mail message arrives, the mail receiver process sends a plumbing message to the 8927dd7cddfSDavid du Colombier.CW newmail 8937dd7cddfSDavid du Colombierport, which notifies any interested process that new mail is here. 8947dd7cddfSDavid du ColombierThe plumbing message contains information about the mail, including 8957dd7cddfSDavid du Colombierits sender, date, and current location in the file system. 8967dd7cddfSDavid du ColombierThe interested processes include a program, 8977dd7cddfSDavid du Colombier.CW faces , 8987dd7cddfSDavid du Colombierthat gives a graphical display of the mail box using 8997dd7cddfSDavid du Colombierfaces to represent the senders of messages [PiPr85], 9007dd7cddfSDavid du Colombieras well as interactive mail programs such as the Acme mail viewer [Pike94]. 9017dd7cddfSDavid du ColombierThe user can then click on the face that appears, and the 9027dd7cddfSDavid du Colombier.CW faces 9037dd7cddfSDavid du Colombierprogram will send another plumbing message, this time to the 9047dd7cddfSDavid du Colombier.CW showmail 9057dd7cddfSDavid du Colombierport. 9067dd7cddfSDavid du ColombierHere is the rule for that port: 9077dd7cddfSDavid du Colombier.P1 9087dd7cddfSDavid du Colombier# faces -> new mail window for message 9097dd7cddfSDavid du Colombiertype is text 9107dd7cddfSDavid du Colombierdata matches '[a-zA-Z0-9_\e-./]+' 9117dd7cddfSDavid du Colombierdata matches '/mail/fs/[a-zA-Z0-9/]+/[0-9]+' 9127dd7cddfSDavid du Colombierplumb to showmail 9137dd7cddfSDavid du Colombierplumb start window edmail -s $0 9147dd7cddfSDavid du Colombier.P2 9157dd7cddfSDavid du ColombierIf a program, such as the Acme mail reader, is reading that port, it will open a new window 9167dd7cddfSDavid du Colombierin which to display the message. 9177dd7cddfSDavid du ColombierIf not, the 9187dd7cddfSDavid du Colombier.CW plumb 9197dd7cddfSDavid du Colombier.CW start 9207dd7cddfSDavid du Colombierrule will create a new window and run 9217dd7cddfSDavid du Colombier.CW edmail , 9227dd7cddfSDavid du Colombiera conventional mail reading process, to examine it. 9237dd7cddfSDavid du ColombierNotice how the plumbing connects the components of the interface together the same way 9247dd7cddfSDavid du Colombierregardless of which components are actually being used to view mail. 9257dd7cddfSDavid du Colombier.LP 9267dd7cddfSDavid du ColombierThere is more to the mail story. 9277dd7cddfSDavid du ColombierNaturally, mail boxes in Plan 9 are treated as little file systems, which are synthesized 9287dd7cddfSDavid du Colombieron demand by a special-purpose file server that takes a flat mail box file and converts 9297dd7cddfSDavid du Colombierit into a set of directories, one per message, with component files containing the header, 9307dd7cddfSDavid du Colombierbody, MIME information, and so on. 9317dd7cddfSDavid du ColombierMulti-part MIME messages are unpacked into multi-level directories, like this: 9327dd7cddfSDavid du Colombier.P1 9337dd7cddfSDavid du Colombier% ls -l /mail/fs/mbox/25 9347dd7cddfSDavid du Colombierd-r-xr-xr-x M 20 rob rob 0 Nov 21 13:06 /mail/fs/mbox/25/1 9357dd7cddfSDavid du Colombierd-r-xr-xr-x M 20 rob rob 0 Nov 21 13:06 /mail/fs/mbox/25/2 9367dd7cddfSDavid du Colombier--r--r--r-- M 20 rob rob 28678 Nov 21 13:06 /mail/fs/mbox/25/body 9377dd7cddfSDavid du Colombier--r--r--r-- M 20 rob rob 0 Nov 21 13:06 /mail/fs/mbox/25/cc 9387dd7cddfSDavid du Colombier\&... 9397dd7cddfSDavid du Colombier% mail 9407dd7cddfSDavid du Colombier25 messages 9417dd7cddfSDavid du Colombier: 25 9427dd7cddfSDavid du ColombierFrom: presotto 9437dd7cddfSDavid du ColombierDate: Sun Nov 21 13:05:51 EST 1999 9447dd7cddfSDavid du ColombierTo: rob 9457dd7cddfSDavid du Colombier 9467dd7cddfSDavid du ColombierCheck this out. 9477dd7cddfSDavid du Colombier 9487dd7cddfSDavid du Colombier===> 2/ (image/jpeg) [inline] 9497dd7cddfSDavid du Colombier /mail/fs/mbox/25/2/fabio.jpg 9507dd7cddfSDavid du Colombier: 9517dd7cddfSDavid du Colombier.P2 9527dd7cddfSDavid du ColombierSince the components are all (synthetic) files, the user can plumb the pieces 9537dd7cddfSDavid du Colombierto view embedded pictures, URLs, and so on. 9547dd7cddfSDavid du ColombierNote that the mail program can plumb the contents of 9557dd7cddfSDavid du Colombier.CW inline 9567dd7cddfSDavid du Colombierattachments automatically, without user interaction; 9577dd7cddfSDavid du Colombierin other words, plumbing lets the mailer handle multimedia data 9587dd7cddfSDavid du Colombierwithout itself interpreting it. 9597dd7cddfSDavid du Colombier.LP 9607dd7cddfSDavid du ColombierAt a more mundane level, a shell command, 9617dd7cddfSDavid du Colombier.CW plumb , 9627dd7cddfSDavid du Colombiercan be used to send messages: 9637dd7cddfSDavid du Colombier.P1 9647dd7cddfSDavid du Colombier% cd /usr/rob/src 9657dd7cddfSDavid du Colombier% plumb mem.c 9667dd7cddfSDavid du Colombier.P2 9677dd7cddfSDavid du Colombierwill send the appropriate message to the 9687dd7cddfSDavid du Colombier.CW edit 9697dd7cddfSDavid du Colombierport. 9707dd7cddfSDavid du ColombierA surprising use of the 9717dd7cddfSDavid du Colombier.CW plumb 9727dd7cddfSDavid du Colombiercommand is in actions within the plumbing rules file. 9737dd7cddfSDavid du ColombierIn our lab, we commonly receive Microsoft Word documents by mail, 9747dd7cddfSDavid du Colombierbut we do not run Microsoft operating systems on our machines so we cannot 9757dd7cddfSDavid du Colombierview them without at least rebooting. 9767dd7cddfSDavid du ColombierTherefore, when a Word document arrives in mail, we could plumb the 9777dd7cddfSDavid du Colombier.CW .doc 9787dd7cddfSDavid du Colombierfile but the text editor could not decode it. 9797dd7cddfSDavid du ColombierHowever, we have a program, 9807dd7cddfSDavid du Colombier.CW doc2txt , 9817dd7cddfSDavid du Colombierthat decodes the Word file format to extract and format the embedded text. 9827dd7cddfSDavid du ColombierThe solution is to use 9837dd7cddfSDavid du Colombier.CW plumb 9847dd7cddfSDavid du Colombierin a 9857dd7cddfSDavid du Colombier.CW plumb 9867dd7cddfSDavid du Colombier.CW start 9877dd7cddfSDavid du Colombieraction to invoke 9887dd7cddfSDavid du Colombier.CW doc2txt 9897dd7cddfSDavid du Colombieron 9907dd7cddfSDavid du Colombier.CW .doc 9917dd7cddfSDavid du Colombierfiles and synthesize a plain text file: 9927dd7cddfSDavid du Colombier.P1 9937dd7cddfSDavid du Colombier# rule set for microsoft word documents 9947dd7cddfSDavid du Colombiertype is text 9957dd7cddfSDavid du Colombierdata matches '[a-zA-Z0-9_\e-./]+' 9967dd7cddfSDavid du Colombierdata matches '([a-zA-Z0-9_\e-./]+)\e.doc' 9977dd7cddfSDavid du Colombierarg isfile $0 9987dd7cddfSDavid du Colombierplumb start doc2txt $data | \e 9997dd7cddfSDavid du Colombier plumb -i -d edit -a action=showdata -a filename=$0 10007dd7cddfSDavid du Colombier.P2 10017dd7cddfSDavid du ColombierThe arguments to 10027dd7cddfSDavid du Colombier.CW plumb 10037dd7cddfSDavid du Colombiertell it to take standard input as its data rather than the text of the arguments 10047dd7cddfSDavid du Colombier.CW -i ), ( 10057dd7cddfSDavid du Colombierdefine the destination port 10067dd7cddfSDavid du Colombier.CW -d "" ( 10077dd7cddfSDavid du Colombier.CW edit ), 10087dd7cddfSDavid du Colombierand set a conventional attribute so the editor knows to show the message data 10097dd7cddfSDavid du Colombieritself rather than interpret it as a file name 10107dd7cddfSDavid du Colombier.CW -a "" ( 10117dd7cddfSDavid du Colombier.CW action=showdata ) 10127dd7cddfSDavid du Colombierand provide the original file name 10137dd7cddfSDavid du Colombier.CW -a "" ( 10147dd7cddfSDavid du Colombier.CW filename=$0 ). 10157dd7cddfSDavid du ColombierNow when a user plumbs a 10167dd7cddfSDavid du Colombier.CW .doc 10177dd7cddfSDavid du Colombierfile the plumbing rules run a process to extract the text and send it as a 10187dd7cddfSDavid du Colombiertemporary file to the editor for viewing. 10197dd7cddfSDavid du ColombierIt's imperfect, but it's easy and it beats rebooting. 10207dd7cddfSDavid du Colombier.LP 10217dd7cddfSDavid du ColombierAnother simple example is a rule that turns man pages into hypertext. 10227dd7cddfSDavid du ColombierManual page entries of the form 10237dd7cddfSDavid du Colombier.CW plumber(1) 10247dd7cddfSDavid du Colombiercan be clicked on to pop up a window containing the formatted `man page'. 10257dd7cddfSDavid du ColombierThat man page will in turn contain more such citations, which will also be clickable. 10267dd7cddfSDavid du ColombierThe rule is a little like that for Word documents: 10277dd7cddfSDavid du Colombier.P1 10287dd7cddfSDavid du Colombier# man index entries are synthesized 10297dd7cddfSDavid du Colombiertype is text 10307dd7cddfSDavid du Colombierdata matches '([a-zA-Z0-9_\e-./]+)\e(([0-9])\e)' 10317dd7cddfSDavid du Colombierplumb start man $2 $1 | \e 10327dd7cddfSDavid du Colombier plumb -i -d edit -a action=showdata -a filename=/man/$1($2) 10337dd7cddfSDavid du Colombier.P2 10347dd7cddfSDavid du Colombier.LP 10357dd7cddfSDavid du ColombierThere are many other inventive uses of plumbing. 10367dd7cddfSDavid du ColombierOne more should give some of the flavor. 10377dd7cddfSDavid du ColombierWe have a shell script, 10387dd7cddfSDavid du Colombier.CW src , 10397dd7cddfSDavid du Colombierthat takes as argument the name of an executable binary file. 10407dd7cddfSDavid du ColombierIt examines the symbol table of the binary to find the source file 10417dd7cddfSDavid du Colombierfrom which it was compiled. 10427dd7cddfSDavid du ColombierSince the Plan 9 compilers place full source path names in the symbol table, 10437dd7cddfSDavid du Colombier.CW src 10447dd7cddfSDavid du Colombiercan discover the complete file name. 10457dd7cddfSDavid du ColombierThat is then passed to 10467dd7cddfSDavid du Colombier.CW plumb , 10477dd7cddfSDavid du Colombiercomplete with the line number to find the 10487dd7cddfSDavid du Colombiersymbol 10497dd7cddfSDavid du Colombier.CW main . 10507dd7cddfSDavid du ColombierFor example, 10517dd7cddfSDavid du Colombier.P1 10527dd7cddfSDavid du Colombier% src plumb 10537dd7cddfSDavid du Colombier.P2 10547dd7cddfSDavid du Colombieris all it takes to pop up an editor window on the 10557dd7cddfSDavid du Colombier.CW main 10567dd7cddfSDavid du Colombierroutine of the 10577dd7cddfSDavid du Colombier.CW plumb 10587dd7cddfSDavid du Colombiercommand, beginning at line 39 of 10597dd7cddfSDavid du Colombier.CW /sys/src/cmd/plumb/plumb.c . 10607dd7cddfSDavid du ColombierLike most uses of plumbing, 10617dd7cddfSDavid du Colombierthis is not a breakthrough in functionality, but it is a great convenience. 10627dd7cddfSDavid du Colombier.SH 10637dd7cddfSDavid du ColombierWhy This Architecture? 10647dd7cddfSDavid du Colombier.LP 10657dd7cddfSDavid du ColombierThe design of the plumbing system is peculiar: 10667dd7cddfSDavid du Colombiera centralized language-based file server does most of the work, 10677dd7cddfSDavid du Colombierwhile compared to other systems the applications themselves 10687dd7cddfSDavid du Colombiercontribute relatively little. 10697dd7cddfSDavid du ColombierThis architecture is deliberate, of course. 10707dd7cddfSDavid du Colombier.LP 10717dd7cddfSDavid du ColombierThat the plumber's behavior is derived from a linguistic description 10727dd7cddfSDavid du Colombiergives the system great flexibility and dynamism\(emrules can be added 10737dd7cddfSDavid du Colombierand changed at will, without rebooting\(embut the existence of a central library of rules 10747dd7cddfSDavid du Colombierensures that, for most users, the environment behaves in well-established ways. 10757dd7cddfSDavid du Colombier.LP 10767dd7cddfSDavid du ColombierThat the plumber is a file server is perhaps the most unusual aspect of its design, 10777dd7cddfSDavid du Colombierbut is also one of the most important. 10787dd7cddfSDavid du ColombierMessages are passed by regular I/O operations on files, so no extra technology 10797dd7cddfSDavid du Colombiersuch as remote procedure call or request brokers needs to be provided; 10807dd7cddfSDavid du Colombiermessages are transmitted by familiar means. 10817dd7cddfSDavid du ColombierAlmost every service in Plan 9 is a file server, so services can be exported 10827dd7cddfSDavid du Colombiertrivially using the system's remote file system operations [Pike93]. 10837dd7cddfSDavid du ColombierThe plumber is no exception; 10847dd7cddfSDavid du Colombierplumbing messages pass routinely across the network to remote applications without 10857dd7cddfSDavid du Colombierany special provision, 10867dd7cddfSDavid du Colombierin contrast to some commercial IPC mechanisms that become 10877dd7cddfSDavid du Colombiersignificantly more complex when they involve multiple machines. 10887dd7cddfSDavid du ColombierAs I write this, my window system is talking to applications running on three 10897dd7cddfSDavid du Colombierdifferent machines, but they all share a single instance of the plumber and so 10907dd7cddfSDavid du Colombiercan interoperate to integrate my environment. 10917dd7cddfSDavid du ColombierPlan 9 uses a shared file name space 10927dd7cddfSDavid du Colombierto combine multiple networked machines\(emcompute servers, 10937dd7cddfSDavid du Colombierfile servers, and interactive workstations\(eminto a single 10947dd7cddfSDavid du Colombiercomputing environment; plumbing's design as a file server 10957dd7cddfSDavid du Colombieris a natural by-product of, and contributor to, the overall system architecture 10967dd7cddfSDavid du Colombier[Pike92]. 10977dd7cddfSDavid du Colombier.LP 10987dd7cddfSDavid du ColombierThe centrality of the plumber is also unusual. 10997dd7cddfSDavid du ColombierOther systems tend to let the applications determine where messages will go; 11007dd7cddfSDavid du Colombierconsider mail readers that recognize and highlight URLs in the messages. 11017dd7cddfSDavid du ColombierWhy should just the mail readers do this, and why should they just do it for URLs? 11027dd7cddfSDavid du Colombier(Acme was guilty of similar crimes.) 11037dd7cddfSDavid du ColombierThe plumber, by removing such decisions to a central authority, 11047dd7cddfSDavid du Colombierguarantees that all applications behave the same and simultaneously 11057dd7cddfSDavid du Colombierfrees them all from figuring out what's important. 11067dd7cddfSDavid du ColombierThe ability for the plumber to excerpt useful data from within a message 11077dd7cddfSDavid du Colombieris critical to the success of this model. 11087dd7cddfSDavid du Colombier.LP 11097dd7cddfSDavid du ColombierThe entire system is remarkably small. 11107dd7cddfSDavid du ColombierThe plumber itself is only about two thousand lines of C code. 11117dd7cddfSDavid du ColombierMost applications work fine in a plumbing environment without knowing about it at all; 11127dd7cddfSDavid du Colombiersome need trivial changes such as to standardize their error output; 11137dd7cddfSDavid du Colombiera few need to generate and receive plumbing messages. 11147dd7cddfSDavid du ColombierBut even to add the ability to send and receive messages in a program such as text editor is short work, 11157dd7cddfSDavid du Colombierinvolving typically a few dozen lines of code. 11167dd7cddfSDavid du ColombierPlumbing fits well into the existing environment. 11177dd7cddfSDavid du Colombier.LP 11187dd7cddfSDavid du ColombierBut plumbing is new and it hasn't been pushed far enough yet. 11197dd7cddfSDavid du ColombierMost of the work so far has been with textual messages, although 11207dd7cddfSDavid du Colombierthe underlying system is capable of handling general data. 11217dd7cddfSDavid du ColombierWe plan to reimplement some of the existing data movement operations, 11227dd7cddfSDavid du Colombiersuch as cut and paste or drag and drop, to use plumbing as their exchange mechanism. 11237dd7cddfSDavid du ColombierSince the plumber is a central message handler, it is an obvious place to store the `clipboard'. 11247dd7cddfSDavid du ColombierThe clipboard could be built as a special port that holds onto messages rather than 11257dd7cddfSDavid du Colombierdeleting them after delivery. 11267dd7cddfSDavid du ColombierSince the clipboard would then be holding a plumbing 11277dd7cddfSDavid du Colombiermessage rather than plain text, as in the current Plan 9 environment, 11287dd7cddfSDavid du Colombierit would become possible to cut and paste arbitrary data without 11297dd7cddfSDavid du Colombierproviding new mechanism. 11307dd7cddfSDavid du ColombierIn effect, we would be providing a new user interface to the existing plumbing facilities. 11317dd7cddfSDavid du Colombier.LP 11327dd7cddfSDavid du ColombierAnother possible extension is the ability to override plumbing operations interactively. 11337dd7cddfSDavid du ColombierOriginally, the plan was to provide a mechanism, perhaps a pop-up menu, that one could 11347dd7cddfSDavid du Colombieruse to direct messages, for example to send a PostScript file to the editor rather than the 11357dd7cddfSDavid du ColombierPostScript viewer by naming an explicit destination in the message. 11367dd7cddfSDavid du ColombierAlthough this deficiency should one day be addressed, it should be done without 11377dd7cddfSDavid du Colombiercomplicating the interface for invoking the default behavior. 11387dd7cddfSDavid du ColombierMeanwhile, in practice the default behavior seems to work very well in practice\(emas it 11397dd7cddfSDavid du Colombiermust if plumbing is to be successful\(emso the lack of 11407dd7cddfSDavid du Colombieroverrides is not keenly felt. 11417dd7cddfSDavid du Colombier.SH 11427dd7cddfSDavid du ColombierComparison with Other Systems 11437dd7cddfSDavid du Colombier.LP 11447dd7cddfSDavid du ColombierThe ideas of the plumbing system grew from an 11457dd7cddfSDavid du Colombierattempt to generalize the way Acme acquires files and data. 11467dd7cddfSDavid du ColombierSystems further from that lineage also share some properties with plumbing. 11477dd7cddfSDavid du ColombierMost, however, require explicit linking or message passing rather than 11487dd7cddfSDavid du Colombierplumbing's implicit, context-based pattern matching, and none 11497dd7cddfSDavid du Colombierhas the plumber's design of a language-based file server. 11507dd7cddfSDavid du Colombier.LP 11517dd7cddfSDavid du ColombierReiss's FIELD system [Reis95] probably comes the closest to providing the facilities of the plumber. 11527dd7cddfSDavid du ColombierIt has a central message-passing mechanism that connects applications together through 11537dd7cddfSDavid du Colombiera combination of a library and a pattern-matching central message dispatcher that handles 11547dd7cddfSDavid du Colombiermessage send and reply. 11557dd7cddfSDavid du ColombierThe main differences between FIELD's message dispatcher and the plumber are first 11567dd7cddfSDavid du Colombierthat the plumber is based on a special-purpose language while the FIELD 11577dd7cddfSDavid du Colombiersystem uses an object-oriented library, second that the plumber has no concept 11587dd7cddfSDavid du Colombierof a reply to a message, and finally that the FIELD system 11597dd7cddfSDavid du Colombierhas no concept of port. 11607dd7cddfSDavid du ColombierBut the key distinction is probably in the level of use. 11617dd7cddfSDavid du ColombierIn FIELD, the message dispatcher is a critical integrating force of the underlying 11627dd7cddfSDavid du Colombierprogramming environment, handling everything from debugging events to 11637dd7cddfSDavid du Colombierchanging the working directory of a program. 11647dd7cddfSDavid du ColombierPlumbing, by contrast, is intended primarily for integrating the user interface 11657dd7cddfSDavid du Colombierof existing tools; it is more modest and very much simpler. 11667dd7cddfSDavid du ColombierThe central advantage of the plumber is its convenience and dynamism; 11677dd7cddfSDavid du Colombierthe FIELD system does not share the ease with which 11687dd7cddfSDavid du Colombiermessage dispatch rules can be added or modified. 11697dd7cddfSDavid du Colombier.LP 11707dd7cddfSDavid du ColombierThe inspiration for Acme was 11717dd7cddfSDavid du Colombierthe user interface to the object-oriented Oberon system [WiGu92]. 11727dd7cddfSDavid du ColombierOberon's user interface interprets mouse clicks on strings such as 11737dd7cddfSDavid du Colombier.CW Obj.meth 11747dd7cddfSDavid du Colombierto invoke calls to the method 11757dd7cddfSDavid du Colombier.CW meth 11767dd7cddfSDavid du Colombierof the object 11777dd7cddfSDavid du Colombier.CW Obj . 11787dd7cddfSDavid du ColombierThis was the starting point for Acme's middle-button execution [Pike94], 11797dd7cddfSDavid du Colombierbut nothing in Oberon is much like Acme's right-button `acquisition', 11807dd7cddfSDavid du Colombierwhich was the starting point for the plumber. 11817dd7cddfSDavid du ColombierOberon's implicit method-based linking is not nearly as general as the pattern-matched 11827dd7cddfSDavid du Colombierlinking of the plumber, nor does its style of user-triggered method call 11837dd7cddfSDavid du Colombiercorrespond well to the more general idea of inter-application communication 11847dd7cddfSDavid du Colombierof plumbing messages. 11857dd7cddfSDavid du Colombier.LP 11867dd7cddfSDavid du ColombierMicrosoft's OLE interface is another relative. 11877dd7cddfSDavid du ColombierIt allows one application to 11887dd7cddfSDavid du Colombier.I embed 11897dd7cddfSDavid du Colombierits own data within another's, 11907dd7cddfSDavid du Colombierfor example to place an Excel spreadsheet within a Frame document; 11917dd7cddfSDavid du Colombierwhen Frame needs to format the page, it will start Excel itself, or at least some of its 11927dd7cddfSDavid du ColombierDLLs, to format the spreadsheet. 11937dd7cddfSDavid du ColombierOLE data can only be understood by the application that created it; 11947dd7cddfSDavid du Colombierplumbing messages, by contrast, contain arbitrary data with a rigidly formatted header 11957dd7cddfSDavid du Colombierthat will be interpreted by the pattern matcher and the destination application. 11967dd7cddfSDavid du ColombierThe plumber's simplified message format may limit its 11977dd7cddfSDavid du Colombierflexibility but makes messages easy and efficient to dispatch and to interpret. 11987dd7cddfSDavid du ColombierAt least for the cut-and-paste style of exchange OLE encourages, 11997dd7cddfSDavid du Colombierplumbing gives up some power in return for simplicity, while avoiding 12007dd7cddfSDavid du Colombierthe need to invoke a vestigial program (if Excel can be called a vestige) every time 12017dd7cddfSDavid du Colombierthe pasted data is examined. 12027dd7cddfSDavid du ColombierPlumbing is also better suited to 12037dd7cddfSDavid du Colombierother styles of data exchange, such as connecting compiler errors to the 12047dd7cddfSDavid du Colombiertext editor. 12057dd7cddfSDavid du Colombier.LP 12067dd7cddfSDavid du ColombierThe Hyperbole [Wein] package for Emacs adds hypertext facilities to existing documents. 12077dd7cddfSDavid du ColombierIt includes explicit links and, like plumbing, a rule-driven way to form implicit links. 12087dd7cddfSDavid du ColombierSince Emacs is purely textual, like Acme, Hyperbole does not easily extend to driving 12097dd7cddfSDavid du Colombiergraphical applications, nor does it provide a general interprocess communication method. 12107dd7cddfSDavid du ColombierFor instance, although Hyperbole provides some integration for mail applications, 12117dd7cddfSDavid du Colombierit cannot provide the glue that allows a click on a face icon in an external program to open a 12127dd7cddfSDavid du Colombiermail message within the viewer. 12137dd7cddfSDavid du ColombierMoreover, since it is not implemented as a file server, 12147dd7cddfSDavid du ColombierHyperbole does not share the advantages of that architecture. 12157dd7cddfSDavid du Colombier.LP 12167dd7cddfSDavid du ColombierHenry's 12177dd7cddfSDavid du Colombier.CW error 12187dd7cddfSDavid du Colombierprogram in 4BSD echoes a small but common use of plumbing. 12197dd7cddfSDavid du ColombierIt takes the error messages produced by a compiler and drives a text editor 12207dd7cddfSDavid du Colombierthrough the steps of looking at each one in turn; the notion is to quicken the 12217dd7cddfSDavid du Colombiercompile/edit/debug cycle. 12227dd7cddfSDavid du ColombierSimilar results are achieved in EMACS by writing special M-LISP 12237dd7cddfSDavid du Colombiermacros to parse the error messages from various compilers. 12247dd7cddfSDavid du ColombierAlthough for this particular purpose they may be more convenient than plumbing, 12257dd7cddfSDavid du Colombierthese are specific solutions to a specific problem and lack plumbing's generality. 12267dd7cddfSDavid du Colombier.LP 12277dd7cddfSDavid du ColombierOf course, the resource forks in MacOS and the association rules for 12287dd7cddfSDavid du Colombierfile name extensions in Windows also provide some of the functionality of 12297dd7cddfSDavid du Colombierthe plumber, although again without the generality or dynamic nature. 12307dd7cddfSDavid du Colombier.LP 12317dd7cddfSDavid du ColombierCloser to home, Ousterhout's Tcl (Tool Command Language) [Oust90] 12327dd7cddfSDavid du Colombierwas originally designed to embed a little command interpreter 12337dd7cddfSDavid du Colombierin each application to control interprocess communication and 12347dd7cddfSDavid du Colombierprovide a level of integration. 12357dd7cddfSDavid du ColombierPlumbing, on the other hand, provides minimal support within 12367dd7cddfSDavid du Colombierthe application, offloading most of the message handling and all the 12377dd7cddfSDavid du Colombiercommand execution to the central plumber. 12387dd7cddfSDavid du Colombier.LP 12397dd7cddfSDavid du ColombierThe most obvious relative to plumbing is perhaps the hypertext links of a web browser. 12407dd7cddfSDavid du ColombierPlumbing differs by synthesizing 12417dd7cddfSDavid du Colombierthe links on demand. 12427dd7cddfSDavid du ColombierRather than constructing links within a document as in HTML, 12437dd7cddfSDavid du Colombierplumbing uses the context of a button click to derive what it should link to. 12447dd7cddfSDavid du ColombierThat the rules for this decision can be modified dynamically gives it a more 12457dd7cddfSDavid du Colombierfluid feel than a standard web browsing world. 12467dd7cddfSDavid du ColombierOne possibility for future work is to adapt a web browser to use 12477dd7cddfSDavid du Colombierplumbing as its link-following engine, much as Acme used plumbing to offload 12487dd7cddfSDavid du Colombierits acquisition rules. 12497dd7cddfSDavid du ColombierThis would connect the web browser to the existing tools, rather than the 12507dd7cddfSDavid du Colombiercurrent trend in most systems of replacing the tools by a browser. 12517dd7cddfSDavid du Colombier.LP 12527dd7cddfSDavid du ColombierEach of these prior systems\(emand there are others, e.g. [Pasa93, Free93]\(emaddresses 12537dd7cddfSDavid du Colombiera particular need or subset of the 12547dd7cddfSDavid du Colombierissues of system integration. 12557dd7cddfSDavid du ColombierPlumbing differs because its particular choices were different. 12567dd7cddfSDavid du ColombierIt focuses on two key issues: 12577dd7cddfSDavid du Colombiercentralizing and automating the handling of interprocess communication 12587dd7cddfSDavid du Colombieramong interactive programs, 12597dd7cddfSDavid du Colombierand maximizing the convenience (or minimizing the trouble) for the human user 12607dd7cddfSDavid du Colombierof its services. 12617dd7cddfSDavid du ColombierMoreover, the plumber's implementation as a file server, with messages 12627dd7cddfSDavid du Colombierpassed over files it controls, 12637dd7cddfSDavid du Colombierpermits the architecture to work transparently across a network. 12647dd7cddfSDavid du ColombierNone of the other systems discussed here integrates distributed systems 12657dd7cddfSDavid du Colombieras smoothly as local ones without the addition of significant extra technology. 12667dd7cddfSDavid du Colombier.SH 12677dd7cddfSDavid du ColombierDiscussion 12687dd7cddfSDavid du Colombier.LP 12697dd7cddfSDavid du ColombierThere were a few surprises during the development of plumbing. 12707dd7cddfSDavid du ColombierThe first version of plumbing was done for the Inferno system [Dorw97a,Dorw97b], 12717dd7cddfSDavid du Colombierusing its file-to-channel mechanism to mediate the IPC. 12727dd7cddfSDavid du ColombierAlthough it was very simple to build, it encountered difficulties because 12737dd7cddfSDavid du Colombierthe plumber was too disconnected from its clients; in particular, there was 12747dd7cddfSDavid du Colombierno way to discover whether a port was in use. 12757dd7cddfSDavid du ColombierWhen plumbing was implemented afresh for Plan 9, it was provided through a true file server. 12767dd7cddfSDavid du ColombierAlthough this was much more work, it paid off handsomely. 12777dd7cddfSDavid du ColombierThe plumber now knows whether a port is open, which makes it easy to decide whether 12787dd7cddfSDavid du Colombiera new program must be started to handle a message, 12797dd7cddfSDavid du Colombierand the ability to edit the rules file dynamically is a major advantage. 12807dd7cddfSDavid du ColombierOther advantages arise from the file-server design, 12817dd7cddfSDavid du Colombiersuch as 12827dd7cddfSDavid du Colombierthe ease of exporting plumbing ports across the network to remote machines 12837dd7cddfSDavid du Colombierand the implicit security model a file-based interface provides: no one has 12847dd7cddfSDavid du Colombierpermission to open my private plumbing files. 12857dd7cddfSDavid du Colombier.LP 12867dd7cddfSDavid du ColombierOn the other hand, Inferno was an all-new environment and the user interface for plumbing was 12877dd7cddfSDavid du Colombierable to be made uniform for all applications. 12887dd7cddfSDavid du ColombierThis was impractical for Plan 9, so more 12897dd7cddfSDavid du Colombier.I "ad hoc 12907dd7cddfSDavid du Colombierinterfaces had to be provided for that environment. 12917dd7cddfSDavid du ColombierYet even in Plan 9 the advantages of efficient, 12927dd7cddfSDavid du Colombierconvenient, dynamic interprocess communication outweigh the variability of 12937dd7cddfSDavid du Colombierthe user interface. 12947dd7cddfSDavid du ColombierIn fact, it is perhaps a telling point that the system works well for a variety of interfaces; 12957dd7cddfSDavid du Colombierthe provision of a central, convenient message-passing 12967dd7cddfSDavid du Colombierservice is a good idea regardless of how the programs use it. 12977dd7cddfSDavid du Colombier.LP 12987dd7cddfSDavid du ColombierPlumbing's rule language uses only regular expressions and a few special 12997dd7cddfSDavid du Colombierrules such as 13007dd7cddfSDavid du Colombier.CW isfile 13017dd7cddfSDavid du Colombierfor matching text. 13027dd7cddfSDavid du ColombierThere is much more that could be done. For example, in the current system a JPEG 13037dd7cddfSDavid du Colombierfile can be recognized by a 13047dd7cddfSDavid du Colombier.CW .jpg 13057dd7cddfSDavid du Colombiersuffix but not by its contents, since the plumbing language has no facility 13067dd7cddfSDavid du Colombierfor examining the 13077dd7cddfSDavid du Colombier.I contents 13087dd7cddfSDavid du Colombierof files named in its messages. 13097dd7cddfSDavid du ColombierTo address this issue without adding more special rules requires rethinking 13107dd7cddfSDavid du Colombierthe language itself. 13117dd7cddfSDavid du ColombierAlthough the current system seems a good balance of complexity 13127dd7cddfSDavid du Colombierand functionality, 13137dd7cddfSDavid du Colombierperhaps a richer, more general-purpose language would 13147dd7cddfSDavid du Colombierpermit more exotic applications of the plumbing model. 13157dd7cddfSDavid du Colombier.LP 13167dd7cddfSDavid du ColombierIn conclusion, plumbing adds an effective, easy-to-use inter-application 13177dd7cddfSDavid du Colombiercommunication mechanism to the Plan 9 13187dd7cddfSDavid du Colombieruser interface. 13197dd7cddfSDavid du ColombierIts unusual design as a language-driven file server makes it easy to add 13207dd7cddfSDavid du Colombiercontext-dependent, dynamically interpreted, general-purpose hyperlinks 13217dd7cddfSDavid du Colombierto the desktop, for both existing tools and new ones. 13227dd7cddfSDavid du Colombier.SH 13237dd7cddfSDavid du ColombierAcknowledgements 13247dd7cddfSDavid du Colombier.LP 13257dd7cddfSDavid du ColombierDave Presotto wrote the mail file system and 13267dd7cddfSDavid du Colombier.CW edmail . 13277dd7cddfSDavid du ColombierHe, Russ Cox, Sape Mullender, and Cliff Young influenced the design, offered useful suggestions, 13287dd7cddfSDavid du Colombierand suffered early versions of the software. 13297dd7cddfSDavid du ColombierThey also made helpful comments on this paper, as did Dennis Ritchie and Brian Kernighan. 13307dd7cddfSDavid du Colombier.SH 13317dd7cddfSDavid du ColombierReferences 13327dd7cddfSDavid du Colombier.LP 13337dd7cddfSDavid du Colombier[Dorw97a] 13347dd7cddfSDavid du ColombierSean Dorward, Rob Pike, David Leo Presotto, Dennis M. Ritchie, 13357dd7cddfSDavid du ColombierHoward W. Trickey, and Philip Winterbottom, 13367dd7cddfSDavid du Colombier``Inferno'', 13377dd7cddfSDavid du Colombier.I "Proceedings of the IEEE Compcon 97 Conference" , 13387dd7cddfSDavid du ColombierSan Jose, 1997, pp. 241-244. 13397dd7cddfSDavid du Colombier.LP 13407dd7cddfSDavid du Colombier[Dorw97b] 13417dd7cddfSDavid du ColombierSean Dorward, Rob Pike, David Leo Presotto, Dennis M. Ritchie, 13427dd7cddfSDavid du ColombierHoward W. Trickey, and Philip Winterbottom, 13437dd7cddfSDavid du Colombier``The Inferno Operating System'', 13447dd7cddfSDavid du Colombier.I "Bell Labs Technical Journal" , 13457dd7cddfSDavid du Colombier.B 2 , 13467dd7cddfSDavid du Colombier1, Winter, 1997. 13477dd7cddfSDavid du Colombier.LP 13487dd7cddfSDavid du Colombier[Free93] 13497dd7cddfSDavid du ColombierFreeBSD, 13507dd7cddfSDavid du ColombierSyslog configuration file manual 13517dd7cddfSDavid du Colombier.I syslog.conf (0). 13527dd7cddfSDavid du Colombier.LP 13537dd7cddfSDavid du Colombier[Kill84] 13547dd7cddfSDavid du ColombierT. J. Killian, 13557dd7cddfSDavid du Colombier``Processes as Files'', 13567dd7cddfSDavid du Colombier.I "Proceedings of the Summer 1984 USENIX Conference" , 13577dd7cddfSDavid du ColombierSalt Lake City, 1984, pp. 203-207. 13587dd7cddfSDavid du Colombier.LP 13597dd7cddfSDavid du Colombier[Oust90] 13607dd7cddfSDavid du ColombierJohn K. Ousterhout, 13617dd7cddfSDavid du Colombier``Tcl: An Embeddable Command Languages'', 13627dd7cddfSDavid du Colombier.I "Proceedings of the Winter 1990 USENIX Conference" , 13637dd7cddfSDavid du ColombierWashington, 1990, pp. 133-146. 13647dd7cddfSDavid du Colombier.LP 13657dd7cddfSDavid du Colombier[Pasa93] 13667dd7cddfSDavid du ColombierVern Paxson and Chris Saltmarsh, 13677dd7cddfSDavid du Colombier"Glish: A User-Level Software Bus for Loosely-Coupled Distributed Systems" , 13687dd7cddfSDavid du Colombier.I "Proceedings of the Winter 1993 USENIX Conference" , 13697dd7cddfSDavid du ColombierSan Diego, 1993, pp. 141-155. 13707dd7cddfSDavid du Colombier.LP 13717dd7cddfSDavid du Colombier[Pike87a] 13727dd7cddfSDavid du ColombierRob Pike, 13737dd7cddfSDavid du Colombier``Structural Regular Expressions'', 13747dd7cddfSDavid du Colombier.I "EUUG Spring 1987 Conference Proceedings" , 13757dd7cddfSDavid du ColombierHelsinki, May 1987, pp. 21-28. 13767dd7cddfSDavid du Colombier.LP 13777dd7cddfSDavid du Colombier[Pike87b] 13787dd7cddfSDavid du ColombierRob Pike, 13797dd7cddfSDavid du Colombier``The Text Editor sam'', 13807dd7cddfSDavid du Colombier.I "Software - Practice and Experience" , 13817dd7cddfSDavid du Colombier.B 17 , 13827dd7cddfSDavid du Colombier5, Nov. 1987, pp. 813-845. 13837dd7cddfSDavid du Colombier.LP 13847dd7cddfSDavid du Colombier[Pike91] 13857dd7cddfSDavid du ColombierRob Pike, 13867dd7cddfSDavid du Colombier``8½, the Plan 9 Window System'', 13877dd7cddfSDavid du Colombier.I "Proceedings of the Summer 1991 USENIX Conference" , 13887dd7cddfSDavid du ColombierNashville, 1991, pp. 257-265. 13897dd7cddfSDavid du Colombier.LP 13907dd7cddfSDavid du Colombier[Pike93] 13917dd7cddfSDavid du ColombierRob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom, 13927dd7cddfSDavid du Colombier``The Use of Name Spaces in Plan 9'', 13937dd7cddfSDavid du Colombier.I "Operating Systems Review" , 13947dd7cddfSDavid du Colombier.B 27 , 13957dd7cddfSDavid du Colombier2, April 1993, pp. 72-76. 13967dd7cddfSDavid du Colombier.LP 13977dd7cddfSDavid du Colombier[Pike94] 13987dd7cddfSDavid du ColombierRob Pike, 13997dd7cddfSDavid du Colombier``Acme: A User Interface for Programmers'', 14007dd7cddfSDavid du Colombier.I "Proceedings of the Winter 1994 USENIX Conference", 14017dd7cddfSDavid du ColombierSan Francisco, 1994, pp. 223-234. 14027dd7cddfSDavid du Colombier.LP 14037dd7cddfSDavid du Colombier[PiPr85] 14047dd7cddfSDavid du ColombierRob Pike and Dave Presotto, 14057dd7cddfSDavid du Colombier``Face the Nation'', 14067dd7cddfSDavid du Colombier.I "Proceedings of the USENIX Summer 1985 Conference" , 14077dd7cddfSDavid du ColombierPortland, 1985, pg. 81. 14087dd7cddfSDavid du Colombier.LP 14097dd7cddfSDavid du Colombier[Reis95] 14107dd7cddfSDavid du ColombierSteven P. Reiss, 14117dd7cddfSDavid du Colombier.I "The FIELD Programming Environment: A Friendly Integrated Environment for Learning and Development" , 14127dd7cddfSDavid du ColombierKluwer, Boston, 1995. 14137dd7cddfSDavid du Colombier.LP 14147dd7cddfSDavid du Colombier[Wein] 14157dd7cddfSDavid du ColombierBob Weiner, 14167dd7cddfSDavid du Colombier.I "Hyperbole User Manual" , 14177dd7cddfSDavid du Colombier.CW http://www.cs.indiana.edu/elisp/hyperbole/hyperbole_1.html 14187dd7cddfSDavid du Colombier.LP 14197dd7cddfSDavid du Colombier[Wint94] 14207dd7cddfSDavid du ColombierPhilip Winterbottom, 14217dd7cddfSDavid du Colombier``ACID: A Debugger based on a Language'', 14227dd7cddfSDavid du Colombier.I "Proceedings of the USENIX Winter Conference" , 14237dd7cddfSDavid du ColombierSan Francisco, CA, 1994. 14247dd7cddfSDavid du Colombier.LP 14257dd7cddfSDavid du Colombier[WiGu92] 14267dd7cddfSDavid du ColombierNiklaus Wirth and Jurg Gutknecht, 14277dd7cddfSDavid du Colombier.I "Project Oberon: The Design of an Operating System and Compilers" , 14287dd7cddfSDavid du ColombierAddison-Wesley, Reading, 1992. 14297dd7cddfSDavid du Colombier 1430