1*426d2b71SDavid du Colombier.HTML "Changes to the Programming Environment in the Fourth Release of Plan 9 29a747e4fSDavid du Colombier.FP lucidasans 39a747e4fSDavid du Colombier.TL 49a747e4fSDavid du ColombierChanges to the Programming Environment 59a747e4fSDavid du Colombier.br 69a747e4fSDavid du Colombierin the 79a747e4fSDavid du Colombier.br 89a747e4fSDavid du ColombierFourth Release of Plan 9 99a747e4fSDavid du Colombier.AU 109a747e4fSDavid du ColombierRob Pike 119a747e4fSDavid du Colombier.sp 129a747e4fSDavid du Colombierrob@plan9.bell-labs.com 139a747e4fSDavid du Colombier.SH 149a747e4fSDavid du ColombierIntroduction 159a747e4fSDavid du Colombier.PP 169a747e4fSDavid du ColombierThe fourth release of Plan 9 includes changes at many levels of the system, 179a747e4fSDavid du Colombierwith repercussions in the libraries and program interfaces. 189a747e4fSDavid du ColombierThis document summarizes the changes and describes how 199a747e4fSDavid du Colombierexisting programs must be modified to run in the new release. 209a747e4fSDavid du ColombierIt is not exhaustive, of course; for further detail about any of the 219a747e4fSDavid du Colombiertopics refer to the manual pages, as always. 229a747e4fSDavid du Colombier.PP 239a747e4fSDavid du ColombierProgrammers new to Plan 9 may find valuable tidbits here, but the 249a747e4fSDavid du Colombierreal audience for this paper is those with a need to update applications 259a747e4fSDavid du Colombierand servers written in C for earlier releases of the Plan 9 operating system. 269a747e4fSDavid du Colombier.SH 279a747e4fSDavid du Colombier9P, NAMELEN, and strings 289a747e4fSDavid du Colombier.PP 299a747e4fSDavid du ColombierThe underlying file service protocol for Plan 9, 9P, retains its basic form 309a747e4fSDavid du Colombierbut has had a number of adjustments to deal with longer file names and error strings, 319a747e4fSDavid du Colombiernew authentication mechanisms, and to make it more efficient at 329a747e4fSDavid du Colombierevaluating file names. 339a747e4fSDavid du ColombierThe change to file names affects a number of system interfaces; 349a747e4fSDavid du Colombierbecause file name elements are no longer of fixed size, they can 359a747e4fSDavid du Colombierno longer be stored as arrays. 369a747e4fSDavid du Colombier.PP 379a747e4fSDavid du Colombier9P used to be a fixed-format protocol with 389a747e4fSDavid du Colombier.CW NAMELEN -sized 399a747e4fSDavid du Colombierbyte arrays representing file name elements. 409a747e4fSDavid du ColombierNow, it is a variable-format protocol, as described in 419a747e4fSDavid du Colombier.I intro (5), 429a747e4fSDavid du Colombierin which strings are represented by a count followed by that many bytes. 439a747e4fSDavid du ColombierThus, the string 449a747e4fSDavid du Colombier.CW ken 459a747e4fSDavid du Colombierwould previously have occupied 28 469a747e4fSDavid du Colombier.CW NAMELEN ) ( 479a747e4fSDavid du Colombierbytes in the message; now it occupies 5: a two-byte count followed by the three bytes of 489a747e4fSDavid du Colombier.CW ken 499a747e4fSDavid du Colombierand no terminal zero. 509a747e4fSDavid du Colombier(And of course, a name could now be much longer.) 519a747e4fSDavid du ColombierA similar format change has been made to 529a747e4fSDavid du Colombier.CW stat 539a747e4fSDavid du Colombierbuffers: they are no longer 549a747e4fSDavid du Colombier.CW DIRLEN 559a747e4fSDavid du Colombierbytes long but instead have variable size prefixed by a two-byte count. 569a747e4fSDavid du ColombierAnd in fact the entire 9P message syntax has changed: every message 579a747e4fSDavid du Colombiernow begins with a message length field that makes it trivial to break the 589a747e4fSDavid du Colombierstring into messages without parsing them, so 599a747e4fSDavid du Colombier.CW aux/fcall 609a747e4fSDavid du Colombieris gone. 619a747e4fSDavid du ColombierA new library entry point, 629a747e4fSDavid du Colombier.CW read9pmsg , 639a747e4fSDavid du Colombiermakes it easy for user-level servers to break the client data stream into 9P messages. 649a747e4fSDavid du ColombierAll servers should switch from using 659a747e4fSDavid du Colombier.CW read 669a747e4fSDavid du Colombier(or the now gone 679a747e4fSDavid du Colombier.CW getS) 689a747e4fSDavid du Colombierto using 699a747e4fSDavid du Colombier.CW read9pmsg . 709a747e4fSDavid du Colombier.PP 719a747e4fSDavid du ColombierThis change to 9P affects the way strings are handled by the kernel and throughout 729a747e4fSDavid du Colombierthe system. 739a747e4fSDavid du ColombierThe consequences are primarily that fixed-size arrays have been replaced 749a747e4fSDavid du Colombierby pointers and counts in a variety of system interfaces. 759a747e4fSDavid du ColombierMost programs will need at least some adjustment to the new style. 769a747e4fSDavid du ColombierIn summary: 779a747e4fSDavid du Colombier.CW NAMELEN 789a747e4fSDavid du Colombieris gone, except as a vestige in the authentication libraries, where it has been 799a747e4fSDavid du Colombierrechristened 809a747e4fSDavid du Colombier.CW ANAMELEN . 819a747e4fSDavid du Colombier.CW DIRLEN 829a747e4fSDavid du Colombierand 839a747e4fSDavid du Colombier.CW ERRLEN 849a747e4fSDavid du Colombierare also gone. 859a747e4fSDavid du ColombierAll programs that mention 869a747e4fSDavid du Colombierthese constants 879a747e4fSDavid du Colombierwill need to be fixed. 889a747e4fSDavid du Colombier.PP 899a747e4fSDavid du ColombierThe simplest place to see this change is in the 909a747e4fSDavid du Colombier.CW errstr 919a747e4fSDavid du Colombiersystem call, which no longer assumes a buffer of length 929a747e4fSDavid du Colombier.CW ERRLEN 939a747e4fSDavid du Colombierbut now requires a byte-count argument: 949a747e4fSDavid du Colombier.P1 959a747e4fSDavid du Colombierchar buf[...]; 969a747e4fSDavid du Colombier 979a747e4fSDavid du Colombiererrstr(buf, sizeof buf); 989a747e4fSDavid du Colombier.P2 999a747e4fSDavid du ColombierThe buffer can be any size you like. 1009a747e4fSDavid du ColombierFor convenience, the kernel stores error strings internally as 256-byte arrays, 1019a747e4fSDavid du Colombierso if you like \(em but it's not required \(em you can use the defined constant 1029a747e4fSDavid du Colombier.CW ERRMAX= 256 1039a747e4fSDavid du Colombieras a good buffer size. 1049a747e4fSDavid du ColombierUnlike the old 1059a747e4fSDavid du Colombier.CW ERRLEN 1069a747e4fSDavid du Colombier(which had value 64), 1079a747e4fSDavid du Colombier.CW ERRMAX 1089a747e4fSDavid du Colombieris advisory, not mandatory, and is not part of the 9P specification. 1099a747e4fSDavid du Colombier.PP 1109a747e4fSDavid du ColombierWith names, stat buffers, and directories, there isn't even an echo of a fixed-size array any more. 1119a747e4fSDavid du Colombier.SH 1129a747e4fSDavid du ColombierDirectories and wait messages 1139a747e4fSDavid du Colombier.PP 1149a747e4fSDavid du ColombierWith strings now variable-length, a number of system calls needed to change: 1159a747e4fSDavid du Colombier.CW errstr , 1169a747e4fSDavid du Colombier.CW stat , 1179a747e4fSDavid du Colombier.CW fstat , 1189a747e4fSDavid du Colombier.CW wstat , 1199a747e4fSDavid du Colombier.CW fwstat , 1209a747e4fSDavid du Colombierand 1219a747e4fSDavid du Colombier.CW wait 1229a747e4fSDavid du Colombierare all affected, as is 1239a747e4fSDavid du Colombier.CW read 1249a747e4fSDavid du Colombierwhen applied to directories. 1259a747e4fSDavid du Colombier.PP 1269a747e4fSDavid du ColombierAs far as directories are concerned, most programs don't use the system calls 1279a747e4fSDavid du Colombierdirectly anyway, since they operate on the machine-independent form, but 1289a747e4fSDavid du Colombierinstead call the machine-dependent 1299a747e4fSDavid du Colombier.CW Dir 1309a747e4fSDavid du Colombierroutines 1319a747e4fSDavid du Colombier.CW dirstat , 1329a747e4fSDavid du Colombier.CW dirread , 1339a747e4fSDavid du Colombieretc. 1349a747e4fSDavid du ColombierThese used to fill user-provided fixed-size buffers; now they return objects allocated 1359a747e4fSDavid du Colombierby 1369a747e4fSDavid du Colombier.CW malloc 1379a747e4fSDavid du Colombier(which must therefore be freed after use). 1389a747e4fSDavid du ColombierTo `stat' a file: 1399a747e4fSDavid du Colombier.P1 1409a747e4fSDavid du ColombierDir *d; 1419a747e4fSDavid du Colombier 1429a747e4fSDavid du Colombierd = dirstat(filename); 1439a747e4fSDavid du Colombierif(d == nil){ 1449a747e4fSDavid du Colombier fprint(2, "can't stat %s: %r\en", filename); 1459a747e4fSDavid du Colombier exits("stat"); 1469a747e4fSDavid du Colombier} 1479a747e4fSDavid du Colombieruse(d); 1489a747e4fSDavid du Colombierfree(d); 1499a747e4fSDavid du Colombier.P2 1509a747e4fSDavid du ColombierA common new bug is to forget to free a 1519a747e4fSDavid du Colombier.CW Dir 1529a747e4fSDavid du Colombierreturned by 1539a747e4fSDavid du Colombier.CW dirstat . 1549a747e4fSDavid du Colombier.PP 1559a747e4fSDavid du Colombier.CW Dirfstat 1569a747e4fSDavid du Colombierand 1579a747e4fSDavid du Colombier.CW Dirfwstat 1589a747e4fSDavid du Colombierwork pretty much as before, but changes to 9P make 1599a747e4fSDavid du Colombierit possible to exercise finer-grained control on what fields 1609a747e4fSDavid du Colombierof the 1619a747e4fSDavid du Colombier.CW Dir 1629a747e4fSDavid du Colombierare to be changed; see 1639a747e4fSDavid du Colombier.I stat (2) 1649a747e4fSDavid du Colombierand 1659a747e4fSDavid du Colombier.I stat (5) 1669a747e4fSDavid du Colombierfor details. 1679a747e4fSDavid du Colombier.PP 1689a747e4fSDavid du ColombierReading a directory works in a similar way to 1699a747e4fSDavid du Colombier.CW dirstat , 1709a747e4fSDavid du Colombierwith 1719a747e4fSDavid du Colombier.CW dirread 1729a747e4fSDavid du Colombierallocating and filling in an array of 1739a747e4fSDavid du Colombier.CW Dir 1749a747e4fSDavid du Colombierstructures. 1759a747e4fSDavid du ColombierThe return value is the number of elements of the array. 1769a747e4fSDavid du ColombierThe arguments to 1779a747e4fSDavid du Colombier.CW dirread 1789a747e4fSDavid du Colombiernow include a pointer to a 1799a747e4fSDavid du Colombier.CW Dir* 1809a747e4fSDavid du Colombierto be filled in with the address of the allocated array: 1819a747e4fSDavid du Colombier.P1 1829a747e4fSDavid du ColombierDir *d; 1839a747e4fSDavid du Colombierint i, n; 1849a747e4fSDavid du Colombier 1859a747e4fSDavid du Colombierwhile((n = dirread(fd, &d)) > 0){ 1869a747e4fSDavid du Colombier for(i=0; i<n; i++) 1879a747e4fSDavid du Colombier use(&d[i]); 1889a747e4fSDavid du Colombier free(d); 1899a747e4fSDavid du Colombier} 1909a747e4fSDavid du Colombier.P2 1919a747e4fSDavid du ColombierA new library function, 1929a747e4fSDavid du Colombier.CW dirreadall , 1939a747e4fSDavid du Colombierhas the same form as 1949a747e4fSDavid du Colombier.CW dirread 1959a747e4fSDavid du Colombierbut returns the entire directory in one call: 1969a747e4fSDavid du Colombier.P1 1979a747e4fSDavid du Colombiern = dirreadall(fd, &d) 1989a747e4fSDavid du Colombierfor(i=0; i<n; i++) 1999a747e4fSDavid du Colombier use(&d[i]); 2009a747e4fSDavid du Colombierfree(d); 2019a747e4fSDavid du Colombier.P2 2029a747e4fSDavid du ColombierIf your program insists on using the underlying 2039a747e4fSDavid du Colombier.CW stat 2049a747e4fSDavid du Colombiersystem call or its relatives, or wants to operate directly on the 2059a747e4fSDavid du Colombiermachine-independent format returned by 2069a747e4fSDavid du Colombier.CW stat 2079a747e4fSDavid du Colombieror 2089a747e4fSDavid du Colombier.CW read , 2099a747e4fSDavid du Colombierit will need to be modified. 2109a747e4fSDavid du ColombierSuch programs are rare enough that we'll not discuss them here beyond referring to 2119a747e4fSDavid du Colombierthe man page 2129a747e4fSDavid du Colombier.I stat (2) 2139a747e4fSDavid du Colombierfor details. 2149a747e4fSDavid du ColombierBe aware, though, that it used to be possible to regard the buffer returned by 2159a747e4fSDavid du Colombier.CW stat 2169a747e4fSDavid du Colombieras a byte array that began with the zero-terminated 2179a747e4fSDavid du Colombiername of the file; this is no longer true. 2189a747e4fSDavid du ColombierWith very rare exceptions, programs that call 2199a747e4fSDavid du Colombier.CW stat 2209a747e4fSDavid du Colombierwould be better recast to use the 2219a747e4fSDavid du Colombier.CW dir 2229a747e4fSDavid du Colombierroutines or, if their goal is just to test the existence of a file, 2239a747e4fSDavid du Colombier.CW access . 2249a747e4fSDavid du Colombier.PP 2259a747e4fSDavid du ColombierSimilar changes have affected the 2269a747e4fSDavid du Colombier.CW wait 2279a747e4fSDavid du Colombiersystem call. In fact, 2289a747e4fSDavid du Colombier.CW wait 2299a747e4fSDavid du Colombieris no longer a system call but a library routine that calls the new 2309a747e4fSDavid du Colombier.CW await 2319a747e4fSDavid du Colombiersystem call and returns a newly allocated machine-dependent 2329a747e4fSDavid du Colombier.CW Waitmsg 2339a747e4fSDavid du Colombierstructure: 2349a747e4fSDavid du Colombier.P1 2359a747e4fSDavid du ColombierWaitmsg *w; 2369a747e4fSDavid du Colombier 2379a747e4fSDavid du Colombierw = wait(); 2389a747e4fSDavid du Colombierif(w == nil) 2399a747e4fSDavid du Colombier error("wait: %r"); 2409a747e4fSDavid du Colombierprint("pid is %d; exit string %s\en", w->pid, w->msg); 2419a747e4fSDavid du Colombierfree(w); 2429a747e4fSDavid du Colombier.P2 2439a747e4fSDavid du ColombierThe exit string 2449a747e4fSDavid du Colombier.CW w->msg 2459a747e4fSDavid du Colombiermay be empty but it will never be a nil pointer. 2469a747e4fSDavid du ColombierAgain, don't forget to free the structure returned by 2479a747e4fSDavid du Colombier.CW wait . 2489a747e4fSDavid du ColombierIf all you need is the pid, you can call 2499a747e4fSDavid du Colombier.CW waitpid , 2509a747e4fSDavid du Colombierwhich reports just the pid and doesn't return an allocated structure: 2519a747e4fSDavid du Colombier.P1 2529a747e4fSDavid du Colombierint pid; 2539a747e4fSDavid du Colombier 2549a747e4fSDavid du Colombierpid = waitpid(); 2559a747e4fSDavid du Colombierif(pid < 0) 2569a747e4fSDavid du Colombier error("wait: %r"); 2579a747e4fSDavid du Colombierprint("pid is %d\en", pid); 2589a747e4fSDavid du Colombier.P2 2599a747e4fSDavid du Colombier.SH 2609a747e4fSDavid du ColombierQuoted strings and tokenize 2619a747e4fSDavid du Colombier.PP 2629a747e4fSDavid du Colombier.CW Wait 2639a747e4fSDavid du Colombiergives us a good opportunity to describe how the system copes with all this 2649a747e4fSDavid du Colombierfree-format data. 2659a747e4fSDavid du ColombierConsider the text returned by the 2669a747e4fSDavid du Colombier.CW await 2679a747e4fSDavid du Colombiersystem call, which includes a set of integers (pids and times) and a string (the exit status). 2689a747e4fSDavid du ColombierThis information is formatted free-form; here is the statement in the kernel that 2699a747e4fSDavid du Colombiergenerates the message: 2709a747e4fSDavid du Colombier.P1 2719a747e4fSDavid du Colombiern = snprint(a, n, "%d %lud %lud %lud %q", 2729a747e4fSDavid du Colombier wq->w.pid, 2739a747e4fSDavid du Colombier wq->w.time[TUser], wq->w.time[TSys], wq->w.time[TReal], 2749a747e4fSDavid du Colombier wq->w.msg); 2759a747e4fSDavid du Colombier.P2 2769a747e4fSDavid du ColombierNote the use of 2779a747e4fSDavid du Colombier.CW %q 2789a747e4fSDavid du Colombierto produce a quoted-string representation of the exit status. 2799a747e4fSDavid du ColombierThe 2809a747e4fSDavid du Colombier.CW %q 2819a747e4fSDavid du Colombierformat is like %s but will wrap 2829a747e4fSDavid du Colombier.CW rc -style 2839a747e4fSDavid du Colombiersingle quotes around the string if it contains white space or is otherwise ambiguous. 2849a747e4fSDavid du ColombierThe library routine 2859a747e4fSDavid du Colombier.CW tokenize 2869a747e4fSDavid du Colombiercan be used to parse data formatted this way: it splits white-space-separated 2879a747e4fSDavid du Colombierfields but understands the 2889a747e4fSDavid du Colombier.CW %q 2899a747e4fSDavid du Colombierquoting conventions. 2909a747e4fSDavid du ColombierHere is how the 2919a747e4fSDavid du Colombier.CW wait 2929a747e4fSDavid du Colombierlibrary routine builds its 2939a747e4fSDavid du Colombier.CW Waitmsg 2949a747e4fSDavid du Colombierfrom the data returned by 2959a747e4fSDavid du Colombier.CW await : 2969a747e4fSDavid du Colombier.P1 2979a747e4fSDavid du ColombierWaitmsg* 2989a747e4fSDavid du Colombierwait(void) 2999a747e4fSDavid du Colombier{ 3009a747e4fSDavid du Colombier int n, l; 3019a747e4fSDavid du Colombier char buf[512], *fld[5]; 3029a747e4fSDavid du Colombier Waitmsg *w; 3039a747e4fSDavid du Colombier 3049a747e4fSDavid du Colombier n = await(buf, sizeof buf-1); 3059a747e4fSDavid du Colombier if(n < 0) 3069a747e4fSDavid du Colombier return nil; 3079a747e4fSDavid du Colombier buf[n] = '\0'; 3089a747e4fSDavid du Colombier if(tokenize(buf, fld, nelem(fld)) != nelem(fld)){ 3099a747e4fSDavid du Colombier werrstr("couldn't parse wait message"); 3109a747e4fSDavid du Colombier return nil; 3119a747e4fSDavid du Colombier } 3129a747e4fSDavid du Colombier l = strlen(fld[4])+1; 3139a747e4fSDavid du Colombier w = malloc(sizeof(Waitmsg)+l); 3149a747e4fSDavid du Colombier if(w == nil) 3159a747e4fSDavid du Colombier return nil; 3169a747e4fSDavid du Colombier w->pid = atoi(fld[0]); 3179a747e4fSDavid du Colombier w->time[0] = atoi(fld[1]); 3189a747e4fSDavid du Colombier w->time[1] = atoi(fld[2]); 3199a747e4fSDavid du Colombier w->time[2] = atoi(fld[3]); 3209a747e4fSDavid du Colombier w->msg = (char*)&w[1]; 3219a747e4fSDavid du Colombier memmove(w->msg, fld[4], l); 3229a747e4fSDavid du Colombier return w; 3239a747e4fSDavid du Colombier} 3249a747e4fSDavid du Colombier.P2 3259a747e4fSDavid du Colombier.PP 3269a747e4fSDavid du ColombierThis style of quoted-string and 3279a747e4fSDavid du Colombier.CW tokenize 3289a747e4fSDavid du Colombieris used all through the system now. 3299a747e4fSDavid du ColombierIn particular, devices now 3309a747e4fSDavid du Colombier.CW tokenize 3319a747e4fSDavid du Colombierthe messages written to their 3329a747e4fSDavid du Colombier.CW ctl 3339a747e4fSDavid du Colombierfiles, which means that you can send messages that contain white space, by quoting them, 3349a747e4fSDavid du Colombierand that you no longer need to worry about whether or not the device accepts a newline. 3359a747e4fSDavid du ColombierIn other words, you can say 3369a747e4fSDavid du Colombier.P1 3379a747e4fSDavid du Colombierecho message > /dev/xx/ctl 3389a747e4fSDavid du Colombier.P2 3399a747e4fSDavid du Colombierinstead of 3409a747e4fSDavid du Colombier.CW echo 3419a747e4fSDavid du Colombier.CW -n 3429a747e4fSDavid du Colombierbecause 3439a747e4fSDavid du Colombier.CW tokenize 3449a747e4fSDavid du Colombiertreats the newline character as white space and discards it. 3459a747e4fSDavid du Colombier.PP 3469a747e4fSDavid du ColombierWhile we're on the subject of quotes and strings, note that the implementation of 3479a747e4fSDavid du Colombier.CW await 3489a747e4fSDavid du Colombierused 3499a747e4fSDavid du Colombier.CW snprint 3509a747e4fSDavid du Colombierrather than 3519a747e4fSDavid du Colombier.CW sprint . 3529a747e4fSDavid du ColombierWe now deprecate 3539a747e4fSDavid du Colombier.CW sprint 3549a747e4fSDavid du Colombierbecause it has no protection against buffer overflow. 3559a747e4fSDavid du ColombierWe prefer 3569a747e4fSDavid du Colombier.CW snprint 3579a747e4fSDavid du Colombieror 3589a747e4fSDavid du Colombier.CW seprint , 3599a747e4fSDavid du Colombierto constrain the output. 3609a747e4fSDavid du ColombierThe 3619a747e4fSDavid du Colombier.CW %q 3629a747e4fSDavid du Colombierformat is cleverer than most in this regard: 3639a747e4fSDavid du Colombierif the string is too long to be represented in full, 3649a747e4fSDavid du Colombier.CW %q 3659a747e4fSDavid du Colombieris smart enough to produce a truncated but correctly quoted 3669a747e4fSDavid du Colombierstring within the available space. 3679a747e4fSDavid du Colombier.SH 3689a747e4fSDavid du ColombierMount 3699a747e4fSDavid du Colombier.PP 3709a747e4fSDavid du ColombierAlthough strings in 9P are now variable-length and not zero-terminated, 3719a747e4fSDavid du Colombierthis has little direct effect in most of the system interfaces. 3729a747e4fSDavid du ColombierFile and user names are still zero-terminated strings as always; 3739a747e4fSDavid du Colombierthe kernel does the work of translating them as necessary for 3749a747e4fSDavid du Colombiertransport. 3759a747e4fSDavid du ColombierAnd of course, they are now free to be as long as you might want; 3769a747e4fSDavid du Colombierthe only hard limit is that their length must be represented in 16 bits. 3779a747e4fSDavid du Colombier.PP 3789a747e4fSDavid du ColombierOne example where this matters is that the file system specification in the 3799a747e4fSDavid du Colombier.CW mount 3809a747e4fSDavid du Colombiersystem call can now be much longer. 3819a747e4fSDavid du ColombierPrograms like 3829a747e4fSDavid du Colombier.CW rio 3839a747e4fSDavid du Colombierthat used the specification string in creative ways were limited by the 3849a747e4fSDavid du Colombier.CW NAMELEN 3859a747e4fSDavid du Colombierrestriction; now they can use the string more freely. 3869a747e4fSDavid du Colombier.CW Rio 3879a747e4fSDavid du Colombiernow accepts a simple but less cryptic specification language for the window 3889a747e4fSDavid du Colombierto be created by the 3899a747e4fSDavid du Colombier.CW mount 3909a747e4fSDavid du Colombiercall, e.g.: 3919a747e4fSDavid du Colombier.P1 3929a747e4fSDavid du Colombier% mount $wsys /mnt/wsys 'new -dx 250 -dy 250 -pid 1234' 3939a747e4fSDavid du Colombier.P2 3949a747e4fSDavid du ColombierIn the old system, this sort of control was impossible through the 3959a747e4fSDavid du Colombier.CW mount 3969a747e4fSDavid du Colombierinterface. 3979a747e4fSDavid du Colombier.PP 3989a747e4fSDavid du ColombierWhile we're on the subject of 3999a747e4fSDavid du Colombier.CW mount , 4009a747e4fSDavid du Colombiernote that with the new security architecture 4019a747e4fSDavid du Colombier(see 4029a747e4fSDavid du Colombier.I factotum (4)), 4039a747e4fSDavid du Colombier9P has moved its authentication outside the protocol proper. 4049a747e4fSDavid du Colombier(For a full description of this change to 9P, see 4059a747e4fSDavid du Colombier.I fauth (2), 4069a747e4fSDavid du Colombier.I attach (5), 4079a747e4fSDavid du Colombierand the paper 4089a747e4fSDavid du Colombier.I "Security in Plan 9\f1.) 4099a747e4fSDavid du ColombierThe most explicit effect of this change is that 4109a747e4fSDavid du Colombier.CW mount 4119a747e4fSDavid du Colombiernow takes another argument, 4129a747e4fSDavid du Colombier.CW afd , 4139a747e4fSDavid du Colombiera file descriptor for the 4149a747e4fSDavid du Colombierauthentication file through which the authentication will be made. 4159a747e4fSDavid du ColombierFor most user-level file servers, which do not require authentication, it is 4169a747e4fSDavid du Colombiersufficient to provide 4179a747e4fSDavid du Colombier.CW -1 4189a747e4fSDavid du Colombieras the value of 4199a747e4fSDavid du Colombier.CW afd: 4209a747e4fSDavid du Colombier.P1 421b7b24591SDavid du Colombierif(mount(fd, -1, "/mnt/wsys", MREPL, 4229a747e4fSDavid du Colombier "new -dx 250 -dy 250 -pid 1234") < 0) 4239a747e4fSDavid du Colombier error("mount failed: %r"); 4249a747e4fSDavid du Colombier.P2 4259a747e4fSDavid du ColombierTo connect to servers that require authentication, use the new 4269a747e4fSDavid du Colombier.CW fauth 4279a747e4fSDavid du Colombiersystem call or the reimplemented 4289a747e4fSDavid du Colombier.CW amount 4299a747e4fSDavid du Colombier(authenticated mount) library call. 4309a747e4fSDavid du ColombierIn fact, since 4319a747e4fSDavid du Colombier.CW amount 4329a747e4fSDavid du Colombierhandles both authenticating and non-authenticating servers, it is often 4339a747e4fSDavid du Colombiereasiest just to replace calls to 4349a747e4fSDavid du Colombier.CW mount 4359a747e4fSDavid du Colombierby calls to 4369a747e4fSDavid du Colombier.CW amount ; 4379a747e4fSDavid du Colombiersee 4389a747e4fSDavid du Colombier.I auth (2) 4399a747e4fSDavid du Colombierfor details. 4409a747e4fSDavid du Colombier.SH 4419a747e4fSDavid du ColombierPrint 4429a747e4fSDavid du Colombier.PP 4439a747e4fSDavid du ColombierThe C library has been heavily reworked in places. 4449a747e4fSDavid du ColombierBesides the changes mentioned above, it 4459a747e4fSDavid du Colombiernow has a much more complete set of routines for handling 4469a747e4fSDavid du Colombier.CW Rune 4479a747e4fSDavid du Colombierstrings (that is, zero-terminated arrays of 16-bit character values). 4489a747e4fSDavid du ColombierThe most sweeping changes, however, are in the way formatted I/O is performed. 4499a747e4fSDavid du Colombier.PP 4509a747e4fSDavid du ColombierThe 4519a747e4fSDavid du Colombier.CW print 4529a747e4fSDavid du Colombierroutine and all its relatives have been reimplemented to offer a number 4539a747e4fSDavid du Colombierof improvements: 4549a747e4fSDavid du Colombier.IP (1) 4559a747e4fSDavid du ColombierBetter buffer management, including the provision of an internal flush 4569a747e4fSDavid du Colombierroutine, makes it unnecessary to provide large buffers. 4579a747e4fSDavid du ColombierFor example, 4589a747e4fSDavid du Colombier.CW print 4599a747e4fSDavid du Colombieruses a much smaller buffer now (reducing stack load) while simultaneously 4609a747e4fSDavid du Colombierremoving the need to truncate the output string if it doesn't fit in the buffer. 4619a747e4fSDavid du Colombier.IP (2) 4629a747e4fSDavid du ColombierGlobal variables have been eliminated so no locking is necessary. 4639a747e4fSDavid du Colombier.IP (3) 4649a747e4fSDavid du ColombierThe combination of (1) and (2) means that the standard implementation of 4659a747e4fSDavid du Colombier.CW print 4669a747e4fSDavid du Colombiernow works fine in threaded programs, and 4679a747e4fSDavid du Colombier.CW threadprint 4689a747e4fSDavid du Colombieris gone. 4699a747e4fSDavid du Colombier.IP (4) 4709a747e4fSDavid du ColombierThe new routine 4719a747e4fSDavid du Colombier.CW smprint 4729a747e4fSDavid du Colombierprints into, and returns, storage allocated on demand by 4739a747e4fSDavid du Colombier.CW malloc . 4749a747e4fSDavid du Colombier.IP (5) 4759a747e4fSDavid du ColombierIt is now possible to print into a 4769a747e4fSDavid du Colombier.CW Rune 4779a747e4fSDavid du Colombierstring; for instance, 4789a747e4fSDavid du Colombier.CW runesmprint 4799a747e4fSDavid du Colombieris the 4809a747e4fSDavid du Colombier.CW Rune 4819a747e4fSDavid du Colombieranalog of 4829a747e4fSDavid du Colombier.CW smprint . 4839a747e4fSDavid du Colombier.IP (6) 4849a747e4fSDavid du ColombierThere is improved support for custom 4859a747e4fSDavid du Colombierprint verbs and custom output routines such as error handlers. 4869a747e4fSDavid du ColombierThe routine 4879a747e4fSDavid du Colombier.CW doprint 4889a747e4fSDavid du Colombieris gone, but 4899a747e4fSDavid du Colombier.CW vseprint 4909a747e4fSDavid du Colombiercan always be used instead. 4919a747e4fSDavid du ColombierHowever, the new routines 4929a747e4fSDavid du Colombier.CW fmtfdinit , 4939a747e4fSDavid du Colombier.CW fmtstrinit , 4949a747e4fSDavid du Colombier.CW fmtprint , 4959a747e4fSDavid du Colombierand friends 4969a747e4fSDavid du Colombierare often a better replacement. 4979a747e4fSDavid du ColombierThe details are too long for exposition here; 4989a747e4fSDavid du Colombier.I fmtinstall (2) 4999a747e4fSDavid du Colombierexplains the new interface and provides examples. 5009a747e4fSDavid du Colombier.IP (7) 5019a747e4fSDavid du ColombierTwo new format flags, space and comma, close somewhat the gap between 5029a747e4fSDavid du ColombierPlan 9 and ANSI C. 5039a747e4fSDavid du Colombier.PP 5049a747e4fSDavid du ColombierDespite these changes, most programs will be unaffected; 5059a747e4fSDavid du Colombier.CW print 5069a747e4fSDavid du Colombieris still 5079a747e4fSDavid du Colombier.CW print . 5089a747e4fSDavid du ColombierDon't forget, though, that 5099a747e4fSDavid du Colombieryou should eliminate calls to 5109a747e4fSDavid du Colombier.CW sprint 5119a747e4fSDavid du Colombierand use the 5129a747e4fSDavid du Colombier.CW %q 5139a747e4fSDavid du Colombierformat when appropriate. 5149a747e4fSDavid du Colombier.SH 5159a747e4fSDavid du ColombierBinary compatibility 5169a747e4fSDavid du Colombier.PP 5179a747e4fSDavid du ColombierThe discussion so far has been about changes at the source level. 5189a747e4fSDavid du ColombierExisting binaries will probably run without change in the new 5199a747e4fSDavid du Colombierenvironment, since the kernel provides backward-compatible 5209a747e4fSDavid du Colombiersystem calls for 5219a747e4fSDavid du Colombier.CW errstr , 5229a747e4fSDavid du Colombier.CW stat , 5239a747e4fSDavid du Colombier.CW wait , 5249a747e4fSDavid du Colombieretc. 5259a747e4fSDavid du ColombierThe only exceptions are programs that do either a 5269a747e4fSDavid du Colombier.CW mount 5279a747e4fSDavid du Colombiersystem call, because of the security changes and because 5289a747e4fSDavid du Colombierthe file descriptor in 5299a747e4fSDavid du Colombier.CW mount 5309a747e4fSDavid du Colombiermust point to a new 9P connection; or a 5319a747e4fSDavid du Colombier.CW read 5329a747e4fSDavid du Colombiersystem call on a directory, since the returned data will 5339a747e4fSDavid du Colombierbe in the new format. 5349a747e4fSDavid du ColombierA moment's reflection will discover that this means old 5359a747e4fSDavid du Colombieruser-level file servers will need to be fixed to run on the new system. 5369a747e4fSDavid du Colombier.SH 5379a747e4fSDavid du ColombierFile servers 5389a747e4fSDavid du Colombier.PP 5399a747e4fSDavid du ColombierA full description of what user-level servers must do to provide service with 5409a747e4fSDavid du Colombierthe new 9P is beyond the scope of this paper. 5419a747e4fSDavid du ColombierYour best source of information is section 5 of the manual, 5429a747e4fSDavid du Colombiercombined with study of a few examples. 5439a747e4fSDavid du Colombier.CW /sys/src/cmd/ramfs.c 5449a747e4fSDavid du Colombieris a simple example; it has a counterpart 5459a747e4fSDavid du Colombier.CW /sys/src/lib9p/ramfs.c 5469a747e4fSDavid du Colombierthat implements the same service using the new 5479a747e4fSDavid du Colombier.I 9p (2) 5489a747e4fSDavid du Colombierlibrary. 5499a747e4fSDavid du Colombier.PP 5509a747e4fSDavid du ColombierThat said, it's worth summarizing what to watch for when converting a file server. 5519a747e4fSDavid du ColombierThe 5529a747e4fSDavid du Colombier.CW session 5539a747e4fSDavid du Colombiermessage is gone, and there is a now a 5549a747e4fSDavid du Colombier.CW version 5559a747e4fSDavid du Colombiermessage that is exchanged at the start of a connection to establish 5569a747e4fSDavid du Colombierthe version of the protocol to use (there's only one at the moment, identified by 5579a747e4fSDavid du Colombierthe string 5589a747e4fSDavid du Colombier.CW 9P2000 ) 5599a747e4fSDavid du Colombierand what the maximum message size will be. 5609a747e4fSDavid du ColombierThis negotiation makes it easier to handle 9P encapsulation, such as with 5619a747e4fSDavid du Colombier.CW exportfs , 5629a747e4fSDavid du Colombierand also permits larger message sizes when appropriate. 5639a747e4fSDavid du Colombier.PP 5649a747e4fSDavid du ColombierIf your server wants to authenticate, it will need to implement an authentication file 5659a747e4fSDavid du Colombierand implement the 5669a747e4fSDavid du Colombier.CW auth 5679a747e4fSDavid du Colombiermessage; otherwise it should return a helpful error string to the 5689a747e4fSDavid du Colombier.CW Tauth 5699a747e4fSDavid du Colombierrequest to signal that authentication is not required. 5709a747e4fSDavid du Colombier.PP 5719a747e4fSDavid du ColombierThe handling of 5729a747e4fSDavid du Colombier.CW stat 5739a747e4fSDavid du Colombierand directory reads will require some changes but they should not be fundamental. 5749a747e4fSDavid du ColombierBe aware that seeking on directories is forbidden, so it is fine if you disregard the 5759a747e4fSDavid du Colombierfile offset when implementing directory reads; this makes it a little easier to handle 5769a747e4fSDavid du Colombierthe variable-length entries. 5779a747e4fSDavid du ColombierYou should still never return a partial directory entry; if the I/O count is too small 5789a747e4fSDavid du Colombierto return even one entry, you should return two bytes containing the byte count 5799a747e4fSDavid du Colombierrequired to represent the next entry in the directory. 5809a747e4fSDavid du ColombierUser code can use this value to formulate a retry if it desires. 5819a747e4fSDavid du ColombierSee the 5829a747e4fSDavid du ColombierDIAGNOSTICS section of 5839a747e4fSDavid du Colombier.I stat (2) 5849a747e4fSDavid du Colombierfor a description of this process. 5859a747e4fSDavid du Colombier.PP 5869a747e4fSDavid du ColombierThe trickiest part of updating a file server is that the 5879a747e4fSDavid du Colombier.CW clone 5889a747e4fSDavid du Colombierand 5899a747e4fSDavid du Colombier.CW walk 5909a747e4fSDavid du Colombiermessages have been merged into a single message, a sort of `clone-multiwalk'. 5919a747e4fSDavid du ColombierThe new message, still called 5929a747e4fSDavid du Colombier.CW walk , 5939a747e4fSDavid du Colombierproposes a sequence of file name elements to be evaluated using a possibly 5949a747e4fSDavid du Colombiercloned fid. 5959a747e4fSDavid du ColombierThe return message contains the qids of the files reached by 5969a747e4fSDavid du Colombierwalking to the sequential elements. 5979a747e4fSDavid du ColombierIf all the elements can be walked, the fid will be cloned if requested. 5989a747e4fSDavid du ColombierIf a non-zero number of elements are requested, but none 5999a747e4fSDavid du Colombiercan be walked, an error should be returned. 6009a747e4fSDavid du ColombierIf only some can be walked, the fid is not cloned, the original fid is left 6019a747e4fSDavid du Colombierwhere it was, and the returned 6029a747e4fSDavid du Colombier.CW Rwalk 6039a747e4fSDavid du Colombiermessage should contain the partial list of successfully reached qids. 6049a747e4fSDavid du ColombierSee 6059a747e4fSDavid du Colombier.I walk (5) 6069a747e4fSDavid du Colombierfor a full description. 607