9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

commit 65f285bad8c2fe136ce4c4a99f12cfc1cb2d0f68
parent a3b65ffcdcc4450db02e999e89d126201852813f
Author: Kris Maglione <maglione.k@gmail.com>
Date:   Mon, 19 Jul 2010 11:50:26 -0400

Sync lib9 with plan9port. Fix build with bsdmake.
Diffstat:
Mdiff/Makefile | 2+-
Mlib9/Makefile | 4++--
Mlib9/_p9dir.c | 10++++++++--
Mlib9/bio/bgetrune.c | 2+-
Mlib9/bio/bputrune.c | 2+-
Mlib9/convM2S.c | 20+++++++++++++++++---
Mlib9/convS2M.c | 20+++++++++++++++++---
Mlib9/dial.c | 5+++++
Mlib9/dirread.c | 2+-
Mlib9/fcall.h | 24++++++++++++++++++++----
Mlib9/fmt.h | 2+-
Mlib9/fmt/dofmt.c | 11++++++-----
Mlib9/libc.h | 5+++--
Mlib9/u.h | 3+++
Mlib9/utf.h | 6+++---
Mlib9/utf/rune.c | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
16 files changed, 148 insertions(+), 48 deletions(-)

diff --git a/diff/Makefile b/diff/Makefile @@ -32,4 +32,4 @@ clean: ${TARG}: ${OFILES} @echo LD ${TARG} - @${CC} ${LDFLAGS} -o ${TARG} ${OFILES} -lm -L${PREFIX}/lib -L../lib9 -l9 + ${CC} ${LDFLAGS} -o ${TARG} ${OFILES} -lm -L../lib9 -L${PREFIX}/lib -l9 diff --git a/lib9/Makefile b/lib9/Makefile @@ -221,8 +221,8 @@ ${LIB}: ${OFILES} @${AR} ${LIB} ${OFILES} .c.o: - @echo CC $*.c - @${CC} -o $*.o ${CFLAGS} -Isec -I${PREFIX}/include $*.c + @echo CC $< + @${CC} -o $@ ${CFLAGS} -Isec -I${PREFIX}/include $< clean: rm -f ${OFILES} ${LIB} diff --git a/lib9/_p9dir.c b/lib9/_p9dir.c @@ -44,7 +44,6 @@ disksize(int fd, struct stat *st) #define _HAVESTGEN #include <sys/disklabel.h> #include <sys/ioctl.h> -#include <sys/dkio.h> static vlong disksize(int fd, struct stat *st) { @@ -190,7 +189,14 @@ _p9dir(struct stat *lst, struct stat *st, char *name, Dir *d, char **str, char * d->type = 'M'; d->muid = ""; - d->qid.path = ((uvlong)st->st_dev<<32) | st->st_ino; + d->qid.path = st->st_ino; + /* + * do not include st->st_dev in path, because + * automounters give the same file system different + * st_dev values for successive mounts, causing + * spurious write warnings in acme and sam. + d->qid.path |= (uvlong)st->st_dev<<32; + */ #ifdef _HAVESTGEN d->qid.vers = st->st_gen; #endif diff --git a/lib9/bio/bgetrune.c b/lib9/bio/bgetrune.c @@ -7,7 +7,7 @@ Bgetrune(Biobuf *bp) { int c, i; Rune rune; - char str[4]; + char str[UTFmax]; c = Bgetc(bp); if(c < Runeself) { /* one char */ diff --git a/lib9/bio/bputrune.c b/lib9/bio/bputrune.c @@ -6,7 +6,7 @@ int Bputrune(Biobuf *bp, long c) { Rune rune; - char str[4]; + char str[UTFmax]; int n; rune = c; diff --git a/lib9/convM2S.c b/lib9/convM2S.c @@ -100,6 +100,13 @@ convM2Su(uchar *ap, uint nap, Fcall *f, int dotu) p = gstring(p, ep, &f->aname); if(p == nil) break; + f->uidnum = NOUID; + if(dotu){ + if(p+BIT32SZ > ep) + return 0; + f->uidnum = GBIT32(p); + p += BIT32SZ; + } break; case Tattach: @@ -117,6 +124,13 @@ convM2Su(uchar *ap, uint nap, Fcall *f, int dotu) p = gstring(p, ep, &f->aname); if(p == nil) break; + f->uidnum = NOUID; + if(dotu){ + if(p+BIT32SZ > ep) + return 0; + f->uidnum = GBIT32(p); + p += BIT32SZ; + } break; case Twalk: @@ -233,10 +247,10 @@ convM2Su(uchar *ap, uint nap, Fcall *f, int dotu) p = gstring(p, ep, &f->ename); f->errornum = 0; if(dotu){ - if(p+BIT16SZ > ep) + if(p+BIT32SZ > ep) return 0; - f->errornum = GBIT16(p); - p += BIT16SZ; + f->errornum = GBIT32(p); + p += BIT32SZ; } break; diff --git a/lib9/convS2M.c b/lib9/convS2M.c @@ -74,6 +74,8 @@ sizeS2Mu(Fcall *f, int dotu) n += BIT32SZ; n += stringsz(f->uname); n += stringsz(f->aname); + if(dotu) + n += BIT32SZ; break; case Tattach: @@ -81,6 +83,8 @@ sizeS2Mu(Fcall *f, int dotu) n += BIT32SZ; n += stringsz(f->uname); n += stringsz(f->aname); + if(dotu) + n += BIT32SZ; break; case Twalk: @@ -144,7 +148,7 @@ sizeS2Mu(Fcall *f, int dotu) case Rerror: n += stringsz(f->ename); if(dotu) - n += BIT16SZ; + n += BIT32SZ; break; case Rflush: @@ -249,6 +253,11 @@ convS2Mu(Fcall *f, uchar *ap, uint nap, int dotu) p += BIT32SZ; p = pstring(p, f->uname); p = pstring(p, f->aname); + if(dotu){ + f->uidnum = NOUID; + PBIT32(p, f->uidnum); + p += BIT32SZ; + } break; case Tattach: @@ -258,6 +267,11 @@ convS2Mu(Fcall *f, uchar *ap, uint nap, int dotu) p += BIT32SZ; p = pstring(p, f->uname); p = pstring(p, f->aname); + if(dotu){ + f->uidnum = NOUID; + PBIT32(p, f->uidnum); + p += BIT32SZ; + } break; case Twalk: @@ -344,8 +358,8 @@ convS2Mu(Fcall *f, uchar *ap, uint nap, int dotu) case Rerror: p = pstring(p, f->ename); if(dotu){ - PBIT16(p, f->errornum); - p += BIT16SZ; + PBIT32(p, f->errornum); + p += BIT32SZ; } break; diff --git a/lib9/dial.c b/lib9/dial.c @@ -46,6 +46,11 @@ p9dial(char *addr, char *local, char *dummy2, int *dummy3) free(buf); return -1; } + if(strcmp(net, "unix") != 0 && host == 0){ + werrstr("invalid dial address 0.0.0.0 (aka *)"); + free(buf); + return -1; + } if(strcmp(net, "tcp") == 0) proto = SOCK_STREAM; diff --git a/lib9/dirread.c b/lib9/dirread.c @@ -6,7 +6,7 @@ extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); -#if defined(__linux__) || defined(__FreeBSD_kernel__) +#if defined(__linux__) static int mygetdents(int fd, struct dirent *buf, int n) { diff --git a/lib9/fcall.h b/lib9/fcall.h @@ -34,20 +34,25 @@ struct Fcall ushort nwname; /* Twalk */ char *wname[MAXWELEM]; /* Twalk */ ushort nwqid; /* Rwalk */ - Qid wqid[MAXWELEM]; /* Rwalk */ + Qid wqid[MAXWELEM]; /* Rwalk */ vlong offset; /* Tread, Twrite */ u32int count; /* Tread, Twrite, Rread */ char *data; /* Twrite, Rread */ ushort nstat; /* Twstat, Rstat */ uchar *stat; /* Twstat, Rstat */ int unixfd; /* Ropenfd */ + + /* 9P2000.u extensions */ + int errornum; /* Rerror */ + int uidnum; /* Tattach, Tauth */ + char *extension; /* Tcreate */ } Fcall; #define GBIT8(p) ((p)[0]) #define GBIT16(p) ((p)[0]|((p)[1]<<8)) -#define GBIT32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) -#define GBIT64(p) ((vlong)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\ +#define GBIT32(p) ((u32int)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))) +#define GBIT64(p) ((u32int)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\ ((vlong)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32)) #define PBIT8(p,v) (p)[0]=(v) @@ -65,9 +70,11 @@ struct Fcall /* STATFIXLEN includes leading 16-bit count */ /* The count, however, excludes itself; total size is BIT16SZ+count */ #define STATFIXLEN (BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+1*BIT64SZ) /* amount of fixed length data in a stat buffer */ +#define STATFIXLENU (STATFIXLEN+BIT16SZ+3*BIT32SZ) /* for 9P2000.u */ #define NOTAG (ushort)~0U /* Dummy tag */ #define NOFID (u32int)~0U /* Dummy fid */ +#define NOUID (-1) /* Dummy uid */ #define IOHDRSZ 24 /* ample room for Twrite/Rread header (iounit) */ enum @@ -103,7 +110,7 @@ enum Tmax, Topenfd = 98, - Ropenfd, + Ropenfd }; uint convM2S(uchar*, uint, Fcall*); @@ -115,6 +122,15 @@ uint convM2D(uchar*, uint, Dir*, char*); uint convD2M(Dir*, uchar*, uint); uint sizeD2M(Dir*); +uint convM2Su(uchar*, uint, Fcall*, int); +uint convS2Mu(Fcall*, uchar*, uint, int); +uint sizeS2Mu(Fcall*, int); + +int statchecku(uchar *abuf, uint nbuf, int); +uint convM2Du(uchar*, uint, Dir*, char*, int); +uint convD2Mu(Dir*, uchar*, uint, int); +uint sizeD2Mu(Dir*, int); + int fcallfmt(Fmt*); int dirfmt(Fmt*); int dirmodefmt(Fmt*); diff --git a/lib9/fmt.h b/lib9/fmt.h @@ -30,7 +30,7 @@ struct Fmt{ void *farg; /* to make flush a closure */ int nfmt; /* num chars formatted so far */ va_list args; /* args passed to dofmt */ - int r; /* % format Rune */ + Rune r; /* % format Rune */ int width; int prec; unsigned long flags; diff --git a/lib9/fmt/dofmt.c b/lib9/fmt/dofmt.c @@ -605,12 +605,13 @@ __flagfmt(Fmt *f) int __badfmt(Fmt *f) { - char x[3]; + char x[2+UTFmax]; + int n; x[0] = '%'; - x[1] = f->r; - x[2] = '%'; - f->prec = 3; - __fmtcpy(f, (const void*)x, 3, 3); + n = 1 + runetochar(x+1, &f->r); + x[n++] = '%'; + f->prec = n; + __fmtcpy(f, (const void*)x, n, n); return 0; } diff --git a/lib9/libc.h b/lib9/libc.h @@ -66,10 +66,11 @@ extern int tokenize(char*, char**, int); /* enum { - UTFmax = 3, + UTFmax = 4, Runesync = 0x80, Runeself = 0x80, - Runeerror = 0x80, + Runeerror = 0xFFFD, + Runemax = 0x10FFFF, }; */ diff --git a/lib9/u.h b/lib9/u.h @@ -32,6 +32,9 @@ extern "C" { #if defined(__AIX__) # define _XOPEN_SOURCE 1 #endif +#if defined(__APPLE__) +# define _DARWIN_NO_64_BIT_INODE /* Snow Leopard */ +#endif #define _LARGEFILE64_SOURCE 1 #define _FILE_OFFSET_BITS 64 diff --git a/lib9/utf.h b/lib9/utf.h @@ -4,14 +4,14 @@ extern "C" { #endif -typedef unsigned short Rune; /* 16 bits */ +typedef unsigned int Rune; /* 32 bits */ enum { - UTFmax = 3, /* maximum bytes per rune */ + UTFmax = 4, /* maximum bytes per rune */ Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ Runeself = 0x80, /* rune and UTF sequences are the same (<) */ - Runeerror = 0xFFFD, /* decoding error in UTF */ + Runeerror = 0xFFFD, /* decoding error in UTF */ Runemax = 0x10FFFF /* maximum rune value */ }; diff --git a/lib9/utf/rune.c b/lib9/utf/rune.c @@ -23,16 +23,19 @@ enum Bit2 = 5, Bit3 = 4, Bit4 = 3, + Bit5 = 2, T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */ Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ + T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */ - Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ - Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ - Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ + Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */ + Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0000 0000 0111 1111 1111 */ + Rune3 = (1<<(Bit3+2*Bitx))-1, /* 0000 0000 1111 1111 1111 1111 */ + Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0011 1111 1111 1111 1111 1111 */ Maskx = (1<<Bitx)-1, /* 0011 1111 */ Testx = Maskx ^ 0xFF, /* 1100 0000 */ @@ -43,7 +46,7 @@ enum int chartorune(Rune *rune, char *str) { - int c, c1, c2; + int c, c1, c2, c3; long l; /* @@ -89,6 +92,25 @@ chartorune(Rune *rune, char *str) } /* + * four character sequence + * 10000-10FFFF => T4 Tx Tx Tx + */ + if(UTFmax >= 4) { + c3 = *(uchar*)(str+3) ^ Tx; + if(c3 & Testx) + goto bad; + if(c < T5) { + l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4; + if(l <= Rune3) + goto bad; + if(l > Runemax) + goto bad; + *rune = l; + return 4; + } + } + + /* * bad decoding */ bad: @@ -113,7 +135,7 @@ runetochar(char *str, Rune *rune) /* * two character sequence - * 0080-07FF => T2 Tx + * 00080-007FF => T2 Tx */ if(c <= Rune2) { str[0] = T2 | (c >> 1*Bitx); @@ -123,12 +145,26 @@ runetochar(char *str, Rune *rune) /* * three character sequence - * 0800-FFFF => T3 Tx Tx + * 00800-0FFFF => T3 Tx Tx */ - str[0] = T3 | (c >> 2*Bitx); - str[1] = Tx | ((c >> 1*Bitx) & Maskx); - str[2] = Tx | (c & Maskx); - return 3; + if(c > Runemax) + c = Runeerror; + if(c <= Rune3) { + str[0] = T3 | (c >> 2*Bitx); + str[1] = Tx | ((c >> 1*Bitx) & Maskx); + str[2] = Tx | (c & Maskx); + return 3; + } + + /* + * four character sequence + * 010000-1FFFFF => T4 Tx Tx Tx + */ + str[0] = T4 | (c >> 3*Bitx); + str[1] = Tx | ((c >> 2*Bitx) & Maskx); + str[2] = Tx | ((c >> 1*Bitx) & Maskx); + str[3] = Tx | (c & Maskx); + return 4; } int @@ -155,7 +191,10 @@ runenlen(Rune *r, int nrune) if(c <= Rune2) nb += 2; else + if(c <= Rune3 || c > Runemax) nb += 3; + else + nb += 4; } return nb; } @@ -165,13 +204,14 @@ fullrune(char *str, int n) { int c; - if(n > 0) { - c = *(uchar*)str; - if(c < Tx) - return 1; - if(n > 1) - if(c < T3 || n > 2) - return 1; - } - return 0; + if(n <= 0) + return 0; + c = *(uchar*)str; + if(c < Tx) + return 1; + if(c < T3) + return n >= 2; + if(UTFmax == 3 || c < T4) + return n >= 3; + return n >= 4; }