1*426d2b71SDavid du Colombier.HTML "Lexical File Names in Plan 9 or Getting Dot-Dot Right 27dd7cddfSDavid du Colombier.hw re-create 37dd7cddfSDavid du Colombier.hw re-created 47dd7cddfSDavid du Colombier.TL 57dd7cddfSDavid du ColombierLexical File Names in Plan 9 67dd7cddfSDavid du Colombier.br 77dd7cddfSDavid du Colombieror 87dd7cddfSDavid du Colombier.br 97dd7cddfSDavid du ColombierGetting Dot-Dot Right 107dd7cddfSDavid du Colombier.AU 117dd7cddfSDavid du ColombierRob Pike 127dd7cddfSDavid du Colombier.CW rob@plan9.bell-labs.com 137dd7cddfSDavid du Colombier.AI 147dd7cddfSDavid du Colombier.MH 157dd7cddfSDavid du Colombier.AB 167dd7cddfSDavid du Colombier.LP 177dd7cddfSDavid du ColombierSymbolic links make the Unix file system non-hierarchical, resulting in 187dd7cddfSDavid du Colombiermultiple valid path names for a given file. 197dd7cddfSDavid du ColombierThis ambiguity is a source of confusion, especially since some shells 207dd7cddfSDavid du Colombierwork overtime to present a consistent view from programs such as 217dd7cddfSDavid du Colombier.CW pwd , 227dd7cddfSDavid du Colombierwhile other programs and 237dd7cddfSDavid du Colombierthe kernel itself do nothing about the problem. 247dd7cddfSDavid du Colombier.LP 257dd7cddfSDavid du ColombierPlan 9 has no symbolic links but it does have other mechanisms that produce the same difficulty. 267dd7cddfSDavid du ColombierMoreover, Plan 9 is founded on the ability to control a program's environment 277dd7cddfSDavid du Colombierby manipulating its name space. 287dd7cddfSDavid du ColombierAmbiguous names muddle the result of operations such as copying a name space across 297dd7cddfSDavid du Colombierthe network. 307dd7cddfSDavid du Colombier.LP 317dd7cddfSDavid du ColombierTo address these problems, 327dd7cddfSDavid du Colombierthe Plan 9 kernel has been modified to maintain an accurate path name for every active 337dd7cddfSDavid du Colombierfile (open file, working directory, mount table entry) in the system. 347dd7cddfSDavid du ColombierThe definition of `accurate' is that the path name for a file is guaranteed to be the rooted, 357dd7cddfSDavid du Colombierabsolute name 367dd7cddfSDavid du Colombierthe program used to acquire it. 377dd7cddfSDavid du ColombierThese names are maintained by an efficient method that combines lexical processing\(emsuch as 387dd7cddfSDavid du Colombierevaluating 397dd7cddfSDavid du Colombier.CW .. 407dd7cddfSDavid du Colombierby just removing the last path name element of a directory\(emwith 417dd7cddfSDavid du Colombierlocal operations within the file system to maintain a consistently, easily understood view 427dd7cddfSDavid du Colombierof the name system. 437dd7cddfSDavid du ColombierAmbiguous situations are resolved by examining the lexically maintained names themselves. 447dd7cddfSDavid du Colombier.LP 457dd7cddfSDavid du ColombierA new kernel call, 467dd7cddfSDavid du Colombier.CW fd2path , 477dd7cddfSDavid du Colombierreturns the file name associated with an open file, 487dd7cddfSDavid du Colombierpermitting the use of reliable names to improve system 497dd7cddfSDavid du Colombierservices ranging from 507dd7cddfSDavid du Colombier.CW pwd 517dd7cddfSDavid du Colombierto debugging. 527dd7cddfSDavid du ColombierAlthough this work was done in Plan 9, 537dd7cddfSDavid du ColombierUnix systems could also benefit from the addition of 547dd7cddfSDavid du Colombiera method to recover the accurate name of an 557dd7cddfSDavid du Colombieropen file or the current directory. 567dd7cddfSDavid du Colombier.AE 577dd7cddfSDavid du Colombier.SH 587dd7cddfSDavid du ColombierMotivation 597dd7cddfSDavid du Colombier.LP 607dd7cddfSDavid du ColombierConsider the following unedited transcript of a session running the Bourne shell on a modern 617dd7cddfSDavid du ColombierUnix system: 627dd7cddfSDavid du Colombier.P1 637dd7cddfSDavid du Colombier% echo $HOME 647dd7cddfSDavid du Colombier/home/rob 657dd7cddfSDavid du Colombier% cd $HOME 667dd7cddfSDavid du Colombier% pwd 677dd7cddfSDavid du Colombier/n/bopp/v7/rob 687dd7cddfSDavid du Colombier% cd /home/rob 697dd7cddfSDavid du Colombier% cd /home/ken 707dd7cddfSDavid du Colombier% cd ../rob 717dd7cddfSDavid du Colombier\&../rob: bad directory 727dd7cddfSDavid du Colombier% 737dd7cddfSDavid du Colombier.P2 747dd7cddfSDavid du Colombier(The same output results from running 757dd7cddfSDavid du Colombier.CW tcsh ; 767dd7cddfSDavid du Colombierwe'll discuss 777dd7cddfSDavid du Colombier.CW ksh 787dd7cddfSDavid du Colombierin a moment.) 797dd7cddfSDavid du ColombierTo a neophyte being schooled in the delights of a hierarchical file name space, 807dd7cddfSDavid du Colombierthis behavior must be baffling. 817dd7cddfSDavid du ColombierIt is, of course, the consequence of a series of symbolic links intended to give users 827dd7cddfSDavid du Colombierthe illusion they share a disk, when in fact their files are scattered over several devices: 837dd7cddfSDavid du Colombier.P1 847dd7cddfSDavid du Colombier.ps -1 857dd7cddfSDavid du Colombier% ls -ld /home/rob /home/ken 867dd7cddfSDavid du Colombierlrwxr-xr-x 1 root sys 14 Dec 26 1998 /home/ken -> /n/bopp/v6/ken 877dd7cddfSDavid du Colombierlrwxr-xr-x 1 root sys 14 Dec 23 1998 /home/rob -> /n/bopp/v7/rob 887dd7cddfSDavid du Colombier% 897dd7cddfSDavid du Colombier.ps 907dd7cddfSDavid du Colombier.P2 917dd7cddfSDavid du ColombierThe introduction of symbolic links has changed the Unix file system from a true 927dd7cddfSDavid du Colombierhierarchy into a directed graph, rendering 937dd7cddfSDavid du Colombier.CW .. 947dd7cddfSDavid du Colombierambiguous and sowing confusion. 957dd7cddfSDavid du Colombier.LP 967dd7cddfSDavid du ColombierUnix popularized hierarchical naming, but the introduction of symbolic links 977dd7cddfSDavid du Colombiermade its naming irregular. 987dd7cddfSDavid du ColombierWorse, the 997dd7cddfSDavid du Colombier.CW pwd 1007dd7cddfSDavid du Colombiercommand, through the underlying 1017dd7cddfSDavid du Colombier.CW getwd 1027dd7cddfSDavid du Colombierlibrary routine, 1037dd7cddfSDavid du Colombieruses a tricky, expensive algorithm that often delivers the wrong answer. 1047dd7cddfSDavid du ColombierStarting from the current directory, 1057dd7cddfSDavid du Colombier.CW getwd 1067dd7cddfSDavid du Colombieropens the parent, 1077dd7cddfSDavid du Colombier.CW .. , 1087dd7cddfSDavid du Colombierand searches it for an entry whose i-number matches the current directory; 1097dd7cddfSDavid du Colombierthe matching entry is the final path element of the ultimate result. 1107dd7cddfSDavid du ColombierApplying this process iteratively, 1117dd7cddfSDavid du Colombier.CW getwd 1127dd7cddfSDavid du Colombierworks back towards the root. 1137dd7cddfSDavid du ColombierSince 1147dd7cddfSDavid du Colombier.CW getwd 1157dd7cddfSDavid du Colombierknows nothing about symbolic links, it will recover surprising names for 1167dd7cddfSDavid du Colombierdirectories reached by them, 1177dd7cddfSDavid du Colombieras illustrated by the example; 1187dd7cddfSDavid du Colombierthe backward paths 1197dd7cddfSDavid du Colombier.CW getwd 1207dd7cddfSDavid du Colombiertraverses will not backtrack across the links. 1217dd7cddfSDavid du Colombier.LP 1227dd7cddfSDavid du ColombierPartly for efficiency and partly to make 1237dd7cddfSDavid du Colombier.CW cd 1247dd7cddfSDavid du Colombierand 1257dd7cddfSDavid du Colombier.CW pwd 1267dd7cddfSDavid du Colombiermore predictable, the Korn shell 1277dd7cddfSDavid du Colombier.CW ksh 1287dd7cddfSDavid du Colombier[Korn94] 1297dd7cddfSDavid du Colombierimplements 1307dd7cddfSDavid du Colombier.CW pwd 1317dd7cddfSDavid du Colombieras a builtin. 1327dd7cddfSDavid du Colombier(The 1337dd7cddfSDavid du Colombier.CW cd 1347dd7cddfSDavid du Colombiercommand must be a builtin in any shell, since the current directory is unique to each process.) 1357dd7cddfSDavid du Colombier.CW Ksh 1367dd7cddfSDavid du Colombiermaintains its own private view of the file system to try to disguise symbolic links; 1377dd7cddfSDavid du Colombierin particular, 1387dd7cddfSDavid du Colombier.CW cd 1397dd7cddfSDavid du Colombierand 1407dd7cddfSDavid du Colombier.CW pwd 1417dd7cddfSDavid du Colombierinvolve some lexical processing (somewhat like the 1427dd7cddfSDavid du Colombier.CW cleanname 1437dd7cddfSDavid du Colombierfunction discussed later 1447dd7cddfSDavid du Colombierin this paper), augmented by heuristics such as examining the environment 1457dd7cddfSDavid du Colombierfor names like 1467dd7cddfSDavid du Colombier.CW $HOME 1477dd7cddfSDavid du Colombierand 1487dd7cddfSDavid du Colombier.CW $PWD 1497dd7cddfSDavid du Colombierto assist initialization of the state of the private view. [Korn00] 1507dd7cddfSDavid du Colombier.LP 1517dd7cddfSDavid du ColombierThis transcript begins with a Bourne shell running: 1527dd7cddfSDavid du Colombier.P1 1537dd7cddfSDavid du Colombier% cd /home/rob 1547dd7cddfSDavid du Colombier% pwd 1557dd7cddfSDavid du Colombier/n/bopp/v7/rob 1567dd7cddfSDavid du Colombier% ksh 1577dd7cddfSDavid du Colombier$ pwd 1587dd7cddfSDavid du Colombier/home/rob 1597dd7cddfSDavid du Colombier$ 1607dd7cddfSDavid du Colombier.P2 1617dd7cddfSDavid du ColombierThis result is encouraging. Another example, again starting from a Bourne shell: 1627dd7cddfSDavid du Colombier.P1 1637dd7cddfSDavid du Colombier% cd /home/rob 1647dd7cddfSDavid du Colombier% cd ../ken 1657dd7cddfSDavid du Colombier\&../ken: bad directory 1667dd7cddfSDavid du Colombier% ksh 1677dd7cddfSDavid du Colombier$ pwd 1687dd7cddfSDavid du Colombier/home/rob 1697dd7cddfSDavid du Colombier$ cd ../ken 1707dd7cddfSDavid du Colombier$ pwd 1717dd7cddfSDavid du Colombier/home/ken 1727dd7cddfSDavid du Colombier$ 1737dd7cddfSDavid du Colombier.P2 1747dd7cddfSDavid du ColombierBy doing extra work, 1757dd7cddfSDavid du Colombierthe Korn shell is providing more sensible behavior, 1767dd7cddfSDavid du Colombierbut it is easy to defeat: 1777dd7cddfSDavid du Colombier.P1 1787dd7cddfSDavid du Colombier% cd /home/rob 1797dd7cddfSDavid du Colombier% pwd 1807dd7cddfSDavid du Colombier/n/bopp/v7/rob 1817dd7cddfSDavid du Colombier% cd bin 1827dd7cddfSDavid du Colombier% pwd 1837dd7cddfSDavid du Colombier/n/bopp/v7/rob/bin 1847dd7cddfSDavid du Colombier% ksh 1857dd7cddfSDavid du Colombier$ pwd 1867dd7cddfSDavid du Colombier/n/bopp/v7/rob/bin 1877dd7cddfSDavid du Colombier$ exit 1887dd7cddfSDavid du Colombier% cd /home/ken 1897dd7cddfSDavid du Colombier% pwd 1907dd7cddfSDavid du Colombier/n/bopp/v6/ken 1917dd7cddfSDavid du Colombier% ksh 1927dd7cddfSDavid du Colombier$ pwd 1937dd7cddfSDavid du Colombier/n/bopp/v6/ken 1947dd7cddfSDavid du Colombier$ 1957dd7cddfSDavid du Colombier.P2 1967dd7cddfSDavid du ColombierIn these examples, 1977dd7cddfSDavid du Colombier.CW ksh 's 1987dd7cddfSDavid du Colombierbuilt-in 1997dd7cddfSDavid du Colombier.CW pwd 2007dd7cddfSDavid du Colombierfailed to produce the results 2017dd7cddfSDavid du Colombier.CW /home/rob/bin "" ( 2027dd7cddfSDavid du Colombierand 2037dd7cddfSDavid du Colombier.CW /home/ken ) 2047dd7cddfSDavid du Colombierthat the previous example might have led us to expect. 2057dd7cddfSDavid du ColombierThe Korn shell is hiding the problem, not solving it, and in fact is not even hiding it very well. 2067dd7cddfSDavid du Colombier.LP 2077dd7cddfSDavid du ColombierA deeper question is whether the shell should even be trying to make 2087dd7cddfSDavid du Colombier.CW pwd 2097dd7cddfSDavid du Colombierand 2107dd7cddfSDavid du Colombier.CW cd 2117dd7cddfSDavid du Colombierdo a better job. 2127dd7cddfSDavid du ColombierIf it does, then the 2137dd7cddfSDavid du Colombier.CW getwd 2147dd7cddfSDavid du Colombierlibrary call and every program that uses it will behave differently from the shell, 2157dd7cddfSDavid du Colombiera situation that is sure to confuse. 2167dd7cddfSDavid du ColombierMoreover, the ability to change directory to 2177dd7cddfSDavid du Colombier.CW ../ken 2187dd7cddfSDavid du Colombierwith the Korn shell's 2197dd7cddfSDavid du Colombier.CW cd 2207dd7cddfSDavid du Colombiercommand but not with the 2217dd7cddfSDavid du Colombier.CW chdir 2227dd7cddfSDavid du Colombiersystem call is a symptom of a diseased system, not a healthy shell. 2237dd7cddfSDavid du Colombier.LP 2247dd7cddfSDavid du ColombierThe operating system should provide names that work and make sense. 2257dd7cddfSDavid du ColombierSymbolic links, though, are here to stay, so we need a way to provide 2267dd7cddfSDavid du Colombiersensible, unambiguous names in the face of a non-hierarchical name space. 2277dd7cddfSDavid du ColombierThis paper shows how the challenge was met on Plan 9, an operating system 2287dd7cddfSDavid du Colombierwith Unix-like naming. 2297dd7cddfSDavid du Colombier.SH 2307dd7cddfSDavid du ColombierNames in Plan 9 2317dd7cddfSDavid du Colombier.LP 2327dd7cddfSDavid du ColombierExcept for some details involved with bootstrapping, file names in Plan 9 have the same syntax as in Unix. 2337dd7cddfSDavid du ColombierPlan 9 has no symbolic links, but its name space construction operators, 2347dd7cddfSDavid du Colombier.CW bind 2357dd7cddfSDavid du Colombierand 2367dd7cddfSDavid du Colombier.CW mount , 2377dd7cddfSDavid du Colombiermake it possible to build the same sort of non-hierarchical structures created 2387dd7cddfSDavid du Colombierby symbolically linking directories on Unix. 2397dd7cddfSDavid du Colombier.LP 2407dd7cddfSDavid du ColombierPlan 9's 2417dd7cddfSDavid du Colombier.CW mount 2427dd7cddfSDavid du Colombiersystem call takes a file descriptor 2437dd7cddfSDavid du Colombierand attaches to the local name space the file system service it represents: 2447dd7cddfSDavid du Colombier.P1 2457dd7cddfSDavid du Colombiermount(fd, "/dir", flags) 2467dd7cddfSDavid du Colombier.P2 2477dd7cddfSDavid du ColombierHere 2487dd7cddfSDavid du Colombier.CW fd 2497dd7cddfSDavid du Colombieris a file descriptor to a communications port such as a pipe or network connection; 2507dd7cddfSDavid du Colombierat the other end of the port is a service, such as file server, that talks 9P, the Plan 9 file 2517dd7cddfSDavid du Colombiersystem protocol. 2527dd7cddfSDavid du ColombierAfter the call succeeds, the root directory of the service will be visible at the 2537dd7cddfSDavid du Colombier.I "mount point 2547dd7cddfSDavid du Colombier.CW /dir , 2557dd7cddfSDavid du Colombiermuch as with the 2567dd7cddfSDavid du Colombier.CW mount 2577dd7cddfSDavid du Colombiercall of Unix. 2587dd7cddfSDavid du ColombierThe 2597dd7cddfSDavid du Colombier.CW flag 2607dd7cddfSDavid du Colombierargument specifies the nature of the attachment: 2617dd7cddfSDavid du Colombier.CW MREPL 2627dd7cddfSDavid du Colombiersays that the contents of the root directory (appear to) replace the current contents of 2637dd7cddfSDavid du Colombier.CW /dir ; 2647dd7cddfSDavid du Colombier.CW MAFTER 2657dd7cddfSDavid du Colombiersays that the current contents of 2667dd7cddfSDavid du Colombier.CW dir 2677dd7cddfSDavid du Colombierremain visible, with the mounted directory's contents appearing 2687dd7cddfSDavid du Colombier.I after 2697dd7cddfSDavid du Colombierany existing files; 2707dd7cddfSDavid du Colombierand 2717dd7cddfSDavid du Colombier.CW MBEFORE 2727dd7cddfSDavid du Colombiersays that the contents remain visible, with 2737dd7cddfSDavid du Colombierthe mounted directory's contents appearing 2747dd7cddfSDavid du Colombier.I before 2757dd7cddfSDavid du Colombierany existing files. 2767dd7cddfSDavid du ColombierThese multicomponent directories are called 2777dd7cddfSDavid du Colombier.I "union directories 2787dd7cddfSDavid du Colombierand are somewhat different from union directories in 4.4BSD-Lite [PeMc95], because 2797dd7cddfSDavid du Colombieronly the top-level directory itself is unioned, not its descendents, recursively. 2807dd7cddfSDavid du Colombier(Plan 9's union directories are used differently from 4.4BSD-Lite's, as will become apparent.) 2817dd7cddfSDavid du Colombier.LP 2827dd7cddfSDavid du ColombierFor example, to bootstrap a diskless computer the system builds a local name space containing 2837dd7cddfSDavid du Colombieronly the root directory, 2847dd7cddfSDavid du Colombier.CW / , 2857dd7cddfSDavid du Colombierthen uses the network to open a connection 2867dd7cddfSDavid du Colombierto the main file server. 2877dd7cddfSDavid du ColombierIt then executes 2887dd7cddfSDavid du Colombier.P1 2897dd7cddfSDavid du Colombiermount(rootfd, "/", MREPL); 2907dd7cddfSDavid du Colombier.P2 2917dd7cddfSDavid du ColombierAfter this call, the entire file server's tree is visible, starting from the root of the local machine. 2927dd7cddfSDavid du Colombier.LP 2937dd7cddfSDavid du ColombierWhile 2947dd7cddfSDavid du Colombier.CW mount 2957dd7cddfSDavid du Colombierconnects a new service to the local name space, 2967dd7cddfSDavid du Colombier.CW bind 2977dd7cddfSDavid du Colombierrearranges the existing name space: 2987dd7cddfSDavid du Colombier.P1 2997dd7cddfSDavid du Colombierbind("tofile", "fromfile", flags) 3007dd7cddfSDavid du Colombier.P2 3017dd7cddfSDavid du Colombiercauses subsequent mention of the 3027dd7cddfSDavid du Colombier.CW fromfile 3037dd7cddfSDavid du Colombier(which may be a plain file or a directory) 3047dd7cddfSDavid du Colombierto behave as though 3057dd7cddfSDavid du Colombier.CW tofile 3067dd7cddfSDavid du Colombierhad been mentioned instead, somewhat like a symbolic link. 3077dd7cddfSDavid du Colombier(Note, however, that the arguments are in the opposite order 3087dd7cddfSDavid du Colombiercompared to 3097dd7cddfSDavid du Colombier.CW ln 3107dd7cddfSDavid du Colombier.CW -s ). 3117dd7cddfSDavid du ColombierThe 3127dd7cddfSDavid du Colombier.CW flags 3137dd7cddfSDavid du Colombierargument is the same as with 3147dd7cddfSDavid du Colombier.CW mount . 3157dd7cddfSDavid du Colombier.LP 3167dd7cddfSDavid du ColombierAs an example, a sequence something like the following is done at bootstrap time to 3177dd7cddfSDavid du Colombierassemble, under the single directory 3187dd7cddfSDavid du Colombier.CW /bin , 3197dd7cddfSDavid du Colombierall of the binaries suitable for this architecture, represented by (say) the string 3207dd7cddfSDavid du Colombier.CW sparc : 3217dd7cddfSDavid du Colombier.P1 3227dd7cddfSDavid du Colombierbind("/sparc/bin", "/bin", MREPL); 3237dd7cddfSDavid du Colombierbind("/usr/rob/sparc/bin", "/bin", MAFTER); 3247dd7cddfSDavid du Colombier.P2 3257dd7cddfSDavid du ColombierThis sequence of 3267dd7cddfSDavid du Colombier.CW binds 3277dd7cddfSDavid du Colombiercauses 3287dd7cddfSDavid du Colombier.CW /bin 3297dd7cddfSDavid du Colombierto contain first the standard binaries, then the contents of 3307dd7cddfSDavid du Colombier.CW rob 's 3317dd7cddfSDavid du Colombierprivate SPARC binaries. 3327dd7cddfSDavid du ColombierThe ability to build such union directories 3337dd7cddfSDavid du Colombierobviates the need for a shell 3347dd7cddfSDavid du Colombier.CW $PATH 3357dd7cddfSDavid du Colombiervariable 3367dd7cddfSDavid du Colombierwhile providing opportunities for managing heterogeneity. 3377dd7cddfSDavid du ColombierIf the system were a Power PC, the same sequence would be run with 3387dd7cddfSDavid du Colombier.CW power 3397dd7cddfSDavid du Colombiertextually substituted for 3407dd7cddfSDavid du Colombier.CW sparc 3417dd7cddfSDavid du Colombierto place the Power PC binaries in 3427dd7cddfSDavid du Colombier.CW /bin 3437dd7cddfSDavid du Colombierrather than the SPARC binaries. 3447dd7cddfSDavid du Colombier.LP 3457dd7cddfSDavid du ColombierTrouble is already brewing. After these bindings are set up, 3467dd7cddfSDavid du Colombierwhere does 3477dd7cddfSDavid du Colombier.P1 3487dd7cddfSDavid du Colombier% cd /bin 3497dd7cddfSDavid du Colombier% cd .. 3507dd7cddfSDavid du Colombier.P2 3517dd7cddfSDavid du Colombierset the current working directory, to 3527dd7cddfSDavid du Colombier.CW / 3537dd7cddfSDavid du Colombieror 3547dd7cddfSDavid du Colombier.CW /sparc 3557dd7cddfSDavid du Colombieror 3567dd7cddfSDavid du Colombier.CW /usr/rob/sparc ? 3577dd7cddfSDavid du ColombierWe will return to this issue. 3587dd7cddfSDavid du Colombier.LP 3597dd7cddfSDavid du ColombierThere are some important differences between 3607dd7cddfSDavid du Colombier.CW binds 3617dd7cddfSDavid du Colombierand symbolic links. 3627dd7cddfSDavid du ColombierFirst, 3637dd7cddfSDavid du Colombiersymbolic links are a static part of the file system, while 3647dd7cddfSDavid du ColombierPlan 9 bindings are created at run time, are stored in the kernel, 3657dd7cddfSDavid du Colombierand endure only as long as the system maintains them; 3667dd7cddfSDavid du Colombierthey are temporary. 3677dd7cddfSDavid du ColombierSince they are known to the kernel but not the file system, they must 3687dd7cddfSDavid du Colombierbe set up each time the kernel boots or a user logs in; 3697dd7cddfSDavid du Colombierpermanent bindings are created by editing system initialization scripts 3707dd7cddfSDavid du Colombierand user profiles rather than by building them in the file system itself. 3717dd7cddfSDavid du Colombier.LP 3727dd7cddfSDavid du ColombierThe Plan 9 kernel records what bindings are active for a process, 3737dd7cddfSDavid du Colombierwhereas symbolic links, being held on the Unix file server, may strike whenever the process evaluates 3747dd7cddfSDavid du Colombiera file name. 3757dd7cddfSDavid du ColombierAlso, symbolic links apply to all processes that evaluate the affected file, whereas 3767dd7cddfSDavid du Colombier.CW bind 3777dd7cddfSDavid du Colombierhas a local scope, applying only to the process that executes it and possibly some of its 3787dd7cddfSDavid du Colombierpeers, as discussed in the next section. 3797dd7cddfSDavid du ColombierSymbolic links cannot construct the sort of 3807dd7cddfSDavid du Colombier.CW /bin 3817dd7cddfSDavid du Colombierdirectory built here; it is possible to have multiple directories point to 3827dd7cddfSDavid du Colombier.CW /bin 3837dd7cddfSDavid du Colombierbut not the other way around. 3847dd7cddfSDavid du Colombier.LP 3857dd7cddfSDavid du ColombierFinally, 3867dd7cddfSDavid du Colombiersymbolic links are symbolic, like macros: they evaluate the associated names each time 3877dd7cddfSDavid du Colombierthey are accessed. 3887dd7cddfSDavid du ColombierBindings, on the other hand, are evaluated only once, when the bind is executed; 3897dd7cddfSDavid du Colombierafter the binding is set up, the kernel associates the underlying files, rather than their names. 3907dd7cddfSDavid du ColombierIn fact, the kernel's representation of a bind is identical to its representation of a mount; 3917dd7cddfSDavid du Colombierin effect, a bind is a mount of the 3927dd7cddfSDavid du Colombier.CW tofile 3937dd7cddfSDavid du Colombierupon the 3947dd7cddfSDavid du Colombier.CW fromfile . 3957dd7cddfSDavid du ColombierThe binds and mounts coexist in a single 3967dd7cddfSDavid du Colombier.I "mount table" , 3977dd7cddfSDavid du Colombierthe subject of the next section. 3987dd7cddfSDavid du Colombier.SH 3997dd7cddfSDavid du ColombierThe Mount Table 4007dd7cddfSDavid du Colombier.LP 4017dd7cddfSDavid du ColombierUnix has a single global mount table 4027dd7cddfSDavid du Colombierfor all processes in the system, but Plan 9's mount tables are local to each process. 4037dd7cddfSDavid du ColombierBy default it is inherited when a process forks, so mounts and binds made by one 4047dd7cddfSDavid du Colombierprocess affect the other, but a process may instead inherit a copy, 4057dd7cddfSDavid du Colombierso modifications it makes will be invisible to other processes. 4067dd7cddfSDavid du ColombierThe convention is that related processes, such 4077dd7cddfSDavid du Colombieras processes running in a single window, share a mount table, while sets of processes 4087dd7cddfSDavid du Colombierin different windows have distinct mount tables. 4097dd7cddfSDavid du ColombierIn practice, the name spaces of the two windows will appear largely the same, 4107dd7cddfSDavid du Colombierbut the possibility for different processes to see different files (hence services) under 4117dd7cddfSDavid du Colombierthe same name is fundamental to the system, 4127dd7cddfSDavid du Colombieraffecting the design of key programs such as the 4137dd7cddfSDavid du Colombierwindow system [Pike91]. 4147dd7cddfSDavid du Colombier.LP 4157dd7cddfSDavid du ColombierThe Plan 9 mount table is little more than an ordered list of pairs, mapping the 4167dd7cddfSDavid du Colombier.CW fromfiles 4177dd7cddfSDavid du Colombierto the 4187dd7cddfSDavid du Colombier.CW tofiles . 4197dd7cddfSDavid du ColombierFor mounts, the 4207dd7cddfSDavid du Colombier.CW tofile 4217dd7cddfSDavid du Colombierwill be an item called a 4227dd7cddfSDavid du Colombier.CW Channel , 4237dd7cddfSDavid du Colombiersimilar to a Unix 4247dd7cddfSDavid du Colombier.CW vnode , 4257dd7cddfSDavid du Colombierpointing to the root of the file service, 4267dd7cddfSDavid du Colombierwhile for a bind it will be the 4277dd7cddfSDavid du Colombier.CW Channel 4287dd7cddfSDavid du Colombierpointing to the 4297dd7cddfSDavid du Colombier.CW tofile 4307dd7cddfSDavid du Colombiermentioned in the 4317dd7cddfSDavid du Colombier.CW bind 4327dd7cddfSDavid du Colombiercall. 4337dd7cddfSDavid du ColombierIn both cases, the 4347dd7cddfSDavid du Colombier.CW fromfile 4357dd7cddfSDavid du Colombierentry in the table 4367dd7cddfSDavid du Colombierwill be a 4377dd7cddfSDavid du Colombier.CW Channel 4387dd7cddfSDavid du Colombierpointing to the 4397dd7cddfSDavid du Colombier.CW fromfile 4407dd7cddfSDavid du Colombieritself. 4417dd7cddfSDavid du Colombier.LP 4427dd7cddfSDavid du ColombierThe evaluation of a file name proceeds as follows. 4437dd7cddfSDavid du ColombierIf the name begins with a slash, start with the 4447dd7cddfSDavid du Colombier.CW Channel 4457dd7cddfSDavid du Colombierfor the root; otherwise start with the 4467dd7cddfSDavid du Colombier.CW Channel 4477dd7cddfSDavid du Colombierfor the current directory of the process. 4487dd7cddfSDavid du ColombierFor each path element in the name, 4497dd7cddfSDavid du Colombiersuch as 4507dd7cddfSDavid du Colombier.CW usr 4517dd7cddfSDavid du Colombierin 4527dd7cddfSDavid du Colombier.CW /usr/rob , 4537dd7cddfSDavid du Colombiertry to `walk' the 4547dd7cddfSDavid du Colombier.CW Channel 4557dd7cddfSDavid du Colombierto that element [Pike93]. 4567dd7cddfSDavid du ColombierIf the walk succeeds, look to see if the resulting 4577dd7cddfSDavid du Colombier.CW Channel 4587dd7cddfSDavid du Colombieris the same as any 4597dd7cddfSDavid du Colombier.CW fromfile 4607dd7cddfSDavid du Colombierin the mount table, and if so, replace it by the corresponding 4617dd7cddfSDavid du Colombier.CW tofile . 4627dd7cddfSDavid du ColombierAdvance to the next element and continue. 4637dd7cddfSDavid du Colombier.LP 4647dd7cddfSDavid du ColombierThere are a couple of nuances. If the directory being walked is a union directory, 4657dd7cddfSDavid du Colombierthe walk is attempted in the elements of the union, in order, until a walk succeeds. 4667dd7cddfSDavid du ColombierIf none succeed, the operation fails. 4677dd7cddfSDavid du ColombierAlso, when the destination of a walk is a directory for a purpose such as the 4687dd7cddfSDavid du Colombier.CW chdir 4697dd7cddfSDavid du Colombiersystem call or the 4707dd7cddfSDavid du Colombier.CW fromfile 4717dd7cddfSDavid du Colombierin a 4727dd7cddfSDavid du Colombier.CW bind , 4737dd7cddfSDavid du Colombieronce the final walk of the sequence has completed the operation stops; 4747dd7cddfSDavid du Colombierthe final check through the mount table is not done. 4757dd7cddfSDavid du ColombierAmong other things, this simplifies the management of union directories; 4767dd7cddfSDavid du Colombierfor example, subsequent 4777dd7cddfSDavid du Colombier.CW bind 4787dd7cddfSDavid du Colombiercalls will append to the union associated with the underlying 4797dd7cddfSDavid du Colombier.CW fromfile 4807dd7cddfSDavid du Colombierinstead of what is bound upon it. 4817dd7cddfSDavid du Colombier.SH 4827dd7cddfSDavid du ColombierA Definition of Dot-Dot 4837dd7cddfSDavid du Colombier.LP 4847dd7cddfSDavid du ColombierThe ability to construct union directories and other intricate naming structures 4857dd7cddfSDavid du Colombierintroduces some thorny problems: as with symbolic links, 4867dd7cddfSDavid du Colombierthe name space is no longer hierarchical, files and directories can have multiple 4877dd7cddfSDavid du Colombiernames, and the meaning of 4887dd7cddfSDavid du Colombier.CW .. , 4897dd7cddfSDavid du Colombierthe parent directory, can be ambiguous. 4907dd7cddfSDavid du Colombier.LP 4917dd7cddfSDavid du ColombierThe meaning of 4927dd7cddfSDavid du Colombier.CW .. 4937dd7cddfSDavid du Colombieris straightforward if the directory is in a locally hierarchical part of the name space, 4947dd7cddfSDavid du Colombierbut if we ask what 4957dd7cddfSDavid du Colombier.CW .. 4967dd7cddfSDavid du Colombiershould identify when the current directory is a mount point or union directory or 4977dd7cddfSDavid du Colombiermultiply symlinked spot (which we will henceforth call just a mount point, for brevity), 4987dd7cddfSDavid du Colombierthere is no obvious answer. 4997dd7cddfSDavid du ColombierName spaces have been part of Plan 9 from the beginning, but the definition of 5007dd7cddfSDavid du Colombier.CW .. 5017dd7cddfSDavid du Colombierhas changed several times as we grappled with this issue. 5027dd7cddfSDavid du ColombierIn fact, several attempts to clarify the meaning of 5037dd7cddfSDavid du Colombier.CW .. 5047dd7cddfSDavid du Colombierby clever coding 5057dd7cddfSDavid du Colombierresulted in definitions that could charitably be summarized as `what the implementation gives.' 5067dd7cddfSDavid du Colombier.LP 5077dd7cddfSDavid du ColombierFrustrated by this situation, and eager to have better-defined names for some of the 5087dd7cddfSDavid du Colombierapplications described later in this paper, we recently proposed the following definition 5097dd7cddfSDavid du Colombierfor 5107dd7cddfSDavid du Colombier.CW .. : 5117dd7cddfSDavid du Colombier.IP 5127dd7cddfSDavid du ColombierThe parent of a directory 5137dd7cddfSDavid du Colombier.I X , 5147dd7cddfSDavid du Colombier.I X\f(CW/..\f1, 5157dd7cddfSDavid du Colombieris the same directory that would obtain if 5167dd7cddfSDavid du Colombierwe instead accessed the directory named by stripping away the last 5177dd7cddfSDavid du Colombierpath name element of 5187dd7cddfSDavid du Colombier.I X . 5197dd7cddfSDavid du Colombier.LP 5207dd7cddfSDavid du ColombierFor example, if we are in the directory 5217dd7cddfSDavid du Colombier.CW /a/b/c 5227dd7cddfSDavid du Colombierand 5237dd7cddfSDavid du Colombier.CW chdir 5247dd7cddfSDavid du Colombierto 5257dd7cddfSDavid du Colombier.CW .. , 5267dd7cddfSDavid du Colombierthe result is 5277dd7cddfSDavid du Colombier.I exactly 5287dd7cddfSDavid du Colombieras if we had executed a 5297dd7cddfSDavid du Colombier.CW chdir 5307dd7cddfSDavid du Colombierto 5317dd7cddfSDavid du Colombier.CW /a/b . 5327dd7cddfSDavid du Colombier.LP 5337dd7cddfSDavid du ColombierThis definition is easy to understand and seems natural. 5347dd7cddfSDavid du ColombierIt is, however, a purely 5357dd7cddfSDavid du Colombier.I lexical 5367dd7cddfSDavid du Colombierdefinition that flatly ignores evaluated file names, mount tables, and 5377dd7cddfSDavid du Colombierother kernel-resident data structures. 5387dd7cddfSDavid du ColombierOur challenge is to implement it efficiently. 5397dd7cddfSDavid du ColombierOne obvious (and correct) 5407dd7cddfSDavid du Colombierimplementation is to rewrite path names lexically to fold out 5417dd7cddfSDavid du Colombier.CW .. , 5427dd7cddfSDavid du Colombierand then evaluate the file name forward from the root, 5437dd7cddfSDavid du Colombierbut this is expensive and unappealing. 5447dd7cddfSDavid du ColombierWe want to be able to use local operations to evaluate file names, 5457dd7cddfSDavid du Colombierbut maintain the global, lexical definition of dot-dot. 5467dd7cddfSDavid du ColombierIt isn't too hard. 5477dd7cddfSDavid du Colombier.SH 5487dd7cddfSDavid du ColombierThe Implementation 5497dd7cddfSDavid du Colombier.LP 5507dd7cddfSDavid du ColombierTo operate lexically on file names, we associate a name with each open file in the kernel, that 5517dd7cddfSDavid du Colombieris, with each 5527dd7cddfSDavid du Colombier.CW Channel 5537dd7cddfSDavid du Colombierdata structure. 5547dd7cddfSDavid du ColombierThe first step is therefore to store a 5557dd7cddfSDavid du Colombier.CW char* 5567dd7cddfSDavid du Colombierwith each 5577dd7cddfSDavid du Colombier.CW Channel 5587dd7cddfSDavid du Colombierin the system, called its 5597dd7cddfSDavid du Colombier.CW Cname , 5607dd7cddfSDavid du Colombierthat records the 5617dd7cddfSDavid du Colombier.I absolute 5627dd7cddfSDavid du Colombierrooted 5637dd7cddfSDavid du Colombierfile name for the 5647dd7cddfSDavid du Colombier.CW Channel . 5657dd7cddfSDavid du Colombier.CW Cnames 5667dd7cddfSDavid du Colombierare stored as full text strings, shared copy-on-write for efficiency. 5677dd7cddfSDavid du ColombierThe task is to maintain each 5687dd7cddfSDavid du Colombier.CW Cname 5697dd7cddfSDavid du Colombieras an accurate absolute name using only local operations. 5707dd7cddfSDavid du Colombier.LP 5717dd7cddfSDavid du ColombierWhen a file is opened, the file name argument in the 5727dd7cddfSDavid du Colombier.CW open 5737dd7cddfSDavid du Colombier(or 5747dd7cddfSDavid du Colombier.CW chdir 5757dd7cddfSDavid du Colombieror 5767dd7cddfSDavid du Colombier.CW bind 5777dd7cddfSDavid du Colombieror ...) call is recorded in the 5787dd7cddfSDavid du Colombier.CW Cname 5797dd7cddfSDavid du Colombierof the resulting 5807dd7cddfSDavid du Colombier.CW Channel . 5817dd7cddfSDavid du ColombierWhen the file name begins with a slash, the name is stored as is, 5827dd7cddfSDavid du Colombiersubject to a cleanup pass described in the next section. 5837dd7cddfSDavid du ColombierOtherwise, it is a local name, and the file name must be made 5847dd7cddfSDavid du Colombierabsolute by prefixing it with the 5857dd7cddfSDavid du Colombier.CW Cname 5867dd7cddfSDavid du Colombierof the current directory, followed by a slash. 5877dd7cddfSDavid du ColombierFor example, if we are in 5887dd7cddfSDavid du Colombier.CW /home/rob 5897dd7cddfSDavid du Colombierand 5907dd7cddfSDavid du Colombier.CW chdir 5917dd7cddfSDavid du Colombierto 5927dd7cddfSDavid du Colombier.CW bin , 5937dd7cddfSDavid du Colombierthe 5947dd7cddfSDavid du Colombier.CW Cname 5957dd7cddfSDavid du Colombierof the resulting 5967dd7cddfSDavid du Colombier.CW Channel 5977dd7cddfSDavid du Colombierwill be the string 5987dd7cddfSDavid du Colombier.CW /home/rob/bin . 5997dd7cddfSDavid du Colombier.LP 6007dd7cddfSDavid du ColombierThis assumes, of course, that the local file name contains no 6017dd7cddfSDavid du Colombier.CW .. 6027dd7cddfSDavid du Colombierelements. 6037dd7cddfSDavid du ColombierIf it does, instead of storing for example 6047dd7cddfSDavid du Colombier.CW /home/rob/.. 6057dd7cddfSDavid du Colombierwe delete the last element of the existing name and set the 6067dd7cddfSDavid du Colombier.CW Cname 6077dd7cddfSDavid du Colombierto 6087dd7cddfSDavid du Colombier.CW /home . 6097dd7cddfSDavid du ColombierTo maintain the lexical naming property we must guarantee that the resulting 6107dd7cddfSDavid du Colombier.CW Cname , 6117dd7cddfSDavid du Colombierif it were to be evaluated, would yield the identical directory to the one 6127dd7cddfSDavid du Colombierwe actually do get by the local 6137dd7cddfSDavid du Colombier.CW .. 6147dd7cddfSDavid du Colombieroperation. 6157dd7cddfSDavid du Colombier.LP 6167dd7cddfSDavid du ColombierIf the current directory is not a mount point, it is easy to maintain the lexical property. 6177dd7cddfSDavid du ColombierIf it is a mount point, though, it is still possible to maintain it on Plan 9 6187dd7cddfSDavid du Colombierbecause the mount table, a kernel-resident data structure, contains all the 6197dd7cddfSDavid du Colombierinformation about the non-hierarchical connectivity of the name space. 6207dd7cddfSDavid du Colombier(On Unix, by contrast, symbolic links are stored on the file server rather than in the kernel.) 6217dd7cddfSDavid du ColombierMoreover, the presence of a full file name for each 6227dd7cddfSDavid du Colombier.CW Channel 6237dd7cddfSDavid du Colombierin the mount table provides the information necessary to resolve ambiguities. 6247dd7cddfSDavid du Colombier.LP 6257dd7cddfSDavid du ColombierThe mount table is examined in the 6267dd7cddfSDavid du Colombier.CW from\f1\(->\fPto 6277dd7cddfSDavid du Colombierdirection when evaluating a name, but 6287dd7cddfSDavid du Colombier.CW .. 6297dd7cddfSDavid du Colombierpoints backwards in the hierarchy, so to evaluate 6307dd7cddfSDavid du Colombier.CW .. 6317dd7cddfSDavid du Colombierthe table must be examined in the 6327dd7cddfSDavid du Colombier.CW to\f1\(->\fPfrom 6337dd7cddfSDavid du Colombierdirection. 6347dd7cddfSDavid du Colombier(``How did we get here?'') 6357dd7cddfSDavid du Colombier.LP 6367dd7cddfSDavid du ColombierThe value of 6377dd7cddfSDavid du Colombier.CW .. 6387dd7cddfSDavid du Colombieris ambiguous when there are multiple bindings (mount points) that point to 6397dd7cddfSDavid du Colombierthe directories involved in the evaluation of 6407dd7cddfSDavid du Colombier.CW .. . 6417dd7cddfSDavid du ColombierFor example, return to our original script with 6427dd7cddfSDavid du Colombier.CW /n/bopp/v6 6437dd7cddfSDavid du Colombier(containing a home directory for 6447dd7cddfSDavid du Colombier.CW ken ) 6457dd7cddfSDavid du Colombierand 6467dd7cddfSDavid du Colombier.CW /n/bopp/v7 6477dd7cddfSDavid du Colombier(containing a home directory for 6487dd7cddfSDavid du Colombier.CW rob ) 6497dd7cddfSDavid du Colombierunioned into 6507dd7cddfSDavid du Colombier.CW /home . 6517dd7cddfSDavid du ColombierThis is represented by two entries in the mount table, 6527dd7cddfSDavid du Colombier.CW from=/home , 6537dd7cddfSDavid du Colombier.CW to=/n/bopp/v6 6547dd7cddfSDavid du Colombierand 6557dd7cddfSDavid du Colombier.CW from=/home , 6567dd7cddfSDavid du Colombier.CW to=/n/bopp/v7 . 6577dd7cddfSDavid du ColombierIf we have set our current directory to 6587dd7cddfSDavid du Colombier.CW /home/rob 6597dd7cddfSDavid du Colombier(which has landed us in the physical location 6607dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob ) 6617dd7cddfSDavid du Colombierour current directory is not a mount point but its parent is. 6627dd7cddfSDavid du ColombierThe value of 6637dd7cddfSDavid du Colombier.CW .. 6647dd7cddfSDavid du Colombieris ambiguous: it could be 6657dd7cddfSDavid du Colombier.CW /home , 6667dd7cddfSDavid du Colombier.CW /n/bopp/v7 , 6677dd7cddfSDavid du Colombieror maybe even 6687dd7cddfSDavid du Colombier.CW /n/bopp/v6 , 6697dd7cddfSDavid du Colombierand the ambiguity is caused by two 6707dd7cddfSDavid du Colombier.CW tofiles 6717dd7cddfSDavid du Colombierbound to the same 6727dd7cddfSDavid du Colombier.CW fromfile . 6737dd7cddfSDavid du ColombierBy our definition, if we now evaluate 6747dd7cddfSDavid du Colombier.CW .. , 6757dd7cddfSDavid du Colombierwe should acquire the directory 6767dd7cddfSDavid du Colombier.CW /home ; 6777dd7cddfSDavid du Colombierotherwise 6787dd7cddfSDavid du Colombier.CW ../ken 6797dd7cddfSDavid du Colombiercould not possibly result in 6807dd7cddfSDavid du Colombier.CW ken 's 6817dd7cddfSDavid du Colombierhome directory, which it should. 6827dd7cddfSDavid du ColombierOn the other hand, if we had originally gone to 6837dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob , 6847dd7cddfSDavid du Colombierthe name 6857dd7cddfSDavid du Colombier.CW ../ken 6867dd7cddfSDavid du Colombiershould 6877dd7cddfSDavid du Colombier.I not 6887dd7cddfSDavid du Colombierevaluate to 6897dd7cddfSDavid du Colombier.CW ken 's 6907dd7cddfSDavid du Colombierhome directory because there is no directory 6917dd7cddfSDavid du Colombier.CW /n/bopp/v7/ken 6927dd7cddfSDavid du Colombier.CW ken 's ( 6937dd7cddfSDavid du Colombierhome directory is on 6947dd7cddfSDavid du Colombier.CW v6 ). 6957dd7cddfSDavid du ColombierThe problem is that by using local file operations, it is impossible 6967dd7cddfSDavid du Colombierto distinguish these cases: regardless of whether we got here using the name 6977dd7cddfSDavid du Colombier.CW /home/rob 6987dd7cddfSDavid du Colombieror 6997dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob , 7007dd7cddfSDavid du Colombierthe resulting directory is the same. 7017dd7cddfSDavid du ColombierMoreover, the mount table does not itself have enough information 7027dd7cddfSDavid du Colombierto disambiguate: when we do a local operation to evaluate 7037dd7cddfSDavid du Colombier.CW .. 7047dd7cddfSDavid du Colombierand land in 7057dd7cddfSDavid du Colombier.CW /n/bopp/v7 , 7067dd7cddfSDavid du Colombierwe discover that the directory is a 7077dd7cddfSDavid du Colombier.CW tofile 7087dd7cddfSDavid du Colombierin the mount table; should we step back through the table to 7097dd7cddfSDavid du Colombier.CW /home 7107dd7cddfSDavid du Colombieror not? 7117dd7cddfSDavid du Colombier.LP 7127dd7cddfSDavid du ColombierThe solution comes from the 7137dd7cddfSDavid du Colombier.CW Cnames 7147dd7cddfSDavid du Colombierthemselves. 7157dd7cddfSDavid du ColombierWhether to step back through the mount point 7167dd7cddfSDavid du Colombier.CW from=/home , 7177dd7cddfSDavid du Colombier.CW to=/n/bopp/v7 7187dd7cddfSDavid du Colombierwhen evaluating 7197dd7cddfSDavid du Colombier.CW .. 7207dd7cddfSDavid du Colombierin 7217dd7cddfSDavid du Colombier.CW rob 's 7227dd7cddfSDavid du Colombierdirectory is trivially resolved by asking the question, 7237dd7cddfSDavid du ColombierDoes the 7247dd7cddfSDavid du Colombier.CW Cname 7257dd7cddfSDavid du Colombierfor the directory begin 7267dd7cddfSDavid du Colombier.CW /home ? 7277dd7cddfSDavid du ColombierIf it does, then the path that was evaluated to get us to the current 7287dd7cddfSDavid du Colombierdirectory must have gone through this mount point, and we should 7297dd7cddfSDavid du Colombierback up through it to evaluate 7307dd7cddfSDavid du Colombier.CW .. ; 7317dd7cddfSDavid du Colombierif not, then this mount table entry is irrelevant. 7327dd7cddfSDavid du Colombier.LP 7337dd7cddfSDavid du ColombierMore precisely, 7347dd7cddfSDavid du Colombierboth 7357dd7cddfSDavid du Colombier.I before 7367dd7cddfSDavid du Colombierand 7377dd7cddfSDavid du Colombier.I after 7387dd7cddfSDavid du Colombiereach 7397dd7cddfSDavid du Colombier.CW .. 7407dd7cddfSDavid du Colombierelement in the path name is evaluated, 7417dd7cddfSDavid du Colombierif the directory is a 7427dd7cddfSDavid du Colombier.CW tofile 7437dd7cddfSDavid du Colombierin the mount table, the corresponding 7447dd7cddfSDavid du Colombier.CW fromfile 7457dd7cddfSDavid du Colombieris taken instead, provided the 7467dd7cddfSDavid du Colombier.CW Cname 7477dd7cddfSDavid du Colombierof the corresponding 7487dd7cddfSDavid du Colombier.CW fromfile 7497dd7cddfSDavid du Colombieris the prefix of the 7507dd7cddfSDavid du Colombier.CW Cname 7517dd7cddfSDavid du Colombierof the original directory. 7527dd7cddfSDavid du ColombierSince we always know the full name of the directory 7537dd7cddfSDavid du Colombierwe are evaluating, we can always compare it against all the entries in the mount table that point 7547dd7cddfSDavid du Colombierto it, thereby resolving ambiguous situations 7557dd7cddfSDavid du Colombierand maintaining the 7567dd7cddfSDavid du Colombierlexical property of 7577dd7cddfSDavid du Colombier.CW .. . 7587dd7cddfSDavid du ColombierThis check also guarantees we don't follow a misleading mount point, such as the entry pointing to 7597dd7cddfSDavid du Colombier.CW /home 7607dd7cddfSDavid du Colombierwhen we are really in 7617dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob . 7627dd7cddfSDavid du ColombierKeeping the full names with the 7637dd7cddfSDavid du Colombier.CW Channels 7647dd7cddfSDavid du Colombiermakes it easy to use the mount table to decide how we got here and, therefore, 7657dd7cddfSDavid du Colombierhow to get back. 7667dd7cddfSDavid du Colombier.LP 7677dd7cddfSDavid du ColombierIn summary, the algorithm is as follows. 7687dd7cddfSDavid du ColombierUse the usual file system operations to walk to 7697dd7cddfSDavid du Colombier.CW .. ; 7707dd7cddfSDavid du Colombiercall the resulting directory 7717dd7cddfSDavid du Colombier.I d . 7727dd7cddfSDavid du ColombierLexically remove 7737dd7cddfSDavid du Colombierthe last element of the initial file name. 7747dd7cddfSDavid du ColombierExamine all entries in the mount table whose 7757dd7cddfSDavid du Colombier.CW tofile 7767dd7cddfSDavid du Colombieris 7777dd7cddfSDavid du Colombier.I d 7787dd7cddfSDavid du Colombierand whose 7797dd7cddfSDavid du Colombier.CW fromfile 7807dd7cddfSDavid du Colombierhas a 7817dd7cddfSDavid du Colombier.CW Cname 7827dd7cddfSDavid du Colombieridentical to the truncated name. 7837dd7cddfSDavid du ColombierIf one exists, that 7847dd7cddfSDavid du Colombier.CW fromfile 7857dd7cddfSDavid du Colombieris the correct result; by construction, it also has the right 7867dd7cddfSDavid du Colombier.CW Cname . 7877dd7cddfSDavid du ColombierIn our example, evaluating 7887dd7cddfSDavid du Colombier.CW .. 7897dd7cddfSDavid du Colombierin 7907dd7cddfSDavid du Colombier.CW /home/rob 7917dd7cddfSDavid du Colombier(really 7927dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob ) 7937dd7cddfSDavid du Colombierwill set 7947dd7cddfSDavid du Colombier.I d 7957dd7cddfSDavid du Colombierto 7967dd7cddfSDavid du Colombier.CW /n/bopp/v7 ; 7977dd7cddfSDavid du Colombierthat is a 7987dd7cddfSDavid du Colombier.CW tofile 7997dd7cddfSDavid du Colombierwhose 8007dd7cddfSDavid du Colombier.CW fromfile 8017dd7cddfSDavid du Colombieris 8027dd7cddfSDavid du Colombier.CW /home . 8037dd7cddfSDavid du ColombierRemoving the 8047dd7cddfSDavid du Colombier.CW /rob 8057dd7cddfSDavid du Colombierfrom the original 8067dd7cddfSDavid du Colombier.CW Cname , 8077dd7cddfSDavid du Colombierwe find the name 8087dd7cddfSDavid du Colombier.CW /home , 8097dd7cddfSDavid du Colombierwhich matches that of the 8107dd7cddfSDavid du Colombier.CW fromfile , 8117dd7cddfSDavid du Colombierso the result is the 8127dd7cddfSDavid du Colombier.CW fromfile , 8137dd7cddfSDavid du Colombier.CW /home . 8147dd7cddfSDavid du Colombier.LP 8157dd7cddfSDavid du ColombierSince this implementation uses only local operations to maintain its names, 8167dd7cddfSDavid du Colombierit is possible to confuse it by external changes to the file system. 8177dd7cddfSDavid du ColombierDeleting or renaming directories and files that are part of a 8187dd7cddfSDavid du Colombier.CW Cname , 8197dd7cddfSDavid du Colombieror modifying the mount table, can introduce errors. 8207dd7cddfSDavid du ColombierWith more implementation work, such mistakes could probably be caught, 8217dd7cddfSDavid du Colombierbut in a networked environment, with machines sharing a remote file server, renamings 8227dd7cddfSDavid du Colombierand deletions made by one machine may go unnoticed by others. 8237dd7cddfSDavid du ColombierThese problems, however, are minor, uncommon and, most important, easy to understand. 8247dd7cddfSDavid du ColombierThe method maintains the lexical property of file names unless an external 8257dd7cddfSDavid du Colombieragent changes the name surreptitiously; 8267dd7cddfSDavid du Colombierwithin a stable file system, it is always maintained and 8277dd7cddfSDavid du Colombier.CW pwd 8287dd7cddfSDavid du Colombieris always right. 8297dd7cddfSDavid du Colombier.LP 8307dd7cddfSDavid du ColombierTo recapitulate, maintaining the 8317dd7cddfSDavid du Colombier.CW Channel 's 8327dd7cddfSDavid du Colombierabsolute file names lexically and using the names to disambiguate the 8337dd7cddfSDavid du Colombiermount table entries when evaluating 8347dd7cddfSDavid du Colombier.CW .. 8357dd7cddfSDavid du Colombierat a mount point 8367dd7cddfSDavid du Colombiercombine to maintain the lexical definition of 8377dd7cddfSDavid du Colombier.CW .. 8387dd7cddfSDavid du Colombierefficiently. 8397dd7cddfSDavid du Colombier.SH 8407dd7cddfSDavid du ColombierCleaning names 8417dd7cddfSDavid du Colombier.LP 8427dd7cddfSDavid du ColombierThe lexical processing can generate names that are messy or redundant, 8437dd7cddfSDavid du Colombierones with extra slashes or embedded 8447dd7cddfSDavid du Colombier.CW ../ 8457dd7cddfSDavid du Colombieror 8467dd7cddfSDavid du Colombier.CW ./ 8477dd7cddfSDavid du Colombierelements and other extraneous artifacts. 8487dd7cddfSDavid du ColombierAs part of the kernel's implementation, we wrote a procedure, 8497dd7cddfSDavid du Colombier.CW cleanname , 8507dd7cddfSDavid du Colombierthat rewrites a name in place to canonicalize its appearance. 8517dd7cddfSDavid du ColombierThe procedure is useful enough that it is now part of the Plan 9 C 8527dd7cddfSDavid du Colombierlibrary and is employed by many programs to make sure they always 8537dd7cddfSDavid du Colombierpresent clean file names. 8547dd7cddfSDavid du Colombier.LP 8557dd7cddfSDavid du Colombier.CW Cleanname 8567dd7cddfSDavid du Colombieris analogous to the URL-cleaning rules defined in RFC 1808 [Field95], although 8577dd7cddfSDavid du Colombierthe rules are slightly different. 8587dd7cddfSDavid du Colombier.CW Cleanname 8597dd7cddfSDavid du Colombieriteratively does the following until no further processing can be done: 8607dd7cddfSDavid du Colombier.IP 8617dd7cddfSDavid du Colombier1. Reduce multiple slashes to a single slash. 8627dd7cddfSDavid du Colombier.IP 8637dd7cddfSDavid du Colombier2. Eliminate 8647dd7cddfSDavid du Colombier.CW . 8657dd7cddfSDavid du Colombierpath name elements 8667dd7cddfSDavid du Colombier(the current directory). 8677dd7cddfSDavid du Colombier.IP 8687dd7cddfSDavid du Colombier3. Eliminate 8697dd7cddfSDavid du Colombier.CW .. 8707dd7cddfSDavid du Colombierpath name elements (the parent directory) and the 8717dd7cddfSDavid du Colombier.CW . "" non- 8727dd7cddfSDavid du Colombier.CW .., "" non- 8737dd7cddfSDavid du Colombierelement that precedes them. 8747dd7cddfSDavid du Colombier.IP 8757dd7cddfSDavid du Colombier4. Eliminate 8767dd7cddfSDavid du Colombier.CW .. 8777dd7cddfSDavid du Colombierelements that begin a rooted path, that is, replace 8787dd7cddfSDavid du Colombier.CW /.. 8797dd7cddfSDavid du Colombierby 8807dd7cddfSDavid du Colombier.CW / 8817dd7cddfSDavid du Colombierat the beginning of a path. 8827dd7cddfSDavid du Colombier.IP 8837dd7cddfSDavid du Colombier5. Leave intact 8847dd7cddfSDavid du Colombier.CW .. 8857dd7cddfSDavid du Colombierelements that begin a non-rooted path. 8867dd7cddfSDavid du Colombier.LP 8877dd7cddfSDavid du ColombierIf the result of this process is a null string, 8887dd7cddfSDavid du Colombier.CW cleanname 8897dd7cddfSDavid du Colombierreturns the string 8907dd7cddfSDavid du Colombier.CW \&"." , 8917dd7cddfSDavid du Colombierrepresenting the current directory. 8927dd7cddfSDavid du Colombier.SH 8937dd7cddfSDavid du ColombierThe fd2path system call 8947dd7cddfSDavid du Colombier.LP 8957dd7cddfSDavid du ColombierPlan 9 has a new system call, 8967dd7cddfSDavid du Colombier.CW fd2path , 8977dd7cddfSDavid du Colombierto enable programs to extract the 8987dd7cddfSDavid du Colombier.CW Cname 8997dd7cddfSDavid du Colombierassociated with an open file descriptor. 9007dd7cddfSDavid du ColombierIt takes three arguments: a file descriptor, a buffer, and the size of the buffer: 9017dd7cddfSDavid du Colombier.P1 9027dd7cddfSDavid du Colombierint fd2path(int fd, char *buf, int nbuf) 9037dd7cddfSDavid du Colombier.P2 9047dd7cddfSDavid du ColombierIt returns an error if the file descriptor is invalid; otherwise it fills the buffer with the name 9057dd7cddfSDavid du Colombierassociated with 9067dd7cddfSDavid du Colombier.CW fd . 9077dd7cddfSDavid du Colombier(If the name is too long, it is truncated; perhaps this condition should also draw an error.) 9087dd7cddfSDavid du ColombierThe 9097dd7cddfSDavid du Colombier.CW fd2path 9107dd7cddfSDavid du Colombiersystem call is very cheap, since all it does is copy the 9117dd7cddfSDavid du Colombier.CW Cname 9127dd7cddfSDavid du Colombierstring to user space. 9137dd7cddfSDavid du Colombier.LP 9147dd7cddfSDavid du ColombierThe Plan 9 implementation of 9157dd7cddfSDavid du Colombier.CW getwd 9167dd7cddfSDavid du Colombieruses 9177dd7cddfSDavid du Colombier.CW fd2path 9187dd7cddfSDavid du Colombierrather than the tricky algorithm necessary in Unix: 9197dd7cddfSDavid du Colombier.P1 9207dd7cddfSDavid du Colombierchar* 9217dd7cddfSDavid du Colombiergetwd(char *buf, int nbuf) 9227dd7cddfSDavid du Colombier{ 9237dd7cddfSDavid du Colombier int n, fd; 9247dd7cddfSDavid du Colombier 9257dd7cddfSDavid du Colombier fd = open(".", OREAD); 9267dd7cddfSDavid du Colombier if(fd < 0) 9277dd7cddfSDavid du Colombier return NULL; 9287dd7cddfSDavid du Colombier n = fd2path(fd, buf, nbuf); 9297dd7cddfSDavid du Colombier close(fd); 9307dd7cddfSDavid du Colombier if(n < 0) 9317dd7cddfSDavid du Colombier return NULL; 9327dd7cddfSDavid du Colombier return buf; 9337dd7cddfSDavid du Colombier} 9347dd7cddfSDavid du Colombier.P2 9357dd7cddfSDavid du Colombier(The Unix specification of 9367dd7cddfSDavid du Colombier.CW getwd 9377dd7cddfSDavid du Colombierdoes not include a count argument.) 9387dd7cddfSDavid du ColombierThis version of 9397dd7cddfSDavid du Colombier.CW getwd 9407dd7cddfSDavid du Colombieris not only straightforward, it is very efficient, reducing the performance 9417dd7cddfSDavid du Colombieradvantage of a built-in 9427dd7cddfSDavid du Colombier.CW pwd 9437dd7cddfSDavid du Colombiercommand while guaranteeing that all commands, not just 9447dd7cddfSDavid du Colombier.CW pwd , 9457dd7cddfSDavid du Colombiersee sensible directory names. 9467dd7cddfSDavid du Colombier.LP 9477dd7cddfSDavid du ColombierHere is a routine that prints the file name associated 9487dd7cddfSDavid du Colombierwith each of its open file descriptors; it is useful for tracking down file descriptors 9497dd7cddfSDavid du Colombierleft open by network listeners, text editors that spawn commands, and the like: 9507dd7cddfSDavid du Colombier.P1 9517dd7cddfSDavid du Colombiervoid 9527dd7cddfSDavid du Colombieropenfiles(void) 9537dd7cddfSDavid du Colombier{ 9547dd7cddfSDavid du Colombier int i; 9557dd7cddfSDavid du Colombier char buf[256]; 9567dd7cddfSDavid du Colombier 9577dd7cddfSDavid du Colombier for(i=0; i<NFD; i++) 9587dd7cddfSDavid du Colombier if(fd2path(i, buf, sizeof buf) >= 0) 9597dd7cddfSDavid du Colombier print("%d: %s\en", i, buf); 9607dd7cddfSDavid du Colombier} 9617dd7cddfSDavid du Colombier.P2 9627dd7cddfSDavid du Colombier.SH 9637dd7cddfSDavid du ColombierUses of good names 9647dd7cddfSDavid du Colombier.LP 9657dd7cddfSDavid du ColombierAlthough 9667dd7cddfSDavid du Colombier.CW pwd 9677dd7cddfSDavid du Colombierwas the motivation for getting names right, good file names are useful in many contexts 9687dd7cddfSDavid du Colombierand have become a key part of the Plan 9 programming environment. 9697dd7cddfSDavid du ColombierThe compilers record in the symbol table the full name of the source file, which makes 9707dd7cddfSDavid du Colombierit easy to track down the source of buggy, old software and also permits the 9717dd7cddfSDavid du Colombierimplementation of a program, 9727dd7cddfSDavid du Colombier.CW src , 9737dd7cddfSDavid du Colombierto automate tracking it down. 9747dd7cddfSDavid du ColombierGiven the name of a program, 9757dd7cddfSDavid du Colombier.CW src 9767dd7cddfSDavid du Colombierreads its symbol table, extracts the file information, 9777dd7cddfSDavid du Colombierand triggers the editor to open a window on the program's 9787dd7cddfSDavid du Colombiersource for its 9797dd7cddfSDavid du Colombier.CW main 9807dd7cddfSDavid du Colombierroutine. 9817dd7cddfSDavid du ColombierNo guesswork, no heuristics. 9827dd7cddfSDavid du Colombier.LP 9837dd7cddfSDavid du ColombierThe 9847dd7cddfSDavid du Colombier.CW openfiles 9857dd7cddfSDavid du Colombierroutine was the inspiration for a new file in the 9867dd7cddfSDavid du Colombier.CW /proc 9877dd7cddfSDavid du Colombierfile system [Kill84]. 9887dd7cddfSDavid du ColombierFor process 9897dd7cddfSDavid du Colombier.I n , 9907dd7cddfSDavid du Colombierthe file 9917dd7cddfSDavid du Colombier.CW /proc/\f2n\fP/fd 9927dd7cddfSDavid du Colombieris a list of all its open files, including its working directory, 9937dd7cddfSDavid du Colombierwith associated information including its open status, 9947dd7cddfSDavid du ColombierI/O offset, unique id (analogous to i-number) 9957dd7cddfSDavid du Colombierand file name. 9967dd7cddfSDavid du ColombierHere is the contents of the 9977dd7cddfSDavid du Colombier.CW fd 9987dd7cddfSDavid du Colombierfile for a process in the window system on the machine being used to write this paper: 9997dd7cddfSDavid du Colombier.P1 10007dd7cddfSDavid du Colombier% cat /proc/125099/fd 10017dd7cddfSDavid du Colombier/usr/rob 10027dd7cddfSDavid du Colombier 0 r M 5141 00000001.00000000 0 /mnt/term/dev/cons 10037dd7cddfSDavid du Colombier 1 w M 5141 00000001.00000000 51 /mnt/term/dev/cons 10047dd7cddfSDavid du Colombier 2 w M 5141 00000001.00000000 51 /mnt/term/dev/cons 10057dd7cddfSDavid du Colombier 3 r M 5141 0000000b.00000000 1166 /dev/snarf 10067dd7cddfSDavid du Colombier 4 rw M 5141 0ffffffc.00000000 288 /dev/draw/new 10077dd7cddfSDavid du Colombier 5 rw M 5141 00000036.00000000 4266337 /dev/draw/3/data 10087dd7cddfSDavid du Colombier 6 r M 5141 00000037.00000000 0 /dev/draw/3/refresh 10097dd7cddfSDavid du Colombier 7 r c 0 00000004.00000000 6199848 /dev/bintime 10107dd7cddfSDavid du Colombier% 10117dd7cddfSDavid du Colombier.P2 10127dd7cddfSDavid du Colombier(The Linux implementation of 10137dd7cddfSDavid du Colombier.CW /proc 10147dd7cddfSDavid du Colombierprovides a related service by giving a directory in which each file-descriptor-numbered file is 10157dd7cddfSDavid du Colombiera symbolic link to the file itself.) 10167dd7cddfSDavid du ColombierWhen debugging errant systems software, such information can be valuable. 10177dd7cddfSDavid du Colombier.LP 10187dd7cddfSDavid du ColombierAnother motivation for getting names right was the need to extract from the system 10197dd7cddfSDavid du Colombieran accurate description of the mount table, so that a process's name space could be 10207dd7cddfSDavid du Colombierrecreated on another machine, in order to move (or simulate) a computing environment 10217dd7cddfSDavid du Colombieracross the network. 10227dd7cddfSDavid du ColombierOne program that does this is Plan 9's 10237dd7cddfSDavid du Colombier.CW cpu 10247dd7cddfSDavid du Colombiercommand, which recreates the local name space on a remote machine, typically a large 10257dd7cddfSDavid du Colombierfast multiprocessor. 10267dd7cddfSDavid du ColombierWithout accurate names, it was impossible to do the job right; now 10277dd7cddfSDavid du Colombier.CW /proc 10287dd7cddfSDavid du Colombierprovides a description of the name space of each process, 10297dd7cddfSDavid du Colombier.CW /proc/\f2n\fP/ns : 10307dd7cddfSDavid du Colombier.P1 10317dd7cddfSDavid du Colombier% cat /proc/125099/ns 10327dd7cddfSDavid du Colombierbind / / 10337dd7cddfSDavid du Colombiermount -aC #s/boot / 10347dd7cddfSDavid du Colombierbind #c /dev 10357dd7cddfSDavid du Colombierbind #d /fd 10367dd7cddfSDavid du Colombierbind -c #e /env 10377dd7cddfSDavid du Colombierbind #p /proc 10387dd7cddfSDavid du Colombierbind -c #s /srv 10397dd7cddfSDavid du Colombierbind /386/bin /bin 10407dd7cddfSDavid du Colombierbind -a /rc/bin /bin 10417dd7cddfSDavid du Colombierbind /net /net 10427dd7cddfSDavid du Colombierbind -a #l /net 10437dd7cddfSDavid du Colombiermount -a #s/cs /net 10447dd7cddfSDavid du Colombiermount -a #s/dns /net 10457dd7cddfSDavid du Colombierbind -a #D /net 10467dd7cddfSDavid du Colombiermount -c #s/boot /n/emelie 10477dd7cddfSDavid du Colombierbind -c /n/emelie/mail /mail 10487dd7cddfSDavid du Colombiermount -c /net/il/134/data /mnt/term 10497dd7cddfSDavid du Colombierbind -a /usr/rob/bin/rc /bin 10507dd7cddfSDavid du Colombierbind -a /usr/rob/bin/386 /bin 10517dd7cddfSDavid du Colombiermount #s/boot /n/emelieother other 10527dd7cddfSDavid du Colombierbind -c /n/emelieother/rob /tmp 10537dd7cddfSDavid du Colombiermount #s/boot /n/dump dump 10547dd7cddfSDavid du Colombierbind /mnt/term/dev/cons /dev/cons 10557dd7cddfSDavid du Colombier\&... 10567dd7cddfSDavid du Colombiercd /usr/rob 10577dd7cddfSDavid du Colombier% 10587dd7cddfSDavid du Colombier.P2 10597dd7cddfSDavid du Colombier(The 10607dd7cddfSDavid du Colombier.CW # 10617dd7cddfSDavid du Colombiernotation identifies raw device drivers so they may be attached to the name space.) 10627dd7cddfSDavid du ColombierThe last line of the file gives the working directory of the process. 10637dd7cddfSDavid du ColombierThe format of this file is that used by a library routine, 10647dd7cddfSDavid du Colombier.CW newns , 10657dd7cddfSDavid du Colombierwhich reads a textual description like this and reconstructs a name space. 10667dd7cddfSDavid du ColombierExcept for the need to quote 10677dd7cddfSDavid du Colombier.CW # 10687dd7cddfSDavid du Colombiercharacters, the output is also a shell script that invokes the user-level commands 10697dd7cddfSDavid du Colombier.CW bind 10707dd7cddfSDavid du Colombierand 10717dd7cddfSDavid du Colombier.CW mount , 10727dd7cddfSDavid du Colombierwhich are just interfaces to the underlying system calls. 10737dd7cddfSDavid du ColombierHowever, 10747dd7cddfSDavid du Colombierfiles like 10757dd7cddfSDavid du Colombier.CW /net/il/134/data 10767dd7cddfSDavid du Colombierrepresent network connections; to find out where they point, so that the corresponding 10777dd7cddfSDavid du Colombiercalls can be reestablished for another process, 10787dd7cddfSDavid du Colombierthey must be examined in more detail using the network device files [PrWi93]. Another program, 10797dd7cddfSDavid du Colombier.CW ns , 10807dd7cddfSDavid du Colombierdoes this; it reads the 10817dd7cddfSDavid du Colombier.CW /proc/\f2n\fP/ns 10827dd7cddfSDavid du Colombierfile, decodes the information, and interprets it, translating the network 10837dd7cddfSDavid du Colombieraddresses and quoting the names when required: 10847dd7cddfSDavid du Colombier.P1 10857dd7cddfSDavid du Colombier\&... 10867dd7cddfSDavid du Colombiermount -a '#s/dns' /net 10877dd7cddfSDavid du Colombier\&... 10887dd7cddfSDavid du Colombiermount -c il!135.104.3.100!12884 /mnt/term 10897dd7cddfSDavid du Colombier\&... 10907dd7cddfSDavid du Colombier.P2 10917dd7cddfSDavid du ColombierThese tools make it possible to capture an accurate description of a process's 10927dd7cddfSDavid du Colombiername space and recreate it elsewhere. 10937dd7cddfSDavid du ColombierAnd like the open file descriptor table, 10947dd7cddfSDavid du Colombierthey are a boon to debugging; it is always helpful to know 10957dd7cddfSDavid du Colombierexactly what resources a program is using. 10967dd7cddfSDavid du Colombier.SH 10977dd7cddfSDavid du ColombierAdapting to Unix 10987dd7cddfSDavid du Colombier.LP 10997dd7cddfSDavid du ColombierThis work was done for the Plan 9 operating system, which has the advantage that 11007dd7cddfSDavid du Colombierthe non-hierarchical aspects of the name space are all known to the kernel. 11017dd7cddfSDavid du ColombierIt should be possible, though, to adapt it to a Unix system. 11027dd7cddfSDavid du ColombierThe problem is that Unix has nothing corresponding precisely to a 11037dd7cddfSDavid du Colombier.CW Channel , 11047dd7cddfSDavid du Colombierwhich in Plan 9 represents the unique result of evaluating a name. 11057dd7cddfSDavid du ColombierThe 11067dd7cddfSDavid du Colombier.CW vnode 11077dd7cddfSDavid du Colombierstructure is a shared structure that may represent a file 11087dd7cddfSDavid du Colombierknown by several names, while the 11097dd7cddfSDavid du Colombier.CW file 11107dd7cddfSDavid du Colombierstructure refers only to open files, but for example the current working 11117dd7cddfSDavid du Colombierdirectory of a process is not open. 11127dd7cddfSDavid du ColombierPossibilities to address this discrepancy include 11137dd7cddfSDavid du Colombierintroducing a 11147dd7cddfSDavid du Colombier.CW Channel -like 11157dd7cddfSDavid du Colombierstructure that connects a name and a 11167dd7cddfSDavid du Colombier.CW vnode , 11177dd7cddfSDavid du Colombieror maintaining a separate per-process table that maps names to 11187dd7cddfSDavid du Colombier.CW vnodes , 11197dd7cddfSDavid du Colombierdisambiguating using the techniques described here. 11207dd7cddfSDavid du ColombierIf it could be done 11217dd7cddfSDavid du Colombierthe result would be an implementation of 11227dd7cddfSDavid du Colombier.CW .. 11237dd7cddfSDavid du Colombierthat reduces the need for a built-in 11247dd7cddfSDavid du Colombier.CW pwd 11257dd7cddfSDavid du Colombierin the shell and offers a consistent, sensible interpretation of the `parent directory'. 11267dd7cddfSDavid du Colombier.LP 11277dd7cddfSDavid du ColombierWe have not done this adaptation, but we recommend that the Unix community try it. 11287dd7cddfSDavid du Colombier.SH 11297dd7cddfSDavid du ColombierConclusions 11307dd7cddfSDavid du Colombier.LP 11317dd7cddfSDavid du ColombierIt should be easy to discover a well-defined, absolute path name for every open file and 11327dd7cddfSDavid du Colombierdirectory in the system, even in the face of symbolic links and other non-hierarchical 11337dd7cddfSDavid du Colombierelements of the file name space. 11347dd7cddfSDavid du ColombierIn earlier versions of Plan 9, and all current versions of Unix, 11357dd7cddfSDavid du Colombiernames can instead be inconsistent and confusing. 11367dd7cddfSDavid du Colombier.LP 11377dd7cddfSDavid du ColombierThe Plan 9 operating system now maintains an accurate name for each file, 11387dd7cddfSDavid du Colombierusing inexpensive lexical operations coupled with local file system actions. 11397dd7cddfSDavid du ColombierAmbiguities are resolved by examining the names themselves; 11407dd7cddfSDavid du Colombiersince they reflect the path that was used to reach the file, they also reflect the path back, 11417dd7cddfSDavid du Colombierpermitting a dependable answer to be recovered even when stepping backwards through 11427dd7cddfSDavid du Colombiera multiply-named directory. 11437dd7cddfSDavid du Colombier.LP 11447dd7cddfSDavid du ColombierNames make sense again: they are sensible and consistent. 11457dd7cddfSDavid du ColombierNow that dependable names are available, system services can depend on them, 11467dd7cddfSDavid du Colombierand recent work in Plan 9 is doing just that. 11477dd7cddfSDavid du ColombierWe\(emthe community of Unix and Unix-like systems\(emshould have done this work a long time ago. 11487dd7cddfSDavid du Colombier.SH 11497dd7cddfSDavid du ColombierAcknowledgements 11507dd7cddfSDavid du Colombier.LP 11517dd7cddfSDavid du ColombierPhil Winterbottom devised the 11527dd7cddfSDavid du Colombier.CW ns 11537dd7cddfSDavid du Colombiercommand and the 11547dd7cddfSDavid du Colombier.CW fd 11557dd7cddfSDavid du Colombierand 11567dd7cddfSDavid du Colombier.CW ns 11577dd7cddfSDavid du Colombierfiles in 11587dd7cddfSDavid du Colombier.CW /proc , 11597dd7cddfSDavid du Colombierbased on an earlier implementation of path name management that 11607dd7cddfSDavid du Colombierthe work in this paper replaces. 11617dd7cddfSDavid du ColombierRuss Cox wrote the final version of 11627dd7cddfSDavid du Colombier.CW cleanname 11637dd7cddfSDavid du Colombierand helped debug the code for reversing the mount table. 11647dd7cddfSDavid du ColombierKen Thompson, Dave Presotto, and Jim McKie offered encouragement and consultation. 11657dd7cddfSDavid du Colombier.SH 11667dd7cddfSDavid du ColombierReferences 11677dd7cddfSDavid du Colombier.LP 11687dd7cddfSDavid du Colombier[Field95] 11697dd7cddfSDavid du ColombierR. Fielding, 11707dd7cddfSDavid du Colombier``Relative Uniform Resource Locators'', 11717dd7cddfSDavid du Colombier.I "Network Working Group Request for Comments: 1808" , 11727dd7cddfSDavid du ColombierJune, 1995. 11737dd7cddfSDavid du Colombier.LP 11747dd7cddfSDavid du Colombier[Kill84] 11757dd7cddfSDavid du ColombierT. J. Killian, 11767dd7cddfSDavid du Colombier``Processes as Files'', 11777dd7cddfSDavid du Colombier.I "Proceedings of the Summer 1984 USENIX Conference" , 11787dd7cddfSDavid du ColombierSalt Lake City, 1984, pp. 203-207. 11797dd7cddfSDavid du Colombier.LP 11807dd7cddfSDavid du Colombier[Korn94] 11817dd7cddfSDavid du ColombierDavid G. Korn, 11827dd7cddfSDavid du Colombier``ksh: An Extensible High Level Language'', 11837dd7cddfSDavid du Colombier.I "Proceedings of the USENIX Very High Level Languages Symposium" , 11847dd7cddfSDavid du ColombierSanta Fe, 1994, pp. 129-146. 11857dd7cddfSDavid du Colombier.LP 11867dd7cddfSDavid du Colombier[Korn00] 11877dd7cddfSDavid du ColombierDavid G. Korn, 11887dd7cddfSDavid du Colombierpersonal communication. 11897dd7cddfSDavid du Colombier.LP 11907dd7cddfSDavid du Colombier[PeMc95] 11917dd7cddfSDavid du ColombierJan-Simon Pendry and Marshall Kirk McKusick, 11927dd7cddfSDavid du Colombier``Union Mounts in 4.4BSD-Lite'', 11937dd7cddfSDavid du Colombier.I "Proceedings of the 1995 USENIX Conference" , 11947dd7cddfSDavid du ColombierNew Orleans, 1995. 11957dd7cddfSDavid du Colombier.LP 11967dd7cddfSDavid du Colombier[Pike91] 11977dd7cddfSDavid du ColombierRob Pike, 11987dd7cddfSDavid du Colombier``8½, the Plan 9 Window System'', 11997dd7cddfSDavid du Colombier.I "Proceedings of the Summer 1991 USENIX Conference" , 12007dd7cddfSDavid du ColombierNashville, 1991, pp. 257-265. 12017dd7cddfSDavid du Colombier.LP 12027dd7cddfSDavid du Colombier[Pike93] 12037dd7cddfSDavid du ColombierRob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom, 12047dd7cddfSDavid du Colombier``The Use of Name Spaces in Plan 9'', 12057dd7cddfSDavid du Colombier.I "Operating Systems Review" , 12067dd7cddfSDavid du Colombier.B 27 , 12077dd7cddfSDavid du Colombier2, April 1993, pp. 72-76. 12087dd7cddfSDavid du Colombier.LP 12097dd7cddfSDavid du Colombier[PrWi93] 12107dd7cddfSDavid du ColombierDave Presotto and Phil Winterbottom, 12117dd7cddfSDavid du Colombier``The Organization of Networks in Plan 9'', 12127dd7cddfSDavid du Colombier.I "Proceedings of the Winter 1993 USENIX Conference" , 12137dd7cddfSDavid du ColombierSan Diego, 1993, pp. 43-50. 1214