xref: /plan9/sys/doc/prog4.ms (revision 426d2b71458df9b491ba6c167f699b3f1f7b0428)
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