From c3c9c7b6ae7c6a8bf9c6d040d3af89e020fd92de Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 7 May 2020 08:37:51 -0400 Subject: fmt: disable use of stdatomic on AIX XL C and old GCC C11 is apparently too new for these systems. Fixes #55. --- src/lib9/fmt/fmt.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/lib9/fmt/fmt.c b/src/lib9/fmt/fmt.c index a86482c3..fdfff65d 100644 --- a/src/lib9/fmt/fmt.c +++ b/src/lib9/fmt/fmt.c @@ -1,7 +1,28 @@ /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */ #include #include + +/* + * As of 2020, older systems like RHEL 6 and AIX still do not have C11 atomics. + * On those systems, make the code use volatile int accesses and hope for the best. + * (Most uses of fmtinstall are not actually racing with calls to print that lookup + * formats. The code used volatile here for years without too many problems, + * even though that's technically racy. A mutex is not OK, because we want to + * be able to call print from signal handlers.) + * + * RHEL is using an old GCC (atomics were added in GCC 4.8). + * AIX is using its own IBM compiler (XL C). + */ +#if __IBMC__ || !__clang__ && __GNUC__ && (__GNUC__ < 4 || (__GNUC__==4 && __GNUC_MINOR__<8)) +#warning not using C11 stdatomic on legacy system +#define _Atomic volatile +#define atomic_load(x) (*(x)) +#define atomic_store(x, y) (*(x)=(y)) +#define ATOMIC_VAR_INIT(x) (x) +#else #include +#endif + #include "plan9.h" #include "fmt.h" #include "fmtdef.h" -- cgit v1.2.3 From 4982d4ebc3bd4924d73f2f2ad584309e9ec97435 Mon Sep 17 00:00:00 2001 From: Ben Huntsman Date: Mon, 4 May 2020 19:52:02 -0700 Subject: all: update build scripts to fix AIX XL/C compatibility --- bin/9c | 19 ++++++++++++++++++- bin/9l | 13 +++++++------ include/u.h | 4 ++-- src/cmd/mkfile | 2 +- src/mk.AIX-power | 2 ++ src/mkmk.sh | 6 +++++- 6 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 src/mk.AIX-power diff --git a/bin/9c b/bin/9c index 0f836d24..320a1634 100755 --- a/bin/9c +++ b/bin/9c @@ -82,6 +82,23 @@ useclang() cflags="$ngflags -g" } +usexlc() +{ + cc=${CC9:-xlc_r} + ngflags=" \ + -c \ + -O0 \ + -qmaxmem=-1 \ + -qsuppress=1506-236 \ + -qsuppress=1506-358 \ + -qsuppress=1500-010 \ + -qsuppress=1506-224 \ + -qsuppress=1506-1300 \ + -qsuppress=1506-342 \ + " + cflags="$ngflags -g -qfullpath" +} + tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}-${CC9:-cc}" case "$tag" in *DragonFly*gcc*|*BSD*gcc*) usegcc ;; @@ -120,7 +137,7 @@ case "$tag" in cflags="$ngflags -g" cflags="$cflags -D__sun__ -D__${s}__" ;; -*AIX*) usegcc +*AIX*) usexlc cflags="$ngflags -g -D__AIX__" ;; *) diff --git a/bin/9l b/bin/9l index a10aab72..398adbd8 100755 --- a/bin/9l +++ b/bin/9l @@ -61,8 +61,9 @@ case "$tag" in esac ;; *AIX*) - ld=${CC9:-gcc} - nmflags="-B" + ld="${CC9:-xlc_r} -g -O0" + nmflags="-A -B" + extralibs="$extralibs -lpthread" ;; *) echo do not know how to link on "$tag" 1>&2 @@ -113,8 +114,8 @@ then then a=` nm $nmflags $ofiles | - grep '__p9l_autolib_[a-zA-Z0-9+-]*$' | - sed 's/.*__p9l_autolib_//' | + grep '__p9l_autolib_[a-zA-Z0-9+-]*' | + sed 's/.*__p9l_autolib_//; s/:.*//' | sort -u ` for i in $a @@ -144,8 +145,8 @@ then do b=` nm $lpath/lib$i.a 2>/dev/null | - grep '__p9l_autolib_[a-zA-Z0-9+-]*$' | - sed 's/.*__p9l_autolib_//' | + grep '__p9l_autolib_[a-zA-Z0-9+-]*' | + sed 's/.*__p9l_autolib_//; s/:.*//' | sort -u | egrep -v '^(thread|draw)$' ` diff --git a/include/u.h b/include/u.h index 3bea890e..137b6161 100644 --- a/include/u.h +++ b/include/u.h @@ -20,7 +20,7 @@ extern "C" { #define _NETBSD_SOURCE 1 /* NetBSD */ #define _SVID_SOURCE 1 #define _DEFAULT_SOURCE 1 -#if !defined(__APPLE__) && !defined(__OpenBSD__) +#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__AIX__) # define _XOPEN_SOURCE 1000 # define _XOPEN_SOURCE_EXTENDED 1 #endif @@ -33,7 +33,7 @@ extern "C" { # define __LONG_LONG_SUPPORTED #endif #if defined(__AIX__) -# define _XOPEN_SOURCE 1 +# define _XOPEN_SOURCE 600 #endif #if defined(__APPLE__) # define _DARWIN_NO_64_BIT_INODE /* Snow Leopard */ diff --git a/src/cmd/mkfile b/src/cmd/mkfile index bc8b5a0d..2d0c657e 100644 --- a/src/cmd/mkfile +++ b/src/cmd/mkfile @@ -27,7 +27,7 @@ $PLAN9/bin/lex: $PLAN9/bin/yacc # This should not be necessary. $PLAN9/bin/yacc: $O.yacc - install -c $O.yacc $PLAN9/bin/yacc + $INSTALL -c $O.yacc $PLAN9/bin/yacc $O.yacc: yacc.$O $LD -o $target $prereq yacc.$O: yacc.c diff --git a/src/mk.AIX-power b/src/mk.AIX-power new file mode 100644 index 00000000..39f8ee8a --- /dev/null +++ b/src/mk.AIX-power @@ -0,0 +1,2 @@ +INSTALL=installbsd + diff --git a/src/mkmk.sh b/src/mkmk.sh index dae87ddf..0d52d3f9 100644 --- a/src/mkmk.sh +++ b/src/mkmk.sh @@ -211,5 +211,9 @@ echo cd `pwd` 9c word.c 9c unix.c 9l -o o.mk arc.o archive.o bufblock.o env.o file.o graph.o job.o lex.o main.o match.o mk.o parse.o recipe.o rc.o rule.o run.o sh.o shell.o shprint.o symtab.o var.o varsub.o word.o unix.o -install o.mk $PLAN9/bin/mk +if [ `uname` = AIX ]; then + installbsd o.mk $PLAN9/bin/mk +else + install o.mk $PLAN9/bin/mk +fi cd .. -- cgit v1.2.3 From f84d54a0337f9e101c8baeb51272f33b05b2a0e1 Mon Sep 17 00:00:00 2001 From: Ben Huntsman Date: Mon, 4 May 2020 19:52:40 -0700 Subject: mk: support Big Archive Format under AIX --- src/cmd/mk/archive.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cmd/mk/archive.c b/src/cmd/mk/archive.c index 5b0c1d00..6d646979 100644 --- a/src/cmd/mk/archive.c +++ b/src/cmd/mk/archive.c @@ -1,5 +1,9 @@ #include "mk.h" +#if defined(__AIX__) +#define ARMAG "\n" +#else #define ARMAG "!\n" +#endif #define SARMAG (sizeof(ARMAG) - sizeof("")) #define ARFMAG "`\n" -- cgit v1.2.3 From 5802b09e9d8ceadd2cefdccfd0391c04e492369b Mon Sep 17 00:00:00 2001 From: Ben Huntsman Date: Mon, 4 May 2020 19:53:21 -0700 Subject: all: fix #includes for AIX, add a few AIX "implementation" files --- include/u.h | 4 ++++ src/cmd/9term/AIX.c | 2 ++ src/cmd/9term/bsdpty.c | 2 ++ src/cmd/auxstats/AIX.c | 9 +++++++++ src/cmd/draw/mc.c | 3 +++ src/cmd/vbackup/mount-AIX.c | 1 + src/lib9/readcons.c | 2 ++ src/libip/AIX.c | 1 + src/libmach/AIX.c | 1 + 9 files changed, 25 insertions(+) create mode 100644 src/cmd/9term/AIX.c create mode 100644 src/cmd/auxstats/AIX.c create mode 100644 src/cmd/vbackup/mount-AIX.c create mode 100644 src/libip/AIX.c create mode 100644 src/libmach/AIX.c diff --git a/include/u.h b/include/u.h index 137b6161..10fc7257 100644 --- a/include/u.h +++ b/include/u.h @@ -6,6 +6,8 @@ extern "C" { #endif +#define HAS_SYS_TERMIOS 1 + #define __BSD_VISIBLE 1 /* FreeBSD 5.x */ #if defined(__sun__) # define __EXTENSIONS__ 1 /* SunOS */ @@ -34,6 +36,8 @@ extern "C" { #endif #if defined(__AIX__) # define _XOPEN_SOURCE 600 +# define _ALL_SOURCE +# undef HAS_SYS_TERMIOS #endif #if defined(__APPLE__) # define _DARWIN_NO_64_BIT_INODE /* Snow Leopard */ diff --git a/src/cmd/9term/AIX.c b/src/cmd/9term/AIX.c new file mode 100644 index 00000000..b7ccbf0f --- /dev/null +++ b/src/cmd/9term/AIX.c @@ -0,0 +1,2 @@ +#define TIOCSCTTY 0x540E +#include "bsdpty.c" diff --git a/src/cmd/9term/bsdpty.c b/src/cmd/9term/bsdpty.c index d64e4c2f..3710a18d 100644 --- a/src/cmd/9term/bsdpty.c +++ b/src/cmd/9term/bsdpty.c @@ -5,7 +5,9 @@ #include #include #include +#ifdef HAS_SYS_TERMIOS #include +#endif #ifdef __linux__ #include #endif diff --git a/src/cmd/auxstats/AIX.c b/src/cmd/auxstats/AIX.c new file mode 100644 index 00000000..33ebdedc --- /dev/null +++ b/src/cmd/auxstats/AIX.c @@ -0,0 +1,9 @@ +#include +#include +#include +#include "dat.h" + +void (*statfn[])(int) = +{ + 0 +}; diff --git a/src/cmd/draw/mc.c b/src/cmd/draw/mc.c index ee112194..f1bcc82a 100644 --- a/src/cmd/draw/mc.c +++ b/src/cmd/draw/mc.c @@ -9,7 +9,10 @@ */ #include #include +#include +#ifdef HAS_SYS_TERMIOS #include +#endif #include #include #include diff --git a/src/cmd/vbackup/mount-AIX.c b/src/cmd/vbackup/mount-AIX.c new file mode 100644 index 00000000..3dde4fdf --- /dev/null +++ b/src/cmd/vbackup/mount-AIX.c @@ -0,0 +1 @@ +#include "mount-none.c" diff --git a/src/lib9/readcons.c b/src/lib9/readcons.c index 8de44b8f..c07e5971 100644 --- a/src/lib9/readcons.c +++ b/src/lib9/readcons.c @@ -2,7 +2,9 @@ #define NOPLAN9DEFINES #include #include +#ifdef HAS_SYS_TERMIOS #include +#endif static int rawx(int fd, int echoing) diff --git a/src/libip/AIX.c b/src/libip/AIX.c new file mode 100644 index 00000000..48c87c62 --- /dev/null +++ b/src/libip/AIX.c @@ -0,0 +1 @@ +#include "none.c" diff --git a/src/libmach/AIX.c b/src/libmach/AIX.c new file mode 100644 index 00000000..3626e7c6 --- /dev/null +++ b/src/libmach/AIX.c @@ -0,0 +1 @@ +#include "nosys.c" -- cgit v1.2.3 From bd6f12068b28ba7eb96a3cd495e2201c852682b7 Mon Sep 17 00:00:00 2001 From: Kurt H Maier Date: Thu, 7 May 2020 17:55:15 -0700 Subject: fmt: adjust GCC version check atomics were added in GCC 4.9: https://gcc.gnu.org/gcc-4.9/changes.html --- src/lib9/fmt/fmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib9/fmt/fmt.c b/src/lib9/fmt/fmt.c index fdfff65d..47b186a4 100644 --- a/src/lib9/fmt/fmt.c +++ b/src/lib9/fmt/fmt.c @@ -10,10 +10,10 @@ * even though that's technically racy. A mutex is not OK, because we want to * be able to call print from signal handlers.) * - * RHEL is using an old GCC (atomics were added in GCC 4.8). + * RHEL is using an old GCC (atomics were added in GCC 4.9). * AIX is using its own IBM compiler (XL C). */ -#if __IBMC__ || !__clang__ && __GNUC__ && (__GNUC__ < 4 || (__GNUC__==4 && __GNUC_MINOR__<8)) +#if __IBMC__ || !__clang__ && __GNUC__ && (__GNUC__ < 4 || (__GNUC__==4 && __GNUC_MINOR__<9)) #warning not using C11 stdatomic on legacy system #define _Atomic volatile #define atomic_load(x) (*(x)) -- cgit v1.2.3 From 58fdc083addda3f95eb8895f474da5a52f145be0 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 12:35:03 -0400 Subject: lib9: merge create, open, dirread into open.c Preparation for using opendir. --- src/lib9/create.c | 75 --------------- src/lib9/dirread.c | 207 ---------------------------------------- src/lib9/mkfile | 2 - src/lib9/open.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mkmk.sh | 11 +-- 5 files changed, 273 insertions(+), 292 deletions(-) delete mode 100644 src/lib9/create.c delete mode 100644 src/lib9/dirread.c diff --git a/src/lib9/create.c b/src/lib9/create.c deleted file mode 100644 index e4e3c715..00000000 --- a/src/lib9/create.c +++ /dev/null @@ -1,75 +0,0 @@ -#define _GNU_SOURCE /* for Linux O_DIRECT */ -#include -#define NOPLAN9DEFINES -#include -#include -#include -#include -#include -#ifndef O_DIRECT -#define O_DIRECT 0 -#endif - -int -p9create(char *path, int mode, ulong perm) -{ - int fd, cexec, umode, rclose, lock, rdwr; - struct flock fl; - - rdwr = mode&3; - lock = mode&OLOCK; - cexec = mode&OCEXEC; - rclose = mode&ORCLOSE; - mode &= ~(ORCLOSE|OCEXEC|OLOCK); - - /* XXX should get mode mask right? */ - fd = -1; - if(perm&DMDIR){ - if(mode != OREAD){ - werrstr("bad mode in directory create"); - goto out; - } - if(mkdir(path, perm&0777) < 0) - goto out; - fd = open(path, O_RDONLY); - }else{ - umode = (mode&3)|O_CREAT|O_TRUNC; - mode &= ~(3|OTRUNC); - if(mode&ODIRECT){ - umode |= O_DIRECT; - mode &= ~ODIRECT; - } - if(mode&OEXCL){ - umode |= O_EXCL; - mode &= ~OEXCL; - } - if(mode&OAPPEND){ - umode |= O_APPEND; - mode &= ~OAPPEND; - } - if(mode){ - werrstr("unsupported mode in create"); - goto out; - } - fd = open(path, umode, perm); - } -out: - if(fd >= 0){ - if(lock){ - fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - if(fcntl(fd, F_SETLK, &fl) < 0){ - close(fd); - werrstr("lock: %r"); - return -1; - } - } - if(cexec) - fcntl(fd, F_SETFL, FD_CLOEXEC); - if(rclose) - remove(path); - } - return fd; -} diff --git a/src/lib9/dirread.c b/src/lib9/dirread.c deleted file mode 100644 index c232eb8d..00000000 --- a/src/lib9/dirread.c +++ /dev/null @@ -1,207 +0,0 @@ -#include -#define NOPLAN9DEFINES -#include -#include -#include - -extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); - -#if defined(__linux__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - off_t off; - int nn; - - /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */ - off = p9seek(fd, 0, 1); - nn = getdirentries(fd, (void*)buf, n, &off); - return nn; -} -#elif defined(__APPLE__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - long off; - return getdirentries(fd, (void*)buf, n, &off); -} -#elif defined(__FreeBSD__) || defined(__DragonFly__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - off_t off; - return getdirentries(fd, (void*)buf, n, &off); -} -#elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - return getdents(fd, (void*)buf, n); -} -#elif defined(__AIX__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - return getdirent(fd, (void*)buf, n); -} -#endif - -#if defined(__DragonFly__) -static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); } -#else -static inline int d_reclen(struct dirent *de) { return de->d_reclen; } -#endif - -static int -countde(char *p, int n) -{ - char *e; - int m; - struct dirent *de; - - e = p+n; - m = 0; - while(p < e){ - de = (struct dirent*)p; - if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e) - break; - if(de->d_name[0]=='.' && de->d_name[1]==0) - de->d_name[0] = 0; - else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0) - de->d_name[0] = 0; - m++; - p += d_reclen(de); - } - return m; -} - -static int -dirpackage(int fd, char *buf, int n, Dir **dp) -{ - int oldwd; - char *p, *str, *estr; - int i, nstr, m; - struct dirent *de; - struct stat st, lst; - Dir *d; - - n = countde(buf, n); - if(n <= 0) - return n; - - if((oldwd = open(".", O_RDONLY)) < 0) - return -1; - if(fchdir(fd) < 0) - return -1; - - p = buf; - nstr = 0; - - for(i=0; id_name[0] == 0) - /* nothing */ {} - else if(lstat(de->d_name, &lst) < 0) - de->d_name[0] = 0; - else{ - st = lst; - if(S_ISLNK(lst.st_mode)) - stat(de->d_name, &st); - nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil); - } - p += d_reclen(de); - } - - d = malloc(sizeof(Dir)*n+nstr); - if(d == nil){ - fchdir(oldwd); - close(oldwd); - return -1; - } - str = (char*)&d[n]; - estr = str+nstr; - - p = buf; - m = 0; - for(i=0; id_name[0] != 0 && lstat(de->d_name, &lst) >= 0){ - st = lst; - if((lst.st_mode&S_IFMT) == S_IFLNK) - stat(de->d_name, &st); - _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr); - } - p += d_reclen(de); - } - - fchdir(oldwd); - close(oldwd); - *dp = d; - return m; -} - -long -dirread(int fd, Dir **dp) -{ - char *buf; - struct stat st; - int n; - - *dp = 0; - - if(fstat(fd, &st) < 0) - return -1; - - if(st.st_blksize < 8192) - st.st_blksize = 8192; - - buf = malloc(st.st_blksize); - if(buf == nil) - return -1; - - n = mygetdents(fd, (void*)buf, st.st_blksize); - if(n < 0){ - free(buf); - return -1; - } - n = dirpackage(fd, buf, n, dp); - free(buf); - return n; -} - - -long -dirreadall(int fd, Dir **d) -{ - uchar *buf, *nbuf; - long n, ts; - struct stat st; - - if(fstat(fd, &st) < 0) - return -1; - - if(st.st_blksize < 8192) - st.st_blksize = 8192; - - buf = nil; - ts = 0; - for(;;){ - nbuf = realloc(buf, ts+st.st_blksize); - if(nbuf == nil){ - free(buf); - return -1; - } - buf = nbuf; - n = mygetdents(fd, (void*)(buf+ts), st.st_blksize); - if(n <= 0) - break; - ts += n; - } - if(ts >= 0) - ts = dirpackage(fd, (char*)buf, ts, d); - free(buf); - if(ts == 0 && n < 0) - return -1; - return ts; -} diff --git a/src/lib9/mkfile b/src/lib9/mkfile index 7c37de42..6fb3d4a7 100644 --- a/src/lib9/mkfile +++ b/src/lib9/mkfile @@ -86,14 +86,12 @@ LIB9OFILES=\ convM2D.$O\ convM2S.$O\ convS2M.$O\ - create.$O\ crypt.$O\ ctime.$O\ dial.$O\ dirfstat.$O\ dirfwstat.$O\ dirmodefmt.$O\ - dirread.$O\ dirstat.$O\ dirwstat.$O\ dup.$O\ diff --git a/src/lib9/open.c b/src/lib9/open.c index a0573ae7..44a4feee 100644 --- a/src/lib9/open.c +++ b/src/lib9/open.c @@ -2,11 +2,79 @@ #include #define NOPLAN9DEFINES #include +#include +#include #include +#include +#include #ifndef O_DIRECT #define O_DIRECT 0 #endif +int +p9create(char *path, int mode, ulong perm) +{ + int fd, cexec, umode, rclose, lock, rdwr; + struct flock fl; + + rdwr = mode&3; + lock = mode&OLOCK; + cexec = mode&OCEXEC; + rclose = mode&ORCLOSE; + mode &= ~(ORCLOSE|OCEXEC|OLOCK); + + /* XXX should get mode mask right? */ + fd = -1; + if(perm&DMDIR){ + if(mode != OREAD){ + werrstr("bad mode in directory create"); + goto out; + } + if(mkdir(path, perm&0777) < 0) + goto out; + fd = open(path, O_RDONLY); + }else{ + umode = (mode&3)|O_CREAT|O_TRUNC; + mode &= ~(3|OTRUNC); + if(mode&ODIRECT){ + umode |= O_DIRECT; + mode &= ~ODIRECT; + } + if(mode&OEXCL){ + umode |= O_EXCL; + mode &= ~OEXCL; + } + if(mode&OAPPEND){ + umode |= O_APPEND; + mode &= ~OAPPEND; + } + if(mode){ + werrstr("unsupported mode in create"); + goto out; + } + fd = open(path, umode, perm); + } +out: + if(fd >= 0){ + if(lock){ + fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + if(fcntl(fd, F_SETLK, &fl) < 0){ + close(fd); + werrstr("lock: %r"); + return -1; + } + } + if(cexec) + fcntl(fd, F_SETFL, FD_CLOEXEC); + if(rclose) + remove(path); + } + return fd; +} + int p9open(char *name, int mode) { @@ -60,3 +128,205 @@ p9open(char *name, int mode) } return fd; } + +extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); + +#if defined(__linux__) +static int +mygetdents(int fd, struct dirent *buf, int n) +{ + off_t off; + int nn; + + /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */ + off = p9seek(fd, 0, 1); + nn = getdirentries(fd, (void*)buf, n, &off); + return nn; +} +#elif defined(__APPLE__) +static int +mygetdents(int fd, struct dirent *buf, int n) +{ + long off; + return getdirentries(fd, (void*)buf, n, &off); +} +#elif defined(__FreeBSD__) || defined(__DragonFly__) +static int +mygetdents(int fd, struct dirent *buf, int n) +{ + off_t off; + return getdirentries(fd, (void*)buf, n, &off); +} +#elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__) +static int +mygetdents(int fd, struct dirent *buf, int n) +{ + return getdents(fd, (void*)buf, n); +} +#elif defined(__AIX__) +static int +mygetdents(int fd, struct dirent *buf, int n) +{ + return getdirent(fd, (void*)buf, n); +} +#endif + +#if defined(__DragonFly__) +static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); } +#else +static inline int d_reclen(struct dirent *de) { return de->d_reclen; } +#endif + +static int +countde(char *p, int n) +{ + char *e; + int m; + struct dirent *de; + + e = p+n; + m = 0; + while(p < e){ + de = (struct dirent*)p; + if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e) + break; + if(de->d_name[0]=='.' && de->d_name[1]==0) + de->d_name[0] = 0; + else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0) + de->d_name[0] = 0; + m++; + p += d_reclen(de); + } + return m; +} + +static int +dirpackage(int fd, char *buf, int n, Dir **dp) +{ + int oldwd; + char *p, *str, *estr; + int i, nstr, m; + struct dirent *de; + struct stat st, lst; + Dir *d; + + n = countde(buf, n); + if(n <= 0) + return n; + + if((oldwd = open(".", O_RDONLY)) < 0) + return -1; + if(fchdir(fd) < 0) + return -1; + + p = buf; + nstr = 0; + + for(i=0; id_name[0] == 0) + /* nothing */ {} + else if(lstat(de->d_name, &lst) < 0) + de->d_name[0] = 0; + else{ + st = lst; + if(S_ISLNK(lst.st_mode)) + stat(de->d_name, &st); + nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil); + } + p += d_reclen(de); + } + + d = malloc(sizeof(Dir)*n+nstr); + if(d == nil){ + fchdir(oldwd); + close(oldwd); + return -1; + } + str = (char*)&d[n]; + estr = str+nstr; + + p = buf; + m = 0; + for(i=0; id_name[0] != 0 && lstat(de->d_name, &lst) >= 0){ + st = lst; + if((lst.st_mode&S_IFMT) == S_IFLNK) + stat(de->d_name, &st); + _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr); + } + p += d_reclen(de); + } + + fchdir(oldwd); + close(oldwd); + *dp = d; + return m; +} + +long +dirread(int fd, Dir **dp) +{ + char *buf; + struct stat st; + int n; + + *dp = 0; + + if(fstat(fd, &st) < 0) + return -1; + + if(st.st_blksize < 8192) + st.st_blksize = 8192; + + buf = malloc(st.st_blksize); + if(buf == nil) + return -1; + + n = mygetdents(fd, (void*)buf, st.st_blksize); + if(n < 0){ + free(buf); + return -1; + } + n = dirpackage(fd, buf, n, dp); + free(buf); + return n; +} + + +long +dirreadall(int fd, Dir **d) +{ + uchar *buf, *nbuf; + long n, ts; + struct stat st; + + if(fstat(fd, &st) < 0) + return -1; + + if(st.st_blksize < 8192) + st.st_blksize = 8192; + + buf = nil; + ts = 0; + for(;;){ + nbuf = realloc(buf, ts+st.st_blksize); + if(nbuf == nil){ + free(buf); + return -1; + } + buf = nbuf; + n = mygetdents(fd, (void*)(buf+ts), st.st_blksize); + if(n <= 0) + break; + ts += n; + } + if(ts >= 0) + ts = dirpackage(fd, (char*)buf, ts, d); + free(buf); + if(ts == 0 && n < 0) + return -1; + return ts; +} diff --git a/src/mkmk.sh b/src/mkmk.sh index 0d52d3f9..8094c3ea 100644 --- a/src/mkmk.sh +++ b/src/mkmk.sh @@ -20,14 +20,12 @@ echo cd `pwd` 9c convM2D.c 9c convM2S.c 9c convS2M.c -9c create.c 9c crypt.c 9c ctime.c 9c dial.c 9c dirfstat.c 9c dirfwstat.c 9c dirmodefmt.c -9c dirread.c 9c dirstat.c 9c dirwstat.c 9c dup.c @@ -109,6 +107,7 @@ echo cd `pwd` 9c -Ifmt fmt/fmtstr.c 9c -Ifmt fmt/fmtvprint.c 9c -Ifmt fmt/fprint.c +9c frexp.c 9c -Ifmt fmt/nan64.c 9c -Ifmt fmt/print.c 9c -Ifmt fmt/runefmtstr.c @@ -150,7 +149,7 @@ echo cd `pwd` 9c utf/utfrrune.c 9c utf/utfrune.c 9c utf/utfutf.c -9ar rsc $PLAN9/lib/lib9.a _exits.o _p9dialparse.o _p9dir.o announce.o argv0.o atexit.o atoi.o atol.o atoll.o atnotify.o await.o cistrcmp.o cistrncmp.o cistrstr.o cleanname.o convD2M.o convM2D.o convM2S.o convS2M.o create.o crypt.o ctime.o dial.o dirfstat.o dirfwstat.o dirmodefmt.o dirread.o dirstat.o dirwstat.o dup.o encodefmt.o errstr.o exec.o execl.o exitcode.o fcallfmt.o frand.o get9root.o getcallerpc.o getenv.o getfields.o getnetconn.o getns.o getuser.o getwd.o jmp.o lrand.o lnrand.o main.o malloc.o malloctag.o mallocz.o nan.o needsrcquote.o needstack.o netcrypt.o netmkaddr.o notify.o nrand.o nulldir.o open.o opentemp.o pin.o pipe.o post9p.o postnote.o qlock.o quote.o rand.o read9pmsg.o readcons.o readn.o rfork.o searchpath.o seek.o sendfd.o sleep.o strdup.o strecpy.o sysfatal.o syslog.o sysname.o time.o tm2sec.o tokenize.o truerand.o u16.o u32.o u64.o unsharp.o wait.o waitpid.o write.o zoneinfo.o dofmt.o fltfmt.o fmt.o fmtfd.o fmtfdflush.o fmtlocale.o fmtlock2.o fmtnull.o fmtprint.o fmtquote.o fmtrune.o fmtstr.o fmtvprint.o fprint.o nan64.o print.o runefmtstr.o runeseprint.o runesmprint.o runesnprint.o runesprint.o runevseprint.o runevsmprint.o runevsnprint.o seprint.o smprint.o snprint.o sprint.o strtod.o vfprint.o vseprint.o vsmprint.o vsnprint.o charstod.o pow10.o rune.o runestrcat.o runestrchr.o runestrcmp.o runestrcpy.o runestrdup.o runestrlen.o runestrecpy.o runestrncat.o runestrncmp.o runestrncpy.o runestrrchr.o runestrstr.o runetype.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o utfutf.o +9ar rsc $PLAN9/lib/lib9.a _exits.o _p9dialparse.o _p9dir.o announce.o argv0.o atexit.o atoi.o atol.o atoll.o atnotify.o await.o cistrcmp.o cistrncmp.o cistrstr.o cleanname.o convD2M.o convM2D.o convM2S.o convS2M.o crypt.o ctime.o dial.o dirfstat.o dirfwstat.o dirmodefmt.o dirstat.o dirwstat.o dup.o encodefmt.o errstr.o exec.o execl.o exitcode.o fcallfmt.o frand.o get9root.o getcallerpc.o getenv.o getfields.o getnetconn.o getns.o getuser.o getwd.o jmp.o lrand.o lnrand.o main.o malloc.o malloctag.o mallocz.o nan.o needsrcquote.o needstack.o netcrypt.o netmkaddr.o notify.o nrand.o nulldir.o open.o opentemp.o pin.o pipe.o post9p.o postnote.o qlock.o quote.o rand.o read9pmsg.o readcons.o readn.o rfork.o searchpath.o seek.o sendfd.o sleep.o strdup.o strecpy.o sysfatal.o syslog.o sysname.o time.o tm2sec.o tokenize.o truerand.o u16.o u32.o u64.o unsharp.o wait.o waitpid.o write.o zoneinfo.o dofmt.o fltfmt.o fmt.o fmtfd.o fmtfdflush.o fmtlocale.o fmtlock2.o fmtnull.o fmtprint.o fmtquote.o fmtrune.o fmtstr.o fmtvprint.o fprint.o frexp.o nan64.o print.o runefmtstr.o runeseprint.o runesmprint.o runesnprint.o runesprint.o runevseprint.o runevsmprint.o runevsnprint.o seprint.o smprint.o snprint.o sprint.o strtod.o vfprint.o vseprint.o vsmprint.o vsnprint.o charstod.o pow10.o rune.o runestrcat.o runestrchr.o runestrcmp.o runestrcpy.o runestrdup.o runestrlen.o runestrecpy.o runestrncat.o runestrncmp.o runestrncpy.o runestrrchr.o runestrstr.o runetype.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o utfutf.o cd .. cd libbio echo cd `pwd` @@ -211,9 +210,5 @@ echo cd `pwd` 9c word.c 9c unix.c 9l -o o.mk arc.o archive.o bufblock.o env.o file.o graph.o job.o lex.o main.o match.o mk.o parse.o recipe.o rc.o rule.o run.o sh.o shell.o shprint.o symtab.o var.o varsub.o word.o unix.o -if [ `uname` = AIX ]; then - installbsd o.mk $PLAN9/bin/mk -else - install o.mk $PLAN9/bin/mk -fi +install o.mk $PLAN9/bin/mk cd .. -- cgit v1.2.3 From 6fd4e901ce48f2e056c505c81320f786175588ff Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 12:37:11 -0400 Subject: lib9: add close More preparation for opendir. --- include/libc.h | 4 +++- src/lib9/open.c | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/libc.h b/include/libc.h index 4fa86b22..7b4c3813 100644 --- a/include/libc.h +++ b/include/libc.h @@ -747,7 +747,7 @@ extern int awaitnohang(char*, int); /* extern int bind(char*, char*, int); give up */ /* extern int brk(void*); */ extern int p9chdir(char*); -extern int close(int); +extern int p9close(int); extern int p9create(char*, int, ulong); extern int p9dup(int, int); extern int errstr(char*, uint); @@ -822,6 +822,8 @@ extern ulong rendezvous(ulong, ulong); #define create p9create #undef open #define open p9open +#undef close +#define close p9close #define pipe p9pipe #define waitfor p9waitfor #define write p9write diff --git a/src/lib9/open.c b/src/lib9/open.c index 44a4feee..43910694 100644 --- a/src/lib9/open.c +++ b/src/lib9/open.c @@ -129,6 +129,13 @@ p9open(char *name, int mode) return fd; } +int +p9close(int fd) +{ + return close(fd); +} + + extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); #if defined(__linux__) -- cgit v1.2.3 From 16f60479e16e3714b376e633c6b902a32e0607ea Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 12:38:32 -0400 Subject: lib9: move seek into open.c More preparation for opendir. --- src/lib9/mkfile | 1 - src/lib9/open.c | 7 ++++++- src/lib9/seek.c | 8 -------- src/mkmk.sh | 3 +-- 4 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 src/lib9/seek.c diff --git a/src/lib9/mkfile b/src/lib9/mkfile index 6fb3d4a7..db267dfe 100644 --- a/src/lib9/mkfile +++ b/src/lib9/mkfile @@ -139,7 +139,6 @@ LIB9OFILES=\ readn.$O\ rfork.$O\ searchpath.$O\ - seek.$O\ sendfd.$O\ sleep.$O\ strdup.$O\ diff --git a/src/lib9/open.c b/src/lib9/open.c index 43910694..ffee7931 100644 --- a/src/lib9/open.c +++ b/src/lib9/open.c @@ -129,13 +129,18 @@ p9open(char *name, int mode) return fd; } +vlong +p9seek(int fd, vlong offset, int whence) +{ + return lseek(fd, offset, whence); +} + int p9close(int fd) { return close(fd); } - extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); #if defined(__linux__) diff --git a/src/lib9/seek.c b/src/lib9/seek.c deleted file mode 100644 index b626355f..00000000 --- a/src/lib9/seek.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -vlong -seek(int fd, vlong offset, int whence) -{ - return lseek(fd, offset, whence); -} diff --git a/src/mkmk.sh b/src/mkmk.sh index 8094c3ea..89c311f3 100644 --- a/src/mkmk.sh +++ b/src/mkmk.sh @@ -73,7 +73,6 @@ echo cd `pwd` 9c readn.c 9c rfork.c 9c searchpath.c -9c seek.c 9c sendfd.c 9c sleep.c 9c strdup.c @@ -149,7 +148,7 @@ echo cd `pwd` 9c utf/utfrrune.c 9c utf/utfrune.c 9c utf/utfutf.c -9ar rsc $PLAN9/lib/lib9.a _exits.o _p9dialparse.o _p9dir.o announce.o argv0.o atexit.o atoi.o atol.o atoll.o atnotify.o await.o cistrcmp.o cistrncmp.o cistrstr.o cleanname.o convD2M.o convM2D.o convM2S.o convS2M.o crypt.o ctime.o dial.o dirfstat.o dirfwstat.o dirmodefmt.o dirstat.o dirwstat.o dup.o encodefmt.o errstr.o exec.o execl.o exitcode.o fcallfmt.o frand.o get9root.o getcallerpc.o getenv.o getfields.o getnetconn.o getns.o getuser.o getwd.o jmp.o lrand.o lnrand.o main.o malloc.o malloctag.o mallocz.o nan.o needsrcquote.o needstack.o netcrypt.o netmkaddr.o notify.o nrand.o nulldir.o open.o opentemp.o pin.o pipe.o post9p.o postnote.o qlock.o quote.o rand.o read9pmsg.o readcons.o readn.o rfork.o searchpath.o seek.o sendfd.o sleep.o strdup.o strecpy.o sysfatal.o syslog.o sysname.o time.o tm2sec.o tokenize.o truerand.o u16.o u32.o u64.o unsharp.o wait.o waitpid.o write.o zoneinfo.o dofmt.o fltfmt.o fmt.o fmtfd.o fmtfdflush.o fmtlocale.o fmtlock2.o fmtnull.o fmtprint.o fmtquote.o fmtrune.o fmtstr.o fmtvprint.o fprint.o frexp.o nan64.o print.o runefmtstr.o runeseprint.o runesmprint.o runesnprint.o runesprint.o runevseprint.o runevsmprint.o runevsnprint.o seprint.o smprint.o snprint.o sprint.o strtod.o vfprint.o vseprint.o vsmprint.o vsnprint.o charstod.o pow10.o rune.o runestrcat.o runestrchr.o runestrcmp.o runestrcpy.o runestrdup.o runestrlen.o runestrecpy.o runestrncat.o runestrncmp.o runestrncpy.o runestrrchr.o runestrstr.o runetype.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o utfutf.o +9ar rsc $PLAN9/lib/lib9.a _exits.o _p9dialparse.o _p9dir.o announce.o argv0.o atexit.o atoi.o atol.o atoll.o atnotify.o await.o cistrcmp.o cistrncmp.o cistrstr.o cleanname.o convD2M.o convM2D.o convM2S.o convS2M.o crypt.o ctime.o dial.o dirfstat.o dirfwstat.o dirmodefmt.o dirstat.o dirwstat.o dup.o encodefmt.o errstr.o exec.o execl.o exitcode.o fcallfmt.o frand.o get9root.o getcallerpc.o getenv.o getfields.o getnetconn.o getns.o getuser.o getwd.o jmp.o lrand.o lnrand.o main.o malloc.o malloctag.o mallocz.o nan.o needsrcquote.o needstack.o netcrypt.o netmkaddr.o notify.o nrand.o nulldir.o open.o opentemp.o pin.o pipe.o post9p.o postnote.o qlock.o quote.o rand.o read9pmsg.o readcons.o readn.o rfork.o searchpath.o sendfd.o sleep.o strdup.o strecpy.o sysfatal.o syslog.o sysname.o time.o tm2sec.o tokenize.o truerand.o u16.o u32.o u64.o unsharp.o wait.o waitpid.o write.o zoneinfo.o dofmt.o fltfmt.o fmt.o fmtfd.o fmtfdflush.o fmtlocale.o fmtlock2.o fmtnull.o fmtprint.o fmtquote.o fmtrune.o fmtstr.o fmtvprint.o fprint.o frexp.o nan64.o print.o runefmtstr.o runeseprint.o runesmprint.o runesnprint.o runesprint.o runevseprint.o runevsmprint.o runevsnprint.o seprint.o smprint.o snprint.o sprint.o strtod.o vfprint.o vseprint.o vsmprint.o vsnprint.o charstod.o pow10.o rune.o runestrcat.o runestrchr.o runestrcmp.o runestrcpy.o runestrdup.o runestrlen.o runestrecpy.o runestrncat.o runestrncmp.o runestrncpy.o runestrrchr.o runestrstr.o runetype.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o utfutf.o cd .. cd libbio echo cd `pwd` -- cgit v1.2.3 From 8cb7308f3a24249ed091c7decf22005c64099783 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 20:02:07 -0400 Subject: lib9: use opendir/readdir to read directories getdirentries(2) has been deprecated on macOS since 10.5 (ten releases ago). Using it requires disabling 64-bit inodes, but that in turn makes binaries incompatible with some dynamic libraries, most notably ASAN. At some point getdirentries(2) will actually be removed. For both these reasons, switch to opendir/readdir. A little clunky since we have to keep the DIR* hidden away to preserve the int fd interfaces, but it lets us remove a bunch of OS-specific code too. --- include/u.h | 3 - src/lib9/open.c | 370 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 187 insertions(+), 186 deletions(-) diff --git a/include/u.h b/include/u.h index 10fc7257..297df70a 100644 --- a/include/u.h +++ b/include/u.h @@ -39,9 +39,6 @@ extern "C" { # define _ALL_SOURCE # undef HAS_SYS_TERMIOS #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/src/lib9/open.c b/src/lib9/open.c index ffee7931..65ea99ec 100644 --- a/src/lib9/open.c +++ b/src/lib9/open.c @@ -1,15 +1,76 @@ #define _GNU_SOURCE /* for Linux O_DIRECT */ #include -#define NOPLAN9DEFINES +#include +#include #include -#include -#include -#include #include -#include -#ifndef O_DIRECT -#define O_DIRECT 0 -#endif +#define NOPLAN9DEFINES +#include + +static struct { + Lock lk; + DIR **d; + int nd; +} dirs; + +static int +dirput(int fd, DIR *d) +{ + int i, nd; + DIR **dp; + + if(fd < 0) { + werrstr("invalid fd"); + return -1; + } + lock(&dirs.lk); + if(fd >= dirs.nd) { + nd = dirs.nd*2; + if(nd <= fd) + nd = fd+1; + dp = realloc(dirs.d, nd*sizeof dirs.d[0]); + if(dp == nil) { + werrstr("out of memory"); + unlock(&dirs.lk); + return -1; + } + for(i=dirs.nd; i= 0 && S_ISDIR(st.st_mode)) { + d = fdopendir(fd); + if(d == nil) { + close(fd); + return -1; + } + if(dirput(fd, d) < 0) { + closedir(d); + return -1; + } + } if(rclose) remove(name); } @@ -132,213 +206,143 @@ p9open(char *name, int mode) vlong p9seek(int fd, vlong offset, int whence) { + DIR *d; + + if((d = dirget(fd)) != nil) { + if(whence == 1 && offset == 0) + return telldir(d); + if(whence == 0) { + seekdir(d, offset); + return 0; + } + werrstr("bad seek in directory"); + return -1; + } + return lseek(fd, offset, whence); } int p9close(int fd) { + DIR *d; + + if((d = dirdel(fd)) != nil) + return closedir(d); return close(fd); } -extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); - -#if defined(__linux__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - off_t off; - int nn; - - /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */ - off = p9seek(fd, 0, 1); - nn = getdirentries(fd, (void*)buf, n, &off); - return nn; -} -#elif defined(__APPLE__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - long off; - return getdirentries(fd, (void*)buf, n, &off); -} -#elif defined(__FreeBSD__) || defined(__DragonFly__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - off_t off; - return getdirentries(fd, (void*)buf, n, &off); -} -#elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - return getdents(fd, (void*)buf, n); -} -#elif defined(__AIX__) -static int -mygetdents(int fd, struct dirent *buf, int n) -{ - return getdirent(fd, (void*)buf, n); -} -#endif +typedef struct DirBuild DirBuild; +struct DirBuild { + Dir *d; + int nd; + int md; + char *str; + char *estr; +}; -#if defined(__DragonFly__) -static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); } -#else -static inline int d_reclen(struct dirent *de) { return de->d_reclen; } -#endif +extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*); static int -countde(char *p, int n) +dirbuild1(DirBuild *b, struct stat *lst, struct stat *st, char *name) { - char *e; - int m; - struct dirent *de; - - e = p+n; - m = 0; - while(p < e){ - de = (struct dirent*)p; - if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e) - break; - if(de->d_name[0]=='.' && de->d_name[1]==0) - de->d_name[0] = 0; - else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0) - de->d_name[0] = 0; - m++; - p += d_reclen(de); + int i, nstr; + Dir *d; + int md, mstr; + char *lo, *hi, *newlo; + + nstr = _p9dir(lst, st, name, nil, nil, nil); + if(b->md-b->nd < 1 || b->estr-b->str < nstr) { + // expand either d space or str space or both. + md = b->md; + if(b->md-b->nd < 1) { + md *= 2; + if(md < 16) + md = 16; + } + mstr = b->estr-(char*)&b->d[b->md]; + if(b->estr-b->str < nstr) { + mstr += nstr; + mstr += mstr/2; + } + if(mstr < 512) + mstr = 512; + d = realloc(b->d, md*sizeof d[0] + mstr); + if(d == nil) + return -1; + // move strings and update pointers in Dirs + lo = (char*)&b->d[b->md]; + newlo = (char*)&d[md]; + hi = b->str; + memmove(newlo, lo+((char*)d-(char*)b->d), hi-lo); + for(i=0; ind; i++) { + if(lo <= d[i].name && d[i].name < hi) + d[i].name += newlo - lo; + if(lo <= d[i].uid && d[i].uid < hi) + d[i].uid += newlo - lo; + if(lo <= d[i].gid && d[i].gid < hi) + d[i].gid += newlo - lo; + if(lo <= d[i].muid && d[i].muid < hi) + d[i].muid += newlo - lo; + } + b->d = d; + b->md = md; + b->str += newlo - lo; + b->estr = newlo + mstr; } - return m; + _p9dir(lst, st, name, &b->d[b->nd], &b->str, b->estr); + b->nd++; + return 0; } -static int -dirpackage(int fd, char *buf, int n, Dir **dp) +static long +dirreadmax(int fd, Dir **dp, int max) { - int oldwd; - char *p, *str, *estr; - int i, nstr, m; + int i; + DIR *dir; + DirBuild b; struct dirent *de; struct stat st, lst; - Dir *d; - - n = countde(buf, n); - if(n <= 0) - return n; - - if((oldwd = open(".", O_RDONLY)) < 0) - return -1; - if(fchdir(fd) < 0) - return -1; - - p = buf; - nstr = 0; - - for(i=0; id_name[0] == 0) - /* nothing */ {} - else if(lstat(de->d_name, &lst) < 0) - de->d_name[0] = 0; - else{ - st = lst; - if(S_ISLNK(lst.st_mode)) - stat(de->d_name, &st); - nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil); - } - p += d_reclen(de); - } - d = malloc(sizeof(Dir)*n+nstr); - if(d == nil){ - fchdir(oldwd); - close(oldwd); + if((dir = dirget(fd)) == nil) { + werrstr("not a directory"); return -1; } - str = (char*)&d[n]; - estr = str+nstr; - p = buf; - m = 0; - for(i=0; id_name[0] != 0 && lstat(de->d_name, &lst) >= 0){ - st = lst; - if((lst.st_mode&S_IFMT) == S_IFLNK) - stat(de->d_name, &st); - _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr); + memset(&b, 0, sizeof b); + for(i=0; max == -1 || id_name[de->d_namlen] != 0) + sysfatal("bad readdir"); + if(de->d_name[0]=='.' && de->d_name[1]==0) + continue; + if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0) + continue; + if(fstatat(fd, de->d_name, &lst, AT_SYMLINK_NOFOLLOW) < 0) + continue; + st = lst; + if(S_ISLNK(lst.st_mode)) + fstatat(fd, de->d_name, &st, 0); + dirbuild1(&b, &lst, &st, de->d_name); } - - fchdir(oldwd); - close(oldwd); - *dp = d; - return m; + *dp = b.d; + return b.nd; } long dirread(int fd, Dir **dp) { - char *buf; - struct stat st; - int n; - - *dp = 0; - - if(fstat(fd, &st) < 0) - return -1; - - if(st.st_blksize < 8192) - st.st_blksize = 8192; - - buf = malloc(st.st_blksize); - if(buf == nil) - return -1; - - n = mygetdents(fd, (void*)buf, st.st_blksize); - if(n < 0){ - free(buf); - return -1; - } - n = dirpackage(fd, buf, n, dp); - free(buf); - return n; + return dirreadmax(fd, dp, 10); } - long -dirreadall(int fd, Dir **d) +dirreadall(int fd, Dir **dp) { - uchar *buf, *nbuf; - long n, ts; - struct stat st; - - if(fstat(fd, &st) < 0) - return -1; - - if(st.st_blksize < 8192) - st.st_blksize = 8192; - - buf = nil; - ts = 0; - for(;;){ - nbuf = realloc(buf, ts+st.st_blksize); - if(nbuf == nil){ - free(buf); - return -1; - } - buf = nbuf; - n = mygetdents(fd, (void*)(buf+ts), st.st_blksize); - if(n <= 0) - break; - ts += n; - } - if(ts >= 0) - ts = dirpackage(fd, (char*)buf, ts, d); - free(buf); - if(ts == 0 && n < 0) - return -1; - return ts; + return dirreadmax(fd, dp, -1); } -- cgit v1.2.3 From 154140a22b1c697f6a3edb3e5913efded1be082a Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 20:06:31 -0400 Subject: mk: replace overlapping strcpy with memmove Found by ASAN. --- src/cmd/mk/env.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cmd/mk/env.c b/src/cmd/mk/env.c index d7c6481d..e01aa21a 100644 --- a/src/cmd/mk/env.c +++ b/src/cmd/mk/env.c @@ -123,7 +123,8 @@ buildenv(Job *j, int slot) qp = strchr(cp+1, ')'); if(qp){ *qp = 0; - strcpy(w->s, cp+1); + /* strcpy, but might overlap */ + memmove(w->s, cp+1, strlen(cp+1)+1); l = &w->next; w = w->next; continue; -- cgit v1.2.3 From 9444b8e4bc847f8fd9d02466976b962288cedf31 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 20:07:52 -0400 Subject: 9c, 9l: accept CC9FLAGS from config Also, if CC9FLAGS includes -fsanitize=address (ASAN), predefine PLAN9PORT_ASAN for use by programs that need to know (mainly libthread). The 9c script used to have a variable called ngflags, which was ccflags except -g (ng stood for "no g"), but nothing needs it split out anymore, so simplify to just ccflags. --- bin/9c | 34 +++++++++++++++++++++++----------- bin/9l | 14 +++++++------- man/man1/install.1 | 9 +++++++++ 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/bin/9c b/bin/9c index 320a1634..dd899293 100755 --- a/bin/9c +++ b/bin/9c @@ -4,7 +4,7 @@ test -f $PLAN9/config && . $PLAN9/config usegcc() { cc=${CC9:-gcc} - ngflags=" \ + cflags=" \ -O2 \ -c \ -Wall \ @@ -24,7 +24,12 @@ usegcc() " # want to put -fno-optimize-sibling-calls here but # that option only works with gcc3+ it seems - cflags="$ngflags -ggdb" + cflags="$cflags -ggdb" + cflags="$cflags $CC9FLAGS" + case "$cflags" in + *sanitize=address*) + cflags="$cflags -DPLAN9PORT_ASAN" + esac } quiet() @@ -60,7 +65,7 @@ quiet() useclang() { cc=${CC9:-clang} - ngflags=" \ + cflags=" \ -O2 \ -c \ -Wall \ @@ -79,13 +84,19 @@ useclang() -fsigned-char \ -fno-caret-diagnostics \ " - cflags="$ngflags -g" + cflags="$cflags -g" + cflags="$cflags $CC9FLAGS" + + case "$cflags" in + *sanitize=address*) + cflags="$cflags -DPLAN9PORT_ASAN" + esac } usexlc() { cc=${CC9:-xlc_r} - ngflags=" \ + cflags=" \ -c \ -O0 \ -qmaxmem=-1 \ @@ -96,7 +107,8 @@ usexlc() -qsuppress=1506-1300 \ -qsuppress=1506-342 \ " - cflags="$ngflags -g -qfullpath" + cflags="$cflags -g -qfullpath" + cflags="$cflags $CC9FLAGS" } tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}-${CC9:-cc}" @@ -105,14 +117,14 @@ case "$tag" in *DragonFly*clang|*BSD*clang*) useclang ;; *Darwin-x86_64*) useclang - cflags="$ngflags -g3 -m64" + cflags="$cflags -g3 -m64" ;; *Darwin*clang*) useclang - cflags="$ngflags -g3 -m32" + cflags="$cflags -g3 -m32" ;; *Darwin*) usegcc - cflags="$ngflags -g3 -no-cpp-precomp -m32" ;; + cflags="$cflags -g3 -no-cpp-precomp -m32" ;; *HP-UX*) cc=${CC9:-cc}; cflags="-g -O -c -Ae" ;; *Linux*) usegcc case "${CC9:-gcc}" in @@ -134,11 +146,11 @@ case "$tag" in u=`uname` v=`uname -r` s=`echo $u$v | tr '. ' '__'` - cflags="$ngflags -g" + cflags="$cflags -g" cflags="$cflags -D__sun__ -D__${s}__" ;; *AIX*) usexlc - cflags="$ngflags -g -D__AIX__" + cflags="$cflags -g -D__AIX__" ;; *) echo 9c does not know how to compile on "$tag" 1>&2 diff --git a/bin/9l b/bin/9l index 398adbd8..875e103a 100755 --- a/bin/9l +++ b/bin/9l @@ -12,29 +12,29 @@ extralibs="-lm" tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}" case "$tag" in *DragonFly*|*BSD*) - ld=${CC9:-gcc} + ld="${CC9:-gcc} $CC9FLAGS" userpath=true extralibs="$extralibs -lutil" ;; *OSF1*) - ld=${CC9:-cc} + ld="${CC9:-cc} $CC9FLAGS" userpath=true extralibs="$extralibs -lutil" nmflags="-B" ;; *Linux*) - ld=${CC9:-gcc} + ld="${CC9:-gcc} $CC9FLAGS" userpath=true extralibs="$extralibs -lutil -lresolv -lpthread" ;; *Darwin*x86_64*) - ld="${CC9:-gcc} -m64" + ld="${CC9:-gcc} -m64 $CC9FLAGS" ;; *Darwin*) - ld="${CC9:-gcc} -m32" + ld="${CC9:-gcc} -m32 $CC9FLAGS" ;; *SunOS*) - ld="${CC9:-cc} -g" + ld="${CC9:-cc} -g $CC9FLAGS" extralibs="$extralibs -lrt -lpthread -lsocket -lnsl" # Record paths to shared libraries to avoid needing LD_LIBRARY_PATH for i in "$libsl $@" @@ -61,7 +61,7 @@ case "$tag" in esac ;; *AIX*) - ld="${CC9:-xlc_r} -g -O0" + ld="${CC9:-xlc_r} -g -O0 $CC9FLAGS" nmflags="-A -B" extralibs="$extralibs -lpthread" ;; diff --git a/man/man1/install.1 b/man/man1/install.1 index 8fcc9e41..17411af2 100644 --- a/man/man1/install.1 +++ b/man/man1/install.1 @@ -89,6 +89,15 @@ If contains a line .B WSYSTYPE=nowsys then the system is built without using X11. +.B LOCAL.config +may also list settings for +.B CC9 +(the host C compiler) +and +.B CC9FLAGS +(any additional flags to pass to the compiler). +Values more complex than single words should be quoted +with single quotes. .PP On most Linux systems, the X11 header packages need to be installed to build using X11. On Debian. the required packages are -- cgit v1.2.3 From 06687f70ba7a5836c2e872648a85a724a5a1d486 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 20:09:43 -0400 Subject: INSTALL: build mk all the time If mk gets into a bad state, it's not obvious that you can remove the binary to force the rebuild. Also, not rebuilding means that bugs in mkmk.sh are not noticed. Just rebuild from scratch every time. It doesn't take too long compared to the rest of INSTALL. --- INSTALL | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index 11d35005..49a4d9a4 100755 --- a/INSTALL +++ b/INSTALL @@ -143,10 +143,9 @@ echo "* Compiler version:" cd src if $dobuild; then - if [ ! -x ../bin/mk ]; then - echo "* Building mk..." - ../dist/buildmk 2>&1 | sed 's/^[+] //' - fi + echo "* Building mk..." + ../dist/buildmk 2>&1 | sed 's/^[+] //' + if [ ! -x ../bin/mk ]; then echo "* Error: mk failed to build." exit 1 -- cgit v1.2.3 From baef953da253314657be9adea8f371bfbf4ba09e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 08:24:54 -0400 Subject: libthread: add pthreadperthread mode and use under ASAN ASAN can't deal with the coroutine stacks. In theory we can call into ASAN runtime to let it know about them, but ASAN still has problems with fork or exit happening from a non-system stack. Bypass all possible problems by just having a full OS thread for each libthread thread. The threads are still cooperatively scheduled within a proc (in thos mode, a group of OS threads). Setting the environment variable LIBTHREAD=pthreadperthread will enable the pthreadperthread mode, as will building with CC9FLAGS='-fsanitize=address' in $PLAN9/config. This solution is much more general than ASAN - for example if you are trying to find all the thread stacks in a reproducible crash you can use pthreadperthread mode with any debugger that knows only about OS threads. --- src/libthread/channel.c | 2 +- src/libthread/pthread.c | 33 ++++++++++++++++++++++ src/libthread/thread.c | 70 ++++++++++++++++++++++++++++++++++++++++++---- src/libthread/threadimpl.h | 33 ++++++++++++++-------- 4 files changed, 120 insertions(+), 18 deletions(-) diff --git a/src/libthread/channel.c b/src/libthread/channel.c index 53af86e6..9efb7a62 100644 --- a/src/libthread/channel.c +++ b/src/libthread/channel.c @@ -141,7 +141,7 @@ altdequeue(Alt *a) delarray(ar, i); return; } - fprint(2, "cannot find self in altdq\n"); + fprint(2, "cannot find self in altdequeue\n"); abort(); } diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index 46bb396a..5e022f0b 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c @@ -99,6 +99,23 @@ startprocfn(void *v) pthread_exit(0); } +static void +startpthreadfn(void *v) +{ + void **a; + Proc *p; + _Thread *t; + + a = (void**)v; + p = a[0]; + t = a[1]; + free(a); + t->osprocid = pthread_self(); + pthread_detach(t->osprocid); + _threadpthreadmain(p, t); + pthread_exit(0); +} + void _procstart(Proc *p, void (*fn)(Proc*)) { @@ -116,6 +133,22 @@ _procstart(Proc *p, void (*fn)(Proc*)) } } +void +_threadpthreadstart(Proc *p, _Thread *t) +{ + void **a; + + a = malloc(3*sizeof a[0]); + if(a == nil) + sysfatal("_pthreadstart malloc: %r"); + a[0] = p; + a[1] = t; + if(pthread_create(&t->osprocid, nil, (void*(*)(void*))startpthreadfn, (void*)a) < 0){ + fprint(2, "pthread_create: %r\n"); + abort(); + } +} + static pthread_key_t prockey; Proc* diff --git a/src/libthread/thread.c b/src/libthread/thread.c index f657b5b2..f579b567 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -7,6 +7,7 @@ static uint threadnsysproc; static Lock threadnproclock; static Ref threadidref; static Proc *threadmainproc; +static int pthreadperthread; static void addproc(Proc*); static void delproc(Proc*); @@ -176,12 +177,16 @@ _threadcreate(Proc *p, void (*fn)(void*), void *arg, uint stack) if(stack < (256<<10)) stack = 256<<10; - if(p->nthread == 0) + if(p->nthread == 0 || pthreadperthread) stack = 0; // not using it t = threadalloc(fn, arg, stack); t->proc = p; - addthreadinproc(p, t); + if(p->nthread == 0) + p->thread0 = t; + else if(pthreadperthread) + _threadpthreadstart(p, t); p->nthread++; + addthreadinproc(p, t); _threadready(t); return t; } @@ -209,6 +214,29 @@ proccreate(void (*fn)(void*), void *arg, uint stack) return id; } +// For pthreadperthread mode, procswitch flips +// between the threads. +static void +procswitch(Proc *p, _Thread *from, _Thread *to) +{ +// fprint(2, "procswitch %p %d %d\n", p, from?from->id:-1, to?to->id:-1); + lock(&p->schedlock); + from->schedrend.l = &p->schedlock; + if(to) { + p->schedthread = to; + to->schedrend.l = &p->schedlock; + _procwakeup(&to->schedrend); + } + if(p->schedthread != from) { + if(from->exiting) { + unlock(&p->schedlock); + _threadpexit(); + } + _procsleep(&from->schedrend); + } + unlock(&p->schedlock); +} + void _threadswitch(void) { @@ -216,9 +244,13 @@ _threadswitch(void) needstack(0); p = proc(); + /*print("threadswtch %p\n", p); */ - if(p->thread->stk == nil) + + if(p->thread == p->thread0) procscheduler(p); + else if(pthreadperthread) + procswitch(p, p->thread, p->thread0); else contextswitch(&p->thread->context, &p->schedcontext); } @@ -346,6 +378,15 @@ procmain(Proc *p) threadexits(nil); } +void +_threadpthreadmain(Proc *p, _Thread *t) +{ + _threadsetproc(p); + procswitch(p, t, nil); + t->startfn(t->startarg); + threadexits(nil); +} + static void procscheduler(Proc *p) { @@ -401,9 +442,12 @@ Top: p->nswitch++; _threaddebug("run %d (%s)", t->id, t->name); //print("run %p %p %p %p\n", t, *(uintptr*)(t->context.uc.mc.sp), t->context.uc.mc.di, t->context.uc.mc.si); - if(t->stk == nil) + if(t == p->thread0) return; - contextswitch(&p->schedcontext, &t->context); + if(pthreadperthread) + procswitch(p, p->thread0, t); + else + contextswitch(&p->schedcontext, &t->context); /*print("back in scheduler\n"); */ goto Top; } @@ -757,10 +801,24 @@ int main(int argc, char **argv) { Proc *p; + char *opts; argv0 = argv[0]; - if(getenv("NOLIBTHREADDAEMONIZE") == nil) + opts = getenv("LIBTHREAD"); + if(opts == nil) + opts = ""; + + pthreadperthread = (strstr(opts, "pthreadperthread") != nil); +#ifdef PLAN9PORT_ASAN + // ASAN can't deal with the coroutine stack switches. + // In theory it has support for informing it about stack switches, + // but even with those calls added it can't deal with things + // like fork or exit from a coroutine stack. + // Easier to just run in pthread-per-thread mode. + pthreadperthread = 1; +#endif + if(strstr(opts, "nodaemon") || getenv("NOLIBTHREADDAEMONIZE") == nil) _threadsetupdaemonize(); threadargc = argc; diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index cceb1b8e..c7373843 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -102,6 +102,17 @@ struct Execjob Channel *c; }; +struct _Procrendez +{ + Lock *l; + int asleep; +#ifdef PLAN9PORT_USING_PTHREADS + pthread_cond_t cond; +#else + int pid; +#endif +}; + struct _Thread { _Thread *next; @@ -112,6 +123,11 @@ struct _Thread void (*startfn)(void*); void *startarg; uint id; +#ifdef PLAN9PORT_USING_PTHREADS + pthread_t osprocid; +#else + int osprocid; +#endif uchar *stk; uint stksize; int exiting; @@ -120,17 +136,7 @@ struct _Thread char state[256]; void *udata; Alt *alt; -}; - -struct _Procrendez -{ - Lock *l; - int asleep; -#ifdef PLAN9PORT_USING_PTHREADS - pthread_cond_t cond; -#else - int pid; -#endif + _Procrendez schedrend; }; extern void _procsleep(_Procrendez*); @@ -149,6 +155,7 @@ struct Proc #endif Lock lock; int nswitch; + _Thread *thread0; _Thread *thread; _Thread *pinthread; _Threadlist runqueue; @@ -157,6 +164,8 @@ struct Proc uint nthread; uint sysproc; _Procrendez runrend; + Lock schedlock; + _Thread *schedthread; Context schedcontext; void *udata; Jmp sigjmp; @@ -188,6 +197,8 @@ extern void _threadpexit(void); extern void _threaddaemonize(void); extern void *_threadstkalloc(int); extern void _threadstkfree(void*, int); +extern void _threadpthreadmain(Proc*, _Thread*); +extern void _threadpthreadstart(Proc*, _Thread*); #define USPALIGN(ucp, align) \ (void*)((((uintptr)(ucp)->uc_stack.ss_sp+(ucp)->uc_stack.ss_size)-(align))&~((align)-1)) -- cgit v1.2.3 From 162d0d5cd94fabab822ac66655be8957151cef99 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 17 May 2020 22:31:38 -0400 Subject: libthread: handle spurious _procsleep wakeups, fix $LIBTHREAD handling --- src/libthread/pthread.c | 4 +++- src/libthread/thread.c | 28 +++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/libthread/pthread.c b/src/libthread/pthread.c index 5e022f0b..35f6ffe3 100644 --- a/src/libthread/pthread.c +++ b/src/libthread/pthread.c @@ -50,13 +50,15 @@ _threadunlock(Lock *lk, ulong pc) abort(); } +/* note: _procsleep can have spurious wakeups, like pthread_cond_wait */ void _procsleep(_Procrendez *r) { /* r is protected by r->l, which we hold */ pthread_cond_init(&r->cond, 0); r->asleep = 1; - pthread_cond_wait(&r->cond, &r->l->mutex); + if(pthread_cond_wait(&r->cond, &r->l->mutex) != 0) + sysfatal("pthread_cond_wait: %r"); pthread_cond_destroy(&r->cond); r->asleep = 0; } diff --git a/src/libthread/thread.c b/src/libthread/thread.c index f579b567..902942d9 100644 --- a/src/libthread/thread.c +++ b/src/libthread/thread.c @@ -54,9 +54,9 @@ _threaddebug(char *fmt, ...) va_end(arg); t = proc()->thread; if(t) - fprint(fd, "%d.%d: %s\n", getpid(), t->id, buf); + fprint(fd, "%p %d.%d: %s\n", proc(), getpid(), t->id, buf); else - fprint(fd, "%d._: %s\n", getpid(), buf); + fprint(fd, "%p %d._: %s\n", proc(), getpid(), buf); } static _Thread* @@ -219,20 +219,28 @@ proccreate(void (*fn)(void*), void *arg, uint stack) static void procswitch(Proc *p, _Thread *from, _Thread *to) { -// fprint(2, "procswitch %p %d %d\n", p, from?from->id:-1, to?to->id:-1); + _threaddebug("procswitch %p %d %d", p, from?from->id:-1, to?to->id:-1); lock(&p->schedlock); from->schedrend.l = &p->schedlock; if(to) { p->schedthread = to; to->schedrend.l = &p->schedlock; + _threaddebug("procswitch wakeup %p %d", p, to->id); _procwakeup(&to->schedrend); } if(p->schedthread != from) { if(from->exiting) { unlock(&p->schedlock); _threadpexit(); + _threaddebug("procswitch exit wakeup!!!\n"); } - _procsleep(&from->schedrend); + while(p->schedthread != from) { + _threaddebug("procswitch sleep %p %d", p, from->id); + _procsleep(&from->schedrend); + _threaddebug("procswitch awake %p %d", p, from->id); + } + if(p->schedthread != from) + sysfatal("_procswitch %p %p oops", p->schedthread, from); } unlock(&p->schedlock); } @@ -448,6 +456,7 @@ Top: procswitch(p, p->thread0, t); else contextswitch(&p->schedcontext, &t->context); + _threaddebug("back in scheduler"); /*print("back in scheduler\n"); */ goto Top; } @@ -589,6 +598,10 @@ threadqlock(QLock *l, int block, ulong pc) if(l->owner == nil){ l->owner = (*threadnow)(); /*print("qlock %p @%#x by %p\n", l, pc, l->owner); */ + if(l->owner == nil) { + fprint(2, "%s: qlock uncontended owner=nil oops\n", argv0); + abort(); + } unlock(&l->l); return 1; } @@ -613,6 +626,11 @@ threadqlock(QLock *l, int block, ulong pc) argv0, pc, l->owner, (*threadnow)()); abort(); } + if(l->owner == nil) { + fprint(2, "%s: qlock threadswitch owner=nil oops\n", argv0); + abort(); + } + /*print("qlock wakeup %p @%#x by %p\n", l, pc, (*threadnow)()); */ return 1; } @@ -818,7 +836,7 @@ main(int argc, char **argv) // Easier to just run in pthread-per-thread mode. pthreadperthread = 1; #endif - if(strstr(opts, "nodaemon") || getenv("NOLIBTHREADDAEMONIZE") == nil) + if(strstr(opts, "nodaemon") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil) _threadsetupdaemonize(); threadargc = argc; -- cgit v1.2.3 From 94d381ec9d579e5336f3817b68cf4d1a8a7333db Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 25 Jan 2020 14:31:52 -0500 Subject: devdraw: use indirect impl interface Setting up for a real window system. --- src/cmd/devdraw/devdraw.c | 4 ++-- src/cmd/devdraw/devdraw.h | 23 ++++++++++++++--------- src/cmd/devdraw/mac-screen.m | 38 ++++++++++++++++++++++++++++++-------- src/cmd/devdraw/srv.c | 26 +++++++++++++++----------- 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c index b4c373ad..6269dfda 100644 --- a/src/cmd/devdraw/devdraw.c +++ b/src/cmd/devdraw/devdraw.c @@ -143,7 +143,7 @@ addflush(Client *c, Rectangle r) // during a resize. rpc_gfxdrawunlock(); qunlock(&c->drawlk); - rpc_flush(c, fr); + c->impl->rpc_flush(c, fr); qlock(&c->drawlk); rpc_gfxdrawlock(); } @@ -188,7 +188,7 @@ drawflush(Client *c) // during a resize. rpc_gfxdrawunlock(); qunlock(&c->drawlk); - rpc_flush(c, r); + c->impl->rpc_flush(c, r); qlock(&c->drawlk); rpc_gfxdrawlock(); } diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h index 6829ab32..1dac2d50 100644 --- a/src/cmd/devdraw/devdraw.h +++ b/src/cmd/devdraw/devdraw.h @@ -7,6 +7,7 @@ typedef struct Mousebuf Mousebuf; typedef struct Tagbuf Tagbuf; typedef struct Client Client; +typedef struct ClientImpl ClientImpl; typedef struct DImage DImage; typedef struct DScreen DScreen; typedef struct CScreen CScreen; @@ -43,6 +44,18 @@ struct Tagbuf int wi; }; +struct ClientImpl +{ + void (*rpc_resizeimg)(Client*); + void (*rpc_resizewindow)(Client*, Rectangle); + void (*rpc_setcursor)(Client*, Cursor*, Cursor2*); + void (*rpc_setlabel)(Client*, char*); + void (*rpc_setmouse)(Client*, Point); + void (*rpc_topwin)(Client*); + void (*rpc_bouncemouse)(Client*, Mouse); + void (*rpc_flush)(Client*, Rectangle); +}; + struct Client { int rfd; @@ -82,6 +95,7 @@ struct Client int nname; DName* name; int namevers; + ClientImpl* impl; // Only accessed/modified by the graphics thread. const void* view; @@ -196,17 +210,8 @@ void gfx_started(void); Memimage *rpc_attach(Client*, char*, char*); char* rpc_getsnarf(void); void rpc_putsnarf(char*); -void rpc_resizeimg(Client*); -void rpc_resizewindow(Client*, Rectangle); -void rpc_serve(Client*); -void rpc_setcursor(Client*, Cursor*, Cursor2*); -void rpc_setlabel(Client*, char*); -void rpc_setmouse(Client*, Point); void rpc_shutdown(void); -void rpc_topwin(Client*); void rpc_main(void); -void rpc_bouncemouse(Client*, Mouse); -void rpc_flush(Client*, Rectangle); // rpc_gfxdrawlock and rpc_gfxdrawunlock // are called around drawing operations to lock and unlock diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m index c6e58341..9454be05 100644 --- a/src/cmd/devdraw/mac-screen.m +++ b/src/cmd/devdraw/mac-screen.m @@ -37,6 +37,27 @@ static void setprocname(const char*); static uint keycvt(uint); static uint msec(void); +static void rpc_resizeimg(Client*); +static void rpc_resizewindow(Client*, Rectangle); +static void rpc_serve(Client*); +static void rpc_setcursor(Client*, Cursor*, Cursor2*); +static void rpc_setlabel(Client*, char*); +static void rpc_setmouse(Client*, Point); +static void rpc_topwin(Client*); +static void rpc_bouncemouse(Client*, Mouse); +static void rpc_flush(Client*, Rectangle); + +static ClientImpl macimpl = { + rpc_resizeimg, + rpc_resizewindow, + rpc_setcursor, + rpc_setlabel, + rpc_setmouse, + rpc_topwin, + rpc_bouncemouse, + rpc_flush +}; + @class DrawView; @class DrawLayer; @@ -201,6 +222,7 @@ rpc_attach(Client *c, char *label, char *winsize) { LOG(@"attachscreen(%s, %s)", label, winsize); + c->impl = &macimpl; dispatch_sync(dispatch_get_main_queue(), ^(void) { @autoreleasepool { DrawView *view = [[DrawView new] attach:c winsize:winsize label:label]; @@ -302,7 +324,7 @@ rpc_attach(Client *c, char *label, char *winsize) // rpc_topwin moves the window to the top of the desktop. // Called from an RPC thread with no client lock held. -void +static void rpc_topwin(Client *c) { DrawView *view = (__bridge DrawView*)c->view; @@ -319,7 +341,7 @@ rpc_topwin(Client *c) // rpc_setlabel updates the client window's label. // If label == nil, the call is a no-op. // Called from an RPC thread with no client lock held. -void +static void rpc_setlabel(Client *client, char *label) { DrawView *view = (__bridge DrawView*)client->view; @@ -344,7 +366,7 @@ rpc_setlabel(Client *client, char *label) // rpc_setcursor updates the client window's cursor image. // Either c and c2 are both non-nil, or they are both nil to use the default arrow. // Called from an RPC thread with no client lock held. -void +static void rpc_setcursor(Client *client, Cursor *c, Cursor2 *c2) { DrawView *view = (__bridge DrawView*)client->view; @@ -460,7 +482,7 @@ rpc_setcursor(Client *client, Cursor *c, Cursor2 *c2) // rpc_flush flushes changes to view.img's rectangle r // to the on-screen window, making them visible. // Called from an RPC thread with no client lock held. -void +static void rpc_flush(Client *client, Rectangle r) { DrawView *view = (__bridge DrawView*)client->view; @@ -506,7 +528,7 @@ rpc_flush(Client *client, Rectangle r) // rpc_resizeimg forces the client window to discard its current window and make a new one. // It is called when the user types Cmd-R to toggle whether retina mode is forced. // Called from an RPC thread with no client lock held. -void +static void rpc_resizeimg(Client *c) { DrawView *view = (__bridge DrawView*)c->view; @@ -541,7 +563,7 @@ rpc_resizeimg(Client *c) // rpc_resizewindow asks for the client window to be resized to size r. // Called from an RPC thread with no client lock held. -void +static void rpc_resizewindow(Client *c, Rectangle r) { DrawView *view = (__bridge DrawView*)c->view; @@ -696,7 +718,7 @@ rpc_resizewindow(Client *c, Rectangle r) // rpc_setmouse moves the mouse cursor. // Called from an RPC thread with no client lock held. -void +static void rpc_setmouse(Client *c, Point p) { DrawView *view = (__bridge DrawView*)c->view; @@ -1095,7 +1117,7 @@ rpc_putsnarf(char *s) // rpc_bouncemouse is for sending a mouse event // back to the X11 window manager rio(1). // Does not apply here. -void +static void rpc_bouncemouse(Client *c, Mouse m) { } diff --git a/src/cmd/devdraw/srv.c b/src/cmd/devdraw/srv.c index 570091bc..bdfc1654 100644 --- a/src/cmd/devdraw/srv.c +++ b/src/cmd/devdraw/srv.c @@ -54,6 +54,7 @@ threadmain(int argc, char **argv) usage(); }ARGEND + memimageinit(); fmtinstall('H', encodefmt); if((p = getenv("DEVDRAWTRACE")) != nil) trace = atoi(p); @@ -202,8 +203,11 @@ runmsg(Client *c, Wsysmsg *m) break; case Tinit: - memimageinit(); i = rpc_attach(c, m->label, m->winsize); + if(i == nil) { + replyerror(c, m); + break; + } draw_initdisplaymemimage(c, i); replymsg(c, m); break; @@ -241,35 +245,35 @@ runmsg(Client *c, Wsysmsg *m) break; case Tmoveto: - rpc_setmouse(c, m->mouse.xy); + c->impl->rpc_setmouse(c, m->mouse.xy); replymsg(c, m); break; case Tcursor: if(m->arrowcursor) - rpc_setcursor(c, nil, nil); + c->impl->rpc_setcursor(c, nil, nil); else { scalecursor(&m->cursor2, &m->cursor); - rpc_setcursor(c, &m->cursor, &m->cursor2); + c->impl->rpc_setcursor(c, &m->cursor, &m->cursor2); } replymsg(c, m); break; case Tcursor2: if(m->arrowcursor) - rpc_setcursor(c, nil, nil); + c->impl->rpc_setcursor(c, nil, nil); else - rpc_setcursor(c, &m->cursor, &m->cursor2); + c->impl->rpc_setcursor(c, &m->cursor, &m->cursor2); replymsg(c, m); break; case Tbouncemouse: - rpc_bouncemouse(c, m->mouse); + c->impl->rpc_bouncemouse(c, m->mouse); replymsg(c, m); break; case Tlabel: - rpc_setlabel(c, m->label); + c->impl->rpc_setlabel(c, m->label); replymsg(c, m); break; @@ -306,12 +310,12 @@ runmsg(Client *c, Wsysmsg *m) break; case Ttop: - rpc_topwin(c); + c->impl->rpc_topwin(c); replymsg(c, m); break; case Tresize: - rpc_resizewindow(c, m->rect); + c->impl->rpc_resizewindow(c, m->rect); replymsg(c, m); break; } @@ -513,7 +517,7 @@ gfx_keystroke(Client *c, int ch) else c->forcedpi = 225; qunlock(&c->eventlk); - rpc_resizeimg(c); + c->impl->rpc_resizeimg(c); return; } if(!c->kbd.alting){ -- cgit v1.2.3 From 587933c16132d880a06ff99bd087e64a3a04975e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 25 Jan 2020 14:33:20 -0500 Subject: devdraw: use global drawlk instead of per-client Setting up for a real window system. --- src/cmd/devdraw/devdraw.c | 26 ++++++++++++++------------ src/cmd/devdraw/devdraw.h | 5 +++-- src/cmd/devdraw/mac-screen.m | 7 +++---- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c index 6269dfda..234cdf1b 100644 --- a/src/cmd/devdraw/devdraw.c +++ b/src/cmd/devdraw/devdraw.c @@ -14,6 +14,8 @@ #include #include "devdraw.h" +QLock drawlk; + static int drawuninstall(Client*, int); static Memimage* drawinstall(Client*, int, Memimage*, DScreen*); static void drawfreedimage(Client*, DImage*); @@ -47,14 +49,14 @@ gfx_replacescreenimage(Client *c, Memimage *m) */ Memimage *om; - qlock(&c->drawlk); + qlock(&drawlk); om = c->screenimage; c->screenimage = m; m->screenref = 1; if(om && --om->screenref == 0){ _freememimage(om); } - qunlock(&c->drawlk); + qunlock(&drawlk); gfx_mouseresized(c); } @@ -142,9 +144,9 @@ addflush(Client *c, Rectangle r) // and gfx thread might be blocked on drawlk trying to install a new screen // during a resize. rpc_gfxdrawunlock(); - qunlock(&c->drawlk); + qunlock(&drawlk); c->impl->rpc_flush(c, fr); - qlock(&c->drawlk); + qlock(&drawlk); rpc_gfxdrawlock(); } } @@ -187,9 +189,9 @@ drawflush(Client *c) // and gfx thread might be blocked on drawlk trying to install a new screen // during a resize. rpc_gfxdrawunlock(); - qunlock(&c->drawlk); + qunlock(&drawlk); c->impl->rpc_flush(c, r); - qlock(&c->drawlk); + qlock(&drawlk); rpc_gfxdrawlock(); } } @@ -614,7 +616,7 @@ drawcoord(uchar *p, uchar *maxp, int oldx, int *newx) int draw_dataread(Client *cl, void *a, int n) { - qlock(&cl->drawlk); + qlock(&drawlk); if(cl->readdata == nil){ werrstr("no draw data"); goto err; @@ -627,11 +629,11 @@ draw_dataread(Client *cl, void *a, int n) memmove(a, cl->readdata, cl->nreaddata); free(cl->readdata); cl->readdata = nil; - qunlock(&cl->drawlk); + qunlock(&drawlk); return n; err: - qunlock(&cl->drawlk); + qunlock(&drawlk); return -1; } @@ -656,7 +658,7 @@ draw_datawrite(Client *client, void *v, int n) Refreshfn reffn; Refx *refx; - qlock(&client->drawlk); + qlock(&drawlk); rpc_gfxdrawlock(); a = v; m = 0; @@ -1431,7 +1433,7 @@ draw_datawrite(Client *client, void *v, int n) } } rpc_gfxdrawunlock(); - qunlock(&client->drawlk); + qunlock(&drawlk); return oldn - n; Enodrawimage: @@ -1502,6 +1504,6 @@ Ebadarg: error: werrstr("%s", err); rpc_gfxdrawunlock(); - qunlock(&client->drawlk); + qunlock(&drawlk); return -1; } diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h index 1dac2d50..261d04d1 100644 --- a/src/cmd/devdraw/devdraw.h +++ b/src/cmd/devdraw/devdraw.h @@ -56,6 +56,8 @@ struct ClientImpl void (*rpc_flush)(Client*, Rectangle); }; +extern QLock drawlk; + struct Client { int rfd; @@ -69,10 +71,9 @@ struct Client char* wsysid; - // drawlk protects the draw data structures. + // drawlk protects the draw data structures for all clients. // It can be acquired by an RPC thread or a graphics thread // but must not be held on one thread while waiting for the other. - QLock drawlk; /*Ref r;*/ DImage* dimage[NHASH]; CScreen* cscreen; diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m index 9454be05..ad9c029e 100644 --- a/src/cmd/devdraw/mac-screen.m +++ b/src/cmd/devdraw/mac-screen.m @@ -39,7 +39,6 @@ static uint msec(void); static void rpc_resizeimg(Client*); static void rpc_resizewindow(Client*, Rectangle); -static void rpc_serve(Client*); static void rpc_setcursor(Client*, Cursor*, Cursor2*); static void rpc_setlabel(Client*, char*); static void rpc_setmouse(Client*, Point); @@ -496,17 +495,17 @@ rpc_flush(Client *client, Rectangle r) if(!rectclip(&r, Rect(0, 0, self.dlayer.texture.width, self.dlayer.texture.height)) || !rectclip(&r, self.img->r)) return; - // self.client->drawlk protects the pixel data in self.img. + // drawlk protects the pixel data in self.img. // In addition to avoiding a technical data race, // the lock avoids drawing partial updates, which makes // animations like sweeping windows much less flickery. - qlock(&self.client->drawlk); + qlock(&drawlk); [self.dlayer.texture replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r)) mipmapLevel:0 withBytes:byteaddr(self.img, Pt(r.min.x, r.min.y)) bytesPerRow:self.img->width*sizeof(u32int)]; - qunlock(&self.client->drawlk); + qunlock(&drawlk); NSRect nr = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r)); dispatch_time_t time; -- cgit v1.2.3 From c53ad837a734f7570badcb3666ccb3604e7e6467 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 17:03:42 -0400 Subject: lib9: avoid unportable use of d_namlen in dirread Fixes #395. --- src/lib9/open.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib9/open.c b/src/lib9/open.c index 65ea99ec..2354268b 100644 --- a/src/lib9/open.c +++ b/src/lib9/open.c @@ -318,8 +318,7 @@ dirreadmax(int fd, Dir **dp, int max) return -1; break; } - if(de->d_name[de->d_namlen] != 0) - sysfatal("bad readdir"); + // Note: not all systems have d_namlen. Assume NUL-terminated. if(de->d_name[0]=='.' && de->d_name[1]==0) continue; if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0) -- cgit v1.2.3 From 84167be4ad170c879db48493438f507c2d40d28d Mon Sep 17 00:00:00 2001 From: Gabriel Diaz Date: Mon, 18 May 2020 17:38:16 +0200 Subject: devdraw: use indirect impl interface in x11 --- src/cmd/devdraw/x11-screen.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/cmd/devdraw/x11-screen.c b/src/cmd/devdraw/x11-screen.c index 62f49f2f..0bbc25d6 100644 --- a/src/cmd/devdraw/x11-screen.c +++ b/src/cmd/devdraw/x11-screen.c @@ -40,6 +40,26 @@ static void _xmovewindow(Xwin *w, Rectangle r); static int _xtoplan9kbd(XEvent *e); static int _xselect(XEvent *e); +static void rpc_resizeimg(Client*); +static void rpc_resizewindow(Client*, Rectangle); +static void rpc_setcursor(Client*, Cursor*, Cursor2*); +static void rpc_setlabel(Client*, char*); +static void rpc_setmouse(Client*, Point); +static void rpc_topwin(Client*); +static void rpc_bouncemouse(Client*, Mouse); +static void rpc_flush(Client*, Rectangle); + +static ClientImpl x11impl = { + rpc_resizeimg, + rpc_resizewindow, + rpc_setcursor, + rpc_setlabel, + rpc_setmouse, + rpc_topwin, + rpc_bouncemouse, + rpc_flush +}; + static Xwin* newxwin(Client *c) { @@ -51,6 +71,7 @@ newxwin(Client *c) w->client = c; w->next = _x.windows; _x.windows = w; + c->impl = &x11impl; c->view = w; return w; } -- cgit v1.2.3 From d4a4b66a401d8988441dd663bf1664e11c045797 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 19:55:01 -0400 Subject: diff: rename class to fix AIX math.h defines a function named class on AIX. --- src/cmd/diff/diffreg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cmd/diff/diffreg.c b/src/cmd/diff/diffreg.c index ed4d17b8..478c1b1b 100644 --- a/src/cmd/diff/diffreg.c +++ b/src/cmd/diff/diffreg.c @@ -66,6 +66,9 @@ * 3*(number of k-candidates installed), typically about * 6n words for files of length n. */ + +#define class diffclass + /* TIDY THIS UP */ struct cand { int x; -- cgit v1.2.3 From 079f5e94459fe5afccf749764d81ab88c59f055a Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 22:29:00 -0400 Subject: libdiskfs: avoid problematic internal constant names AIX defines some of these constants in its C header files. --- src/libdiskfs/ext2.h | 33 +++++++++++++++++++++++++++++++++ src/libdiskfs/ffs.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/libdiskfs/ext2.h b/src/libdiskfs/ext2.h index f4c32ce3..bf98a9ac 100644 --- a/src/libdiskfs/ext2.h +++ b/src/libdiskfs/ext2.h @@ -27,6 +27,39 @@ enum NAMELEN = 255, + /* some systems have these defined */ + #undef IEXEC + #undef IWRITE + #undef IREAD + #undef ISVTX + #undef ISGID + #undef ISUID + #undef IFMT + #undef IFIFO + #undef IFCHR + #undef IFDIR + #undef IFBLK + #undef IFREG + #undef IFLNK + #undef IFSOCK + #undef IFWHT + + #define IEXEC EXT2_IEXEC + #define IWRITE EXT2_IWRITE + #define IREAD EXT2_IREAD + #define ISVTX EXT2_ISVTX + #define ISGID EXT2_ISGID + #define ISUID EXT2_ISUID + #define IFMT EXT2_IFMT + #define IFIFO EXT2_IFIFO + #define IFCHR EXT2_IFCHR + #define IFDIR EXT2_IFDIR + #define IFBLK EXT2_IFBLK + #define IFREG EXT2_IFREG + #define IFLNK EXT2_IFLNK + #define IFSOCK EXT2_IFSOCK + #define IFWHT EXT2_IFWHT + /* permissions in Inode.mode */ IEXEC = 00100, IWRITE = 0200, diff --git a/src/libdiskfs/ffs.h b/src/libdiskfs/ffs.h index d7881f15..b8675448 100644 --- a/src/libdiskfs/ffs.h +++ b/src/libdiskfs/ffs.h @@ -72,6 +72,39 @@ enum NDADDR = 12, NIADDR = 3, + /* some systems have these defined */ + #undef IEXEC + #undef IWRITE + #undef IREAD + #undef ISVTX + #undef ISGID + #undef ISUID + #undef IFMT + #undef IFIFO + #undef IFCHR + #undef IFDIR + #undef IFBLK + #undef IFREG + #undef IFLNK + #undef IFSOCK + #undef IFWHT + + #define IEXEC FFS_IEXEC + #define IWRITE FFS_IWRITE + #define IREAD FFS_IREAD + #define ISVTX FFS_ISVTX + #define ISGID FFS_ISGID + #define ISUID FFS_ISUID + #define IFMT FFS_IFMT + #define IFIFO FFS_IFIFO + #define IFCHR FFS_IFCHR + #define IFDIR FFS_IFDIR + #define IFBLK FFS_IFBLK + #define IFREG FFS_IFREG + #define IFLNK FFS_IFLNK + #define IFSOCK FFS_IFSOCK + #define IFWHT FFS_IFWHT + /* permissions in Inode.mode */ IEXEC = 00100, IWRITE = 0200, -- cgit v1.2.3 From dea4dbdba6e8a4652e682627dce50503bca5c4b4 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 22:31:22 -0400 Subject: acme: avoid global named "class" For AIX. --- src/cmd/acme/regx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cmd/acme/regx.c b/src/cmd/acme/regx.c index 56ea900c..ec574563 100644 --- a/src/cmd/acme/regx.c +++ b/src/cmd/acme/regx.c @@ -15,6 +15,9 @@ Rangeset sel; Rune *lastregexp; +#undef class +#define class regxclass /* some systems declare "class" in system headers */ + /* * Machine Information */ -- cgit v1.2.3 From 20c841bac102e777a3a1723724fa5d31018fefcc Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 22:32:59 -0400 Subject: rc: avoid problematic internal names "var", "thread" For AIX. --- src/cmd/rc/rc.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h index 46ff9510..2fd6758b 100644 --- a/src/cmd/rc/rc.h +++ b/src/cmd/rc/rc.h @@ -33,6 +33,12 @@ #undef pipe /* so that /dev/fd works */ #define searchpath rcsearchpath /* avoid new libc function */ +/* some systems define a global "var", "thread" */ +#undef var +#define var rcvar +#undef thread +#define thread rcthread + typedef struct tree tree; typedef struct word word; typedef struct io io; -- cgit v1.2.3 From 7a371bf93652573b3d57d50466d3ea22a6eebff2 Mon Sep 17 00:00:00 2001 From: Ben Huntsman Date: Wed, 13 May 2020 22:39:53 -0700 Subject: lib9: use __builtin_return_address on IBM XL/C --- include/libc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libc.h b/include/libc.h index 7b4c3813..4bb537d6 100644 --- a/include/libc.h +++ b/include/libc.h @@ -385,7 +385,7 @@ extern int exitcode(char*); extern void exits(char*); extern double p9frexp(double, int*); extern ulong getcallerpc(void*); -#if defined(__GNUC__) || defined(__clang__) +#if defined(__GNUC__) || defined(__clang__) || defined(__IBMC__) #define getcallerpc(x) ((ulong)__builtin_return_address(0)) #endif extern char* p9getenv(char*); -- cgit v1.2.3 From 53bf1f1ccf9a6fee9437649216ac047f80590fae Mon Sep 17 00:00:00 2001 From: Ben Huntsman Date: Mon, 18 May 2020 12:20:48 -0700 Subject: 9l: xlc_r automatically adds -lpthread. --- bin/9l | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/9l b/bin/9l index 875e103a..b4f91584 100755 --- a/bin/9l +++ b/bin/9l @@ -63,7 +63,6 @@ case "$tag" in *AIX*) ld="${CC9:-xlc_r} -g -O0 $CC9FLAGS" nmflags="-A -B" - extralibs="$extralibs -lpthread" ;; *) echo do not know how to link on "$tag" 1>&2 -- cgit v1.2.3 From fa157263c8f510318f1f119a2d4843281e506eba Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 22:38:54 -0400 Subject: 9c: fix tab --- bin/9c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/9c b/bin/9c index dd899293..a22a0a08 100755 --- a/bin/9c +++ b/bin/9c @@ -149,7 +149,7 @@ case "$tag" in cflags="$cflags -g" cflags="$cflags -D__sun__ -D__${s}__" ;; -*AIX*) usexlc +*AIX*) usexlc cflags="$cflags -g -D__AIX__" ;; *) -- cgit v1.2.3 From 6c1235d234dfe290c61c492a1779c7a3ad2f7fc6 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 22:46:16 -0400 Subject: build: use installbsd instead of install on AIX Even in mkmk.sh. --- dist/buildmk | 2 +- src/mk.AIX-power | 2 -- src/mkenv | 1 + src/mkfile | 3 ++- src/mkhdr | 3 --- src/mkmk.sh | 2 +- 6 files changed, 5 insertions(+), 8 deletions(-) delete mode 100644 src/mk.AIX-power diff --git a/dist/buildmk b/dist/buildmk index c559570c..cd11417c 100755 --- a/dist/buildmk +++ b/dist/buildmk @@ -2,5 +2,5 @@ # run this in the src directory . ../src/mkenv -export SYSNAME OBJTYPE +export SYSNAME OBJTYPE INSTALL sh -x mkmk.sh diff --git a/src/mk.AIX-power b/src/mk.AIX-power deleted file mode 100644 index 39f8ee8a..00000000 --- a/src/mk.AIX-power +++ /dev/null @@ -1,2 +0,0 @@ -INSTALL=installbsd - diff --git a/src/mkenv b/src/mkenv index 6ff746e0..6c89f141 100644 --- a/src/mkenv +++ b/src/mkenv @@ -20,3 +20,4 @@ OBJTYPE=`(uname -m -p 2>/dev/null || uname -m) | sed ' s;.*aarch64.*;arm64; s;.*arm64.*;arm64; '` +INSTALL=`[ $(uname) = AIX ] && echo installbsd || echo install` diff --git a/src/mkfile b/src/mkfile index 8ddaee20..4740780d 100644 --- a/src/mkfile +++ b/src/mkfile @@ -30,11 +30,12 @@ mkmk.sh:VD: (cd lib9; mk -n -a install) echo cd .. for i in libbio libregexp cmd/mk - do + do (cd $i; echo cd $i; echo 'echo cd `pwd`'; mk -n -a install) echo cd .. done ) | sed ' + s/'$INSTALL'/$INSTALL/g s/'$SYSNAME'/$SYSNAME/g s/'$OBJTYPE'/$OBJTYPE/g s;'$PLAN9';$PLAN9;g diff --git a/src/mkhdr b/src/mkhdr index 24889cde..35a2ccc5 100644 --- a/src/mkhdr +++ b/src/mkhdr @@ -11,7 +11,6 @@ CC=9c LD=9l AS=9a AR=9ar -INSTALL=install CFLAGS= LDFLAGS= AFLAGS= @@ -24,5 +23,3 @@ LIB= SHORTLIB=9 <|cat $PLAN9/config 2>/dev/null || true -<|cat $PLAN9/src/mk.$SYSNAME-$OBJTYPE 2>/dev/null || true - diff --git a/src/mkmk.sh b/src/mkmk.sh index 89c311f3..dfccd369 100644 --- a/src/mkmk.sh +++ b/src/mkmk.sh @@ -209,5 +209,5 @@ echo cd `pwd` 9c word.c 9c unix.c 9l -o o.mk arc.o archive.o bufblock.o env.o file.o graph.o job.o lex.o main.o match.o mk.o parse.o recipe.o rc.o rule.o run.o sh.o shell.o shprint.o symtab.o var.o varsub.o word.o unix.o -install o.mk $PLAN9/bin/mk +$INSTALL o.mk $PLAN9/bin/mk cd .. -- cgit v1.2.3 From b4cc38f94321c71e8d19fbbd4691e72f7c0d817b Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 22:58:09 -0400 Subject: build: drop _XOPEN_SOURCE in u.h on AIX --- include/u.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/u.h b/include/u.h index 297df70a..f84e348a 100644 --- a/include/u.h +++ b/include/u.h @@ -35,7 +35,6 @@ extern "C" { # define __LONG_LONG_SUPPORTED #endif #if defined(__AIX__) -# define _XOPEN_SOURCE 600 # define _ALL_SOURCE # undef HAS_SYS_TERMIOS #endif -- cgit v1.2.3 From d25d0ca1a3682d97df67f62789767562aa5bf1b3 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 23:45:03 -0400 Subject: devdraw, libdraw: handle keyboard runes > U+FFFF Runes in Plan 9 were limited to the 16-bit BMP when I drew up the RPC protocol between graphical programs and devdraw a long time ago. Now that they can be 32-bit, use a 32-bit wire encoding too. A new message number to avoid problems with other clients (like 9fans.net/go). Add keyboard shortcut alt : , for U+1F602, face with tears of joy, to test that it all works. --- include/drawfcall.h | 11 ++++++++--- lib/keyboard | 1 + src/cmd/devdraw/mklatinkbd.c | 2 +- src/cmd/devdraw/srv.c | 9 +++++++-- src/libdraw/drawclient.c | 2 +- src/libdraw/drawfcall.c | 15 +++++++++++++++ src/libdraw/event.c | 2 +- 7 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/drawfcall.h b/include/drawfcall.h index 8b9656d5..b8535fb6 100644 --- a/include/drawfcall.h +++ b/include/drawfcall.h @@ -22,8 +22,11 @@ tag[1] Rbouncemouse tag[1] Trdkbd tag[1] Rrdkbd rune[2] +tag[1] Trdkbd4 +tag[1] Rrdkbd4 rune[4] + tag[1] Tlabel label[s] -tag[1] Rlabel +tag[1] Rlabel tag[1] Tctxt wsysid[s] tag[1] Rctxt @@ -31,7 +34,7 @@ tag[1] Rctxt tag[1] Tinit winsize[s] label[s] font[s] tag[1] Rinit -tag[1] Trdsnarf +tag[1] Trdsnarf tag[1] Rrdsnarf snarf[s] tag[1] Twrsnarf snarf[s] @@ -47,7 +50,7 @@ tag[1] Ttop tag[1] Rtop tag[1] Tresize rect[4*4] -tag[1] Rresize +tag[1] Rresize */ @@ -99,6 +102,8 @@ enum { Rcursor2, Tctxt = 30, Rctxt, + Trdkbd4 = 32, + Rrdkbd4, Tmax, }; diff --git a/lib/keyboard b/lib/keyboard index a1574a36..1a0e85a5 100644 --- a/lib/keyboard +++ b/lib/keyboard @@ -584,3 +584,4 @@ F015 ZA  raw alt (plan 9 specific) F016 ZS  raw shift (plan 9 specific) F017 ZC  raw ctl (plan 9 specific) +1F602 :, 😂 face with tears of joy diff --git a/src/cmd/devdraw/mklatinkbd.c b/src/cmd/devdraw/mklatinkbd.c index db34b6ec..50dd26b0 100644 --- a/src/cmd/devdraw/mklatinkbd.c +++ b/src/cmd/devdraw/mklatinkbd.c @@ -191,7 +191,7 @@ readfile(char *fname) r = strtol(line, nil, 16); p = strchr(line, ' '); - if(r == 0 || p != line+4 || p[0] != ' ' || p[1] != ' ') { + if(r == 0 || (p != line+4 && p != line+5) || p[0] != ' ' || (p == line+4 && p[1] != ' ')) { fprint(2, "%s:%d: cannot parse line\n", fname, lineno); continue; } diff --git a/src/cmd/devdraw/srv.c b/src/cmd/devdraw/srv.c index bdfc1654..05a08fda 100644 --- a/src/cmd/devdraw/srv.c +++ b/src/cmd/devdraw/srv.c @@ -229,6 +229,7 @@ runmsg(Client *c, Wsysmsg *m) break; case Trdkbd: + case Trdkbd4: qlock(&c->eventlk); if((c->kbdtags.wi+1)%nelem(c->kbdtags.t) == c->kbdtags.ri) { qunlock(&c->eventlk); @@ -236,7 +237,7 @@ runmsg(Client *c, Wsysmsg *m) replyerror(c, m); break; } - c->kbdtags.t[c->kbdtags.wi++] = m->tag; + c->kbdtags.t[c->kbdtags.wi++] = (m->tag<<1) | (m->type==Trdkbd4); if(c->kbdtags.wi == nelem(c->kbdtags.t)) c->kbdtags.wi = 0; c->kbd.stall = 0; @@ -357,13 +358,17 @@ replymsg(Client *c, Wsysmsg *m) static void matchkbd(Client *c) { + int tag; Wsysmsg m; if(c->kbd.stall) return; while(c->kbd.ri != c->kbd.wi && c->kbdtags.ri != c->kbdtags.wi){ + tag = c->kbdtags.t[c->kbdtags.ri++]; m.type = Rrdkbd; - m.tag = c->kbdtags.t[c->kbdtags.ri++]; + if(tag&1) + m.type = Rrdkbd4; + m.tag = tag>>1; if(c->kbdtags.ri == nelem(c->kbdtags.t)) c->kbdtags.ri = 0; m.rune = c->kbd.r[c->kbd.ri++]; diff --git a/src/libdraw/drawclient.c b/src/libdraw/drawclient.c index 9376f9c0..c38f4801 100644 --- a/src/libdraw/drawclient.c +++ b/src/libdraw/drawclient.c @@ -333,7 +333,7 @@ _displayrdkbd(Display *d, Rune *r) { Wsysmsg tx, rx; - tx.type = Trdkbd; + tx.type = Trdkbd4; if(displayrpc(d, &tx, &rx, nil) < 0) return -1; *r = rx.rune; diff --git a/src/libdraw/drawfcall.c b/src/libdraw/drawfcall.c index eea14095..94115384 100644 --- a/src/libdraw/drawfcall.c +++ b/src/libdraw/drawfcall.c @@ -50,6 +50,7 @@ sizeW2M(Wsysmsg *m) case Rcursor: case Rcursor2: case Trdkbd: + case Trdkbd4: case Rlabel: case Rctxt: case Rinit: @@ -73,6 +74,8 @@ sizeW2M(Wsysmsg *m) return 4+1+1+_stringsize(m->error); case Rrdkbd: return 4+1+1+2; + case Rrdkbd4: + return 4+1+1+4; case Tlabel: return 4+1+1+_stringsize(m->label); case Tctxt: @@ -117,6 +120,7 @@ convW2M(Wsysmsg *m, uchar *p, uint n) case Rcursor: case Rcursor2: case Trdkbd: + case Trdkbd4: case Rlabel: case Rctxt: case Rinit: @@ -166,6 +170,9 @@ convW2M(Wsysmsg *m, uchar *p, uint n) case Rrdkbd: PUT2(p+6, m->rune); break; + case Rrdkbd4: + PUT(p+6, m->rune); + break; case Tlabel: PUTSTRING(p+6, m->label); break; @@ -221,6 +228,7 @@ convM2W(uchar *p, uint n, Wsysmsg *m) case Rcursor: case Rcursor2: case Trdkbd: + case Trdkbd4: case Rlabel: case Rctxt: case Rinit: @@ -270,6 +278,9 @@ convM2W(uchar *p, uint n, Wsysmsg *m) case Rrdkbd: GET2(p+6, m->rune); break; + case Rrdkbd4: + GET(p+6, m->rune); + break; case Tlabel: GETSTRING(p+6, &m->label); break; @@ -360,6 +371,10 @@ drawfcallfmt(Fmt *fmt) return fmtprint(fmt, "Trdkbd"); case Rrdkbd: return fmtprint(fmt, "Rrdkbd rune=%C", m->rune); + case Trdkbd4: + return fmtprint(fmt, "Trdkbd4"); + case Rrdkbd4: + return fmtprint(fmt, "Rrdkbd4 rune=%C", m->rune); case Tlabel: return fmtprint(fmt, "Tlabel label='%s'", m->label); case Rlabel: diff --git a/src/libdraw/event.c b/src/libdraw/event.c index 9d7e10c2..e2d5f707 100644 --- a/src/libdraw/event.c +++ b/src/libdraw/event.c @@ -284,7 +284,7 @@ extract(int canblock) } }else if(i == Skeyboard){ if(eslave[i].rpc == nil) - eslave[i].rpc = startrpc(Trdkbd); + eslave[i].rpc = startrpc(Trdkbd4); if(eslave[i].rpc){ /* if ready, don't block in select */ if(eslave[i].rpc->p) -- cgit v1.2.3 From bfe4377e409ce271c479665e6ef966a7b6008626 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 18 May 2020 23:51:35 -0400 Subject: man: update man pages to say $HOME when accurate Fixes #386. --- man/man1/acid.1 | 30 +++++++++++++++--------------- man/man1/acme.1 | 8 ++++---- man/man1/rc.1 | 4 ++++ man/man1/sam.1 | 28 ++++++++++++++-------------- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/man/man1/acid.1 b/man/man1/acid.1 index e76aeb25..ed0b24db 100644 --- a/man/man1/acid.1 +++ b/man/man1/acid.1 @@ -48,7 +48,7 @@ is a programmable symbolic debugger. It can inspect one or more processes that share an address space. A program to be debugged may be specified by the process id of a running or defunct process, -or by the name of the program's text file +or by the name of the program's text file .RB ( a.out by default). At the prompt, @@ -63,7 +63,7 @@ Allow the textfile to be modified. Print variable renamings at startup. .TP .BI -l " library -Load from +Load from .I library at startup; see below. .TP @@ -84,8 +84,8 @@ obtains standard function definitions from the library file architecture-dependent functions from .BR \*9/acid/$objtype , user-specified functions from -.BR $home/lib/acid , -and further functions from +.BR $HOME/lib/acid , +and further functions from .B -l files. Definitions in any file may override previously defined functions. @@ -106,7 +106,7 @@ to create .I acid functions for examining data structures. .SS Language -Symbols of the program being debugged become integer +Symbols of the program being debugged become integer variables whose values are addresses. Contents of addresses are obtained by indirection. Local variables are qualified by @@ -114,7 +114,7 @@ function name, for example .BR main:argv . When program symbols conflict with .I acid -words, distinguishing +words, distinguishing .B $ signs are prefixed. Such renamings are reported at startup; option @@ -127,7 +127,7 @@ and formats are inferred from assignments. Truth values false/true are attributed to zero/nonzero integers or floats and to empty/nonempty lists or strings. Lists are sequences of expressions surrounded by -.BR {\^} +.BR {\^} and separated by commas. .PP Expressions are much as in C, @@ -219,7 +219,7 @@ Same as .BR spr();gpr() . .TP .BI fmt( expr , format ) -Expression +Expression .I expr with format given by the character value of expression .IR format . @@ -243,7 +243,7 @@ List current source directories. Add a source directory to the list. .TP .BI filepc( where ) -Convert a string of the form +Convert a string of the form .IB sourcefile : linenumber to a machine address. .TP @@ -288,7 +288,7 @@ interpreted according to a string of format codes. .BI dump( address , n , string\fP) Like .BR mem (), -repeated for +repeated for .I n consecutive blocks. .TP @@ -300,7 +300,7 @@ Start a new process with arguments given as a string and halt at the first instruction. .TP .B new() -Like +Like .IR newproc (), but take arguments (except .BR argv[0] ) @@ -308,7 +308,7 @@ from string variable .BR progargs . .TP .B win() -Like +Like .IR new (), but run the process in a separate window. .TP @@ -337,7 +337,7 @@ When a pid or core file is specified on the command line, .I acid will, as part of its startup, determine the set of shared libraries in use by the process image and map those at appropriate locations. -If +If .I acid is started without a pid or core file and is subsequently attached to a process via @@ -414,7 +414,7 @@ acid: *argv0 acid: bpset(ls) acid: cont() 70094: breakpoint ls ADD $-0x16c8,R29 -acid: +acid: .EE .PP Display elements of a linked list of structures: @@ -499,7 +499,7 @@ acid: cont() .br .B \*9/acid/truss .br -.B $home/lib/acid +.B $HOME/lib/acid .SH SOURCE .B \*9/src/cmd/acid .SH "SEE ALSO" diff --git a/man/man1/acme.1 b/man/man1/acme.1 index 182bcc7b..f21566f9 100644 --- a/man/man1/acme.1 +++ b/man/man1/acme.1 @@ -300,7 +300,7 @@ Delete window without checking for dirtiness. Write the state of .I acme to the file name, if specified, or -.B $home/acme.dump +.B $HOME/acme.dump by default. .TP .B Edit @@ -403,7 +403,7 @@ commands named as arguments. Restore the state of .I acme from a file (default -.BR $home/acme.dump ) +.BR $HOME/acme.dump ) created by the .B Dump command. @@ -745,9 +745,9 @@ and .I awd reside. .SH FILES -.TF $home/acme.dump +.TF $HOME/acme.dump .TP -.B $home/acme.dump +.B $HOME/acme.dump default file for .B Dump and diff --git a/man/man1/rc.1 b/man/man1/rc.1 index 792cdc95..7553707d 100644 --- a/man/man1/rc.1 +++ b/man/man1/rc.1 @@ -806,6 +806,10 @@ is set to its process id. .B $home The default directory for .BR cd . +Defaults to +.B $HOME +or else +.LR / . .TP .B $ifs The input field separators used in backquote substitutions. diff --git a/man/man1/sam.1 b/man/man1/sam.1 index 460fd6d6..8e771833 100644 --- a/man/man1/sam.1 +++ b/man/man1/sam.1 @@ -1,7 +1,7 @@ .TH SAM 1 .ds a \fR*\ \fP .SH NAME -sam, B, E, sam.save, samterm, samsave \- screen editor with structural regular expressions +sam, B, E, sam.save, samterm, samsave \- screen editor with structural regular expressions .SH SYNOPSIS .B sam [ @@ -43,7 +43,7 @@ The options are .TP .B -a Autoindent. In this mode, when a newline character is typed -in the terminal interface, +in the terminal interface, .I samterm copies leading white space on the current line to the new line. .TP @@ -121,7 +121,7 @@ is the beginning of the file. .TP .BI ? regexp ? The substring that matches the regular expression, -found by looking toward the end +found by looking toward the end .RB ( / ) or beginning .RB ( ? ) @@ -248,7 +248,7 @@ or is reversed. .PP It is an error for a compound address to represent a malformed substring. -Some useful idioms: +Some useful idioms: .IB a1 +- \%(\f2a1\fB-+\f1) selects the line containing @@ -258,7 +258,7 @@ locates the first match of the expression in the file. (The form .B 0;// sets dot unnecessarily.) -.BI ./ regexp /// +.BI ./ regexp /// finds the second following occurrence of the expression, and .BI .,/ regexp / @@ -276,7 +276,7 @@ newline may not appear literally; .B \en may be typed for newline; and .B \e/ -quotes the delimiter, here +quotes the delimiter, here .LR / . Backslash is otherwise interpreted literally, except in .B s @@ -284,7 +284,7 @@ commands. .PP Most commands may be prefixed by an address to indicate their range of operation. -Those that may not are marked with a +Those that may not are marked with a .L * below. If a command takes @@ -347,12 +347,12 @@ Substitute .I text for the first match to the regular expression in the range. Set dot to the modified range. -In +In .I text the character .B & stands for the string -that matched the expression. +that matched the expression. Backslash behaves as usual unless followed by a digit: .BI \e d @@ -500,7 +500,7 @@ Plan 9 command. .BI \*acd " directory Change working directory. If no directory is specified, -.B $home +.B $HOME is used. .PD .PP @@ -543,7 +543,7 @@ For each match of the regular expression in the range, run the command with dot set to the match. Set dot to the last match. If the regular -expression and its slashes are omitted, +expression and its slashes are omitted, .L /.*\en/ is assumed. Null string matches potentially occur before every character @@ -652,7 +652,7 @@ If no address is specified (the command is a newline) dot is extended in either direction to line boundaries and printed. If dot is thereby unchanged, it is set to -.B .+1 +.B .+1 and printed. .PD .SS Grouping and multiple changes @@ -713,7 +713,7 @@ of a rectangle. from the command window or the whole screen, depending on where the null rectangle is. .TF resize -.TP +.TP .B new Create a new, empty file. .TP @@ -819,7 +819,7 @@ typed in a command. Send the text in dot, or the snarf buffer if dot is the null string, as if it were typed to the command window. Saves the sent text in the snarf buffer. -(Command window only.) +(Command window only.) .PD .SS Simulated buttons For systems without a three-button mouse, the keyboard modifier -- cgit v1.2.3 From a6ad39aaaa36b8aadc5c35bfc803afbde32918c0 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 26 May 2020 11:24:18 -0400 Subject: libdraw: handle larger number of subfonts --- include/draw.h | 5 +++-- man/man3/cachechars.3 | 2 +- src/libdraw/openfont.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/draw.h b/include/draw.h index 926cc748..9a22e6b6 100644 --- a/include/draw.h +++ b/include/draw.h @@ -311,8 +311,8 @@ struct Font Display *display; short height; /* max height of image, interline spacing */ short ascent; /* top of image to baseline */ - short width; /* widest so far; used in caching only */ - short nsub; /* number of subfonts */ + short width; /* widest so far; used in caching only */ + int nsub; /* number of subfonts */ u32int age; /* increasing counter; used for LRU */ int maxdepth; /* maximum depth of all loaded subfonts */ int ncache; /* size of cache */ @@ -516,6 +516,7 @@ extern Display *display; extern Font *font; extern Image *screen; extern Screen *_screen; +extern int drawmousemask; /* set bits to disable receiving those buttons */ extern int _cursorfd; extern int _drawdebug; /* set to 1 to see errors from flushimage */ extern void _setdrawop(Display*, Drawop); diff --git a/man/man3/cachechars.3 b/man/man3/cachechars.3 index b0c7abfa..f2d82f19 100644 --- a/man/man3/cachechars.3 +++ b/man/man3/cachechars.3 @@ -165,7 +165,7 @@ struct Font { short height; /* max ht of image;interline space*/ short ascent; /* top of image to baseline */ short width; /* widest so far; used in caching */ - short nsub; /* number of subfonts */ + int nsub; /* number of subfonts */ ulong age; /* increasing counter; for LRU */ int ncache; /* size of cache */ int nsubf; /* size of subfont list */ diff --git a/src/libdraw/openfont.c b/src/libdraw/openfont.c index 9312eb43..8714a8c7 100644 --- a/src/libdraw/openfont.c +++ b/src/libdraw/openfont.c @@ -69,7 +69,7 @@ openfont1(Display *d, char *name) n = _drawflength(fd); if(fd < 0 && strncmp(fname, "/mnt/font/", 10) == 0) { fd = _fontpipe(fname+10); - n = 128*1024; + n = 1024*1024; } if(fd < 0){ free(nambuf); -- cgit v1.2.3 From 5f0fa185d0a978b45de5bf206193769596c056b5 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 26 May 2020 11:36:59 -0400 Subject: fontsrv: handle non-BMP runes on X11 Have to adjust algorithms to deal with much larger number of subfont files as well. --- src/cmd/fontsrv/a.h | 9 ++++++--- src/cmd/fontsrv/mac.c | 6 ++++-- src/cmd/fontsrv/main.c | 53 ++++++++++++++++++++++---------------------------- src/cmd/fontsrv/x11.c | 19 ++++++++++-------- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/cmd/fontsrv/a.h b/src/cmd/fontsrv/a.h index 164b1bd6..2eeb404f 100644 --- a/src/cmd/fontsrv/a.h +++ b/src/cmd/fontsrv/a.h @@ -4,19 +4,22 @@ int nxfont; enum { SubfontSize = 32, - SubfontMask = (1<<16)/SubfontSize - 1, + MaxSubfont = (Runemax+1)/SubfontSize, }; struct XFont { char *name; int loaded; - uchar range[(1<<16)/SubfontSize]; // range[i] == whether to have subfont i*SubfontSize to (i+1)*SubfontSize - 1. - int nrange; + uchar range[MaxSubfont]; // range[i] = fontfile starting at i*SubfontSize exists + ushort file[MaxSubfont]; // file[i] == fontfile i's lo rune / SubfontSize + int nfile; int unit; double height; double originy; void (*loadheight)(XFont*, int, int*, int*); + char *fonttext; + int nfonttext; // fontconfig workarround, as FC_FULLNAME does not work for matching fonts. char *fontfile; diff --git a/src/cmd/fontsrv/mac.c b/src/cmd/fontsrv/mac.c index b4dadd90..9829b5a8 100644 --- a/src/cmd/fontsrv/mac.c +++ b/src/cmd/fontsrv/mac.c @@ -200,9 +200,12 @@ load(XFont *f) f->loadheight = fontheight; // enable all Unicode ranges + if(nelem(f->file) > 0xffff) + sysfatal("too many subfiles"); // f->file holds ushorts for(i=0; irange); i++) { f->range[i] = 1; - f->nrange++; + f->file[i] = i; + f->nfile++; } } @@ -233,7 +236,6 @@ mksubfont(XFont *f, char *name, int lo, int hi, int size, int antialias) if(font == nil) return nil; - bbox = CTFontGetBoundingBox(font); x = (int)(bbox.size.width*2 + 0.99999999); diff --git a/src/cmd/fontsrv/main.c b/src/cmd/fontsrv/main.c index ebab6249..b2189be9 100644 --- a/src/cmd/fontsrv/main.c +++ b/src/cmd/fontsrv/main.c @@ -52,7 +52,7 @@ enum #define QFONT(p) (((p) >> 4) & 0xFFFF) #define QSIZE(p) (((p) >> 20) & 0xFF) #define QANTIALIAS(p) (((p) >> 28) & 0x1) -#define QRANGE(p) (((p) >> 29) & SubfontMask) +#define QRANGE(p) (((p) >> 29) & 0xFFFFFF) static int sizes[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 28 }; static vlong @@ -102,7 +102,7 @@ dostat(vlong path, Qid *qid, Dir *dir) case Qfontfile: f = &xfont[QFONT(path)]; load(f); - length = 11+1+11+1+f->nrange*(6+1+6+1+9+1); + length = 11+1+11+1+f->nfile*(6+1+6+1+9+1); name = "font"; break; @@ -189,9 +189,9 @@ xwalk1(Fid *fid, char *name, Qid *qid) goto NotFound; p++; n = strtoul(p, &p, 16); - if(p != name+5 || n%SubfontSize != 0 || strcmp(p, ".bit") != 0 || !f->range[(n/SubfontSize) & SubfontMask]) + if(p < name+5 || p > name+5 && name[1] == '0' || n%SubfontSize != 0 || n/SubfontSize >= MaxSubfont || strcmp(p, ".bit") != 0 || !f->range[n/SubfontSize]) goto NotFound; - path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, (n/SubfontSize) & SubfontMask); + path += Qsubfontfile - Qsizedir + qpath(0, 0, 0, 0, n/SubfontSize); break; } Found: @@ -229,7 +229,6 @@ sizegen(int i, Dir *d, void *v) vlong path; Fid *fid; XFont *f; - int j; fid = v; path = fid->qid.path; @@ -240,15 +239,10 @@ sizegen(int i, Dir *d, void *v) i--; f = &xfont[QFONT(path)]; load(f); - for(j=0; jrange); j++) { - if(f->range[j] == 0) - continue; - if(i == 0) { - path += Qsubfontfile - Qsizedir; - path += qpath(0, 0, 0, 0, j); - goto Done; - } - i--; + if(i < f->nfile) { + path += Qsubfontfile - Qsizedir; + path += qpath(0, 0, 0, 0, f->file[i]); + goto Done; } return -1; @@ -315,23 +309,22 @@ xread(Req *r) readstr(r, "font missing\n"); break; } - height = 0; - ascent = 0; - if(f->unit > 0) { - height = f->height * (int)QSIZE(path)/f->unit + 0.99999999; - ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999); - } - if(f->loadheight != nil) - f->loadheight(f, QSIZE(path), &height, &ascent); - fmtprint(&fmt, "%11d %11d\n", height, ascent); - for(i=0; irange); i++) { - if(f->range[i] == 0) - continue; - fmtprint(&fmt, "0x%04x 0x%04x x%04x.bit\n", i*SubfontSize, ((i+1)*SubfontSize) - 1, i*SubfontSize); + if(f->fonttext == nil) { + height = 0; + ascent = 0; + if(f->unit > 0) { + height = f->height * (int)QSIZE(path)/f->unit + 0.99999999; + ascent = height - (int)(-f->originy * (int)QSIZE(path)/f->unit + 0.99999999); + } + if(f->loadheight != nil) + f->loadheight(f, QSIZE(path), &height, &ascent); + fmtprint(&fmt, "%11d %11d\n", height, ascent); + for(i=0; infile; i++) + fmtprint(&fmt, "0x%04x 0x%04x x%04x.bit\n", f->file[i]*SubfontSize, ((f->file[i]+1)*SubfontSize) - 1, f->file[i]*SubfontSize); + f->fonttext = fmtstrflush(&fmt); + f->nfonttext = strlen(f->fonttext); } - data = fmtstrflush(&fmt); - readstr(r, data); - free(data); + readbuf(r, f->fonttext, f->nfonttext); break; case Qsubfontfile: f = &xfont[QFONT(path)]; diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c index 0f6b97bb..c78ad036 100644 --- a/src/cmd/fontsrv/x11.c +++ b/src/cmd/fontsrv/x11.c @@ -85,20 +85,23 @@ load(XFont *f) int idx = charcode/SubfontSize; - if(charcode > 0xffff) + if(charcode > Runemax) break; - if(!f->range[idx]) { + if(!f->range[idx]) f->range[idx] = 1; - f->nrange++; - } } + FT_Done_Face(face); + // libdraw expects U+0000 to be present - if(!f->range[0]) { + if(!f->range[0]) f->range[0] = 1; - f->nrange++; - } - FT_Done_Face(face); + + // fix up file list + for(i=0; irange); i++) + if(f->range[i]) + f->file[f->nfile++] = i; + f->loaded = 1; } -- cgit v1.2.3 From 2c70acc3ab751ab1ccb1999f1d22310ad8c35b27 Mon Sep 17 00:00:00 2001 From: dzklaim Date: Sat, 30 May 2020 01:02:10 +0000 Subject: fontsrv: scale f->originy to match f->height on x11 Co-authored-by: dzklaim --- src/cmd/fontsrv/x11.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c index c78ad036..417dcfa6 100644 --- a/src/cmd/fontsrv/x11.c +++ b/src/cmd/fontsrv/x11.c @@ -78,7 +78,7 @@ load(XFont *f) } f->unit = face->units_per_EM; f->height = (int)((face->ascender - face->descender) * 1.35); - f->originy = face->descender; // bbox.yMin (or descender) is negative, becase the baseline is y-coord 0 + f->originy = face->descender * 1.35; // bbox.yMin (or descender) is negative, because the baseline is y-coord 0 for(charcode=FT_Get_First_Char(face, &glyph_index); glyph_index != 0; charcode=FT_Get_Next_Char(face, charcode, &glyph_index)) { -- cgit v1.2.3 From 3850e6e177677885074c8896ef24534894726ad5 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 29 May 2020 21:19:32 -0400 Subject: devdraw: accept 5- and 6-byte Unicode hex values Alt X 1234 for U+1234 Alt X X 12345 for U+12345 Alt X X X 103456 for U+103456. --- man/man7/keyboard.7 | 21 ++++++++++++++------- src/cmd/devdraw/latin1.c | 39 +++++++++++++++++++++++++++++++-------- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/man/man7/keyboard.7 b/man/man7/keyboard.7 index bc7cb5af..07bfb960 100644 --- a/man/man7/keyboard.7 +++ b/man/man7/keyboard.7 @@ -58,7 +58,7 @@ The up arrow scrolls backward. .PP Characters in Plan 9 are runes (see .IR utf (7)). -Any 16-bit rune can be typed using a compose key followed by several +Any rune can be typed using a compose key followed by several other keys. The compose key is also generally near the lower right of the main key area: the @@ -72,14 +72,21 @@ key on the SLC, the key on the Magnum, and either .B Alt key on the PC. -After typing the compose key, type a capital -.L X -and exactly four hexadecimal characters (digits and +To type a single rune with the value specified by +a given four-digit hexadecimal number, +type the compose key, +then a capital +.LR X , +and then the four hexadecimal digits (decimal digits and .L a to -.LR f ) -to type a single rune with the value represented by -the typed number. +.LR f ). +For a longer rune, type +.L X +twice followed by five digits, +or type +.L X +three times followed by six digits. There are shorthands for many characters, comprising the compose key followed by a two- or three-character sequence. The full list is too long to repeat here, but is contained in the file diff --git a/src/cmd/devdraw/latin1.c b/src/cmd/devdraw/latin1.c index a3d13a08..87c0be45 100644 --- a/src/cmd/devdraw/latin1.c +++ b/src/cmd/devdraw/latin1.c @@ -17,16 +17,15 @@ static struct cvlist }; /* - * Given 5 characters k[0]..k[4], find the rune or return -1 for failure. + * Given 5 characters k[0]..k[n], find the rune or return -1 for failure. */ static long -unicode(Rune *k) +unicode(Rune *k, int n) { long i, c; - k++; /* skip 'X' */ c = 0; - for(i=0; i<4; i++,k++){ + for(i=0; i Runemax) + return -1; } return c; } @@ -53,10 +54,32 @@ latin1(Rune *k, int n) char* p; if(k[0] == 'X'){ - if(n>=5) - return unicode(k); - else - return -5; + if(n < 2) + return -2; + if(k[1] == 'X') { + if(n < 3) + return -3; + if(k[2] == 'X') { + if(n < 9) { + if(unicode(k+3, n-3) < 0) + return -1; + return -(n+1); + } + return unicode(k+3, 6); + } + if(n < 7) { + if(unicode(k+2, n-2) < 0) + return -1; + return -(n+1); + } + return unicode(k+2, 5); + } + if(n < 5) { + if(unicode(k+1, n-1) < 0) + return -1; + return -(n+1); + } + return unicode(k+1, 4); } for(l=latintab; l->ld!=0; l++) -- cgit v1.2.3 From 95220bf88775deab4a037264d08b21bacc612d70 Mon Sep 17 00:00:00 2001 From: sean Date: Thu, 21 May 2020 16:10:30 +0100 Subject: ed: handle Unicode beyond the BMP correctly in list mode. List mode was constrained to the BMP. This change introduces the following new list mode convention, using Go string literal syntax: Non-printing ASCII characters display as \xhh. Non-ASCII characters in the BMP display as \uhhhh. Characters beyond the BMP display as \Uhhhhhhhh. --- man/man1/ed.1 | 12 ++++++++++-- src/cmd/ed.c | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/man/man1/ed.1 b/man/man1/ed.1 index 00eb095a..9b161b29 100644 --- a/man/man1/ed.1 +++ b/man/man1/ed.1 @@ -441,10 +441,18 @@ a backspace as .LR \eb , backslashes as .LR \e\e , -and non-printing characters as +and non-printing ASCII characters as a backslash, an .LR x , -and four hexadecimal digits. +and two hexadecimal digits. +non-ASCII characters in the Basic Multilingual Plane +are printed as a backslash, a small +.LR u , +and four hexadecimal digits; and characters above the +Basic Multilingual Plane are printed as a backslash, +a big +.LR U , +and six hexadecimal digits. Long lines are folded, with the second and subsequent sub-lines indented one tab stop. If the last character in the line is a blank, diff --git a/src/cmd/ed.c b/src/cmd/ed.c index 8b0f36e5..a04f0d3f 100644 --- a/src/cmd/ed.c +++ b/src/cmd/ed.c @@ -21,6 +21,12 @@ enum EOF = -1 }; +enum +{ + LINELEN = 70, /* max number of glyphs in a display line */ + BELL = 6 /* A char could require up to BELL glyphs to display */ +}; + void (*oldhup)(int); void (*oldquit)(int); int* addr1; @@ -40,7 +46,7 @@ int ichanged; int io; Biobuf iobuf; int lastc; -char line[70]; +char line[LINELEN]; Rune* linebp; Rune linebuf[LBSIZE]; int listf; @@ -1543,7 +1549,7 @@ putchr(int ac) *lp++ = 'n'; } } else { - if(col > (72-6-2)) { + if(col > (LINELEN-BELL)) { col = 8; *lp++ = '\\'; *lp++ = '\n'; @@ -1558,15 +1564,32 @@ putchr(int ac) if(c == '\t') c = 't'; col++; - } else - if(c<' ' || c>='\177') { + } else if (c<' ' || c=='\177') { *lp++ = '\\'; *lp++ = 'x'; - *lp++ = hex[c>>12]; - *lp++ = hex[c>>8&0xF]; - *lp++ = hex[c>>4&0xF]; - c = hex[c&0xF]; + *lp++ = hex[(c>>4)&0xF]; + c = hex[c&0xF]; + col += 3; + } else if (c>'\177' && c<=0xFFFF) { + *lp++ = '\\'; + *lp++ = 'u'; + *lp++ = hex[(c>>12)&0xF]; + *lp++ = hex[(c>>8)&0xF]; + *lp++ = hex[(c>>4)&0xF]; + c = hex[c&0xF]; col += 5; + } else if (c>0xFFFF) { + *lp++ = '\\'; + *lp++ = 'U'; + *lp++ = hex[(c>>28)&0xF]; + *lp++ = hex[(c>>24)&0xF]; + *lp++ = hex[(c>>20)&0xF]; + *lp++ = hex[(c>>16)&0xF]; + *lp++ = hex[(c>>12)&0xF]; + *lp++ = hex[(c>>8)&0xF]; + *lp++ = hex[(c>>4)&0xF]; + c = hex[c&0xF]; + col += 9; } } } @@ -1574,7 +1597,7 @@ putchr(int ac) rune = c; lp += runetochar(lp, &rune); - if(c == '\n' || lp >= &line[sizeof(line)-5]) { + if(c == '\n' || lp >= &line[LINELEN-BELL]) { linp = line; write(oflag? 2: 1, line, lp-line); return; -- cgit v1.2.3 From 01b505613590f3107c4a8849b18da2cbefd98466 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 29 May 2020 21:42:54 -0400 Subject: ed(1): fix documentation for list mode I changed from 6 to 8 digits but forgot to update the man page. --- man/man1/ed.1 | 72 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/man/man1/ed.1 b/man/man1/ed.1 index 9b161b29..41071c7e 100644 --- a/man/man1/ed.1 +++ b/man/man1/ed.1 @@ -35,7 +35,7 @@ of character counts by .LR r , and .L w -commands and of the confirming +commands and of the confirming .L ! by .L ! @@ -46,7 +46,7 @@ commands. Write all output to the standard error file except writing by .L w commands. -If no +If no .I file is given, make .B /dev/stdout @@ -62,7 +62,7 @@ in the buffer have no effect on the file until a (write) command is given. The copy of the text being edited resides -in a temporary file called the +in a temporary file called the .IR buffer . .PP Commands to @@ -78,7 +78,7 @@ These addresses specify one or more lines in the buffer. Missing addresses are supplied by default. .PP In general, only one command may appear on a line. -Certain commands allow the +Certain commands allow the addition of text to the buffer. While .I ed @@ -87,13 +87,13 @@ to be in .I "input mode." In this mode, no commands are recognized; all input is merely collected. -Input mode is left by typing a period +Input mode is left by typing a period .L . alone at the beginning of a line. .PP .I Ed -supports the +supports the .I "regular expression" notation described in .IR regexp (7). @@ -108,7 +108,7 @@ the regular expression metacharacters as an ordinary character, that character may be preceded by .RB ` \e '. This also applies to the character bounding the regular -expression (often +expression (often .LR / ) and to .L \e @@ -132,7 +132,7 @@ customarily called `dot', addresses the current line. .TP 2. -The character +The character .L $ addresses the last line of the buffer. .TP @@ -163,7 +163,7 @@ If necessary the search wraps around to the beginning of the buffer. .TP 6. -A regular expression enclosed in queries +A regular expression enclosed in queries .L ? addresses the line found by searching backward from the current line @@ -173,7 +173,7 @@ If necessary the search wraps around to the end of the buffer. .TP 7. -An address followed by a plus sign +An address followed by a plus sign .L + or a minus sign .L - @@ -182,7 +182,7 @@ followed by a decimal number specifies that address plus The plus sign may be omitted. .TP 8. -An address followed by +An address followed by .L + (or .LR - ) @@ -190,20 +190,20 @@ followed by a regular expression enclosed in slashes specifies the first matching line following (or preceding) that address. The search wraps around if necessary. -The +The .L + may be omitted, so .L 0/x/ addresses the .I first -line in the buffer with an +line in the buffer with an .LR x . -Enclosing the regular expression in +Enclosing the regular expression in .L ? reverses the search direction. .TP 9. -If an address begins with +If an address begins with .L + or .L - @@ -214,7 +214,7 @@ is understood to mean .LR .-5 . .TP 10. -If an address ends with +If an address ends with .L + or .LR - , @@ -236,9 +236,9 @@ line less 2. .TP 11. To maintain compatibility with earlier versions of the editor, -the character +the character .L ^ -in addresses is +in addresses is equivalent to .LR - . .PP @@ -254,7 +254,7 @@ Addresses are separated from each other typically by a comma .LR , . They may also be separated by a semicolon .LR ; . -In this case the current line +In this case the current line is set to the previous address before the next address is interpreted. If no address precedes a comma or semicolon, line 1 is assumed; @@ -285,7 +285,7 @@ and append it after the addressed line. Dot is left on the last line input, if there were any, otherwise at the addressed line. -Address +Address .L 0 is legal for this command; text is placed at the beginning of the buffer. @@ -293,7 +293,7 @@ at the beginning of the buffer. .RB (\|\fL.,.\fP\|) \|b [ +- ][\fIpagesize\fP][ pln\fR] Browse. Print a `page', normally 20 lines. -The optional +The optional .L + (default) or .L - @@ -305,11 +305,11 @@ is the number of lines in a page. The optional .LR p , .LR n , -or +or .L l causes printing in the specified format, initially .LR p . -Pagesize and format are remembered between +Pagesize and format are remembered between .L b commands. Dot is left at the last line displayed. @@ -397,7 +397,7 @@ and .L v are not permitted in the command list. Any character other than space or newline may -be used instead of +be used instead of .L / to delimit the regular expression. The second and third forms mean @@ -452,7 +452,7 @@ and four hexadecimal digits; and characters above the Basic Multilingual Plane are printed as a backslash, a big .LR U , -and six hexadecimal digits. +and eight hexadecimal digits. Long lines are folded, with the second and subsequent sub-lines indented one tab stop. If the last character in the line is a blank, @@ -542,13 +542,13 @@ defaults to 1 if missing), the .IR n th matched string is replaced by the replacement specified. -If the global replacement indicator +If the global replacement indicator .L g appears after the command, all subsequent matches on the line are also replaced. It is an error for the substitution to fail on all addressed lines. Any character other than space or newline -may be used instead of +may be used instead of .L / to delimit the regular expression and the replacement. @@ -560,7 +560,7 @@ The second may be omitted if the replacement is empty. .IP -An ampersand +An ampersand .L & appearing in the replacement is replaced by the string matching the regular expression. @@ -584,7 +584,7 @@ is determined by counting occurrences of .L ( starting from the left. .IP -A literal +A literal .LR & , .LR / , .L \e @@ -594,7 +594,7 @@ by prefixing it with .TP .RB (\|\fL.,.\fP\|) \|t\|\fIa Transfer. -Copy the addressed lines +Copy the addressed lines after the line addressed by .IR a . Dot is left at the last line of the copy. @@ -622,7 +622,7 @@ it is created with mode 666 (readable and writable by everyone). If no .I filename is given, the remembered file name, if any, is used. -The file name is remembered if there were no +The file name is remembered if there were no remembered file name already. Dot is unchanged. If the write is successful, the number of characters written is @@ -638,7 +638,7 @@ Print the line number of the addressed line. Dot is unchanged. .TP .BI ! shell\ command -Send the remainder of the line after the +Send the remainder of the line after the .L ! to .IR rc (1) @@ -647,7 +647,7 @@ Dot is unchanged. .TP .RB (\| .+1 )\| An address without a command is taken as a -.L p +.L p command. A terminal .L / @@ -657,11 +657,11 @@ A blank line alone is equivalent to it is useful for stepping through text. .PP -If an interrupt signal +If an interrupt signal .SM (DEL) is sent, .I ed -prints a +prints a .L ? and returns to its command level. .PP @@ -679,7 +679,7 @@ and all characters after the last newline. .SH SOURCE .B \*9/src/cmd/ed.c .SH "SEE ALSO" -.IR sam (1), +.IR sam (1), .IR sed (1), .IR regexp (7) .SH DIAGNOSTICS -- cgit v1.2.3 From 799f330f6de8ff65a7bdf7e0d1b12cd3c10981ba Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 30 May 2020 06:35:27 -0400 Subject: osxvers: use swvers -productVersion to skip one awk call Fixes #406. Suggested by nms42. --- bin/osxvers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/osxvers b/bin/osxvers index 4af44da2..6ebeb11f 100755 --- a/bin/osxvers +++ b/bin/osxvers @@ -3,5 +3,5 @@ u=`uname` case "$u" in Darwin) - sw_vers | awk '$1 == "ProductVersion:" {print $2}' | awk -F. '{printf("CFLAGS=$CFLAGS -DOSX_VERSION=%d%02d%02d\n", $1, $2, $3)}' + sw_vers -productVersion | awk -F. '{printf("CFLAGS=$CFLAGS -DOSX_VERSION=%d%02d%02d\n", $1, $2, $3)}' esac -- cgit v1.2.3 From c3d31baca0a73a9e8033db8a0b47093233c636c1 Mon Sep 17 00:00:00 2001 From: Gregor Best Date: Thu, 4 Jun 2020 19:55:26 +0200 Subject: fontsrv: fix compilation on X11 (#420) --- src/cmd/fontsrv/x11.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c index 417dcfa6..c1d10197 100644 --- a/src/cmd/fontsrv/x11.c +++ b/src/cmd/fontsrv/x11.c @@ -61,6 +61,7 @@ load(XFont *f) FT_Error e; FT_ULong charcode; FT_UInt glyph_index; + int i; if(f->loaded) return; -- cgit v1.2.3 From 329831171dd6ef81c113f101093c7b4947381003 Mon Sep 17 00:00:00 2001 From: Xiao-Yong Date: Mon, 15 Jun 2020 22:18:03 -0500 Subject: libthread: use libc functions in ucontext for macOS (#417) --- src/libthread/Darwin-x86_64-asm.s | 44 --------------------------------------- src/libthread/sysofiles.sh | 4 ++-- src/libthread/threadimpl.h | 36 +------------------------------- 3 files changed, 3 insertions(+), 81 deletions(-) delete mode 100644 src/libthread/Darwin-x86_64-asm.s diff --git a/src/libthread/Darwin-x86_64-asm.s b/src/libthread/Darwin-x86_64-asm.s deleted file mode 100644 index d50d3b6d..00000000 --- a/src/libthread/Darwin-x86_64-asm.s +++ /dev/null @@ -1,44 +0,0 @@ -.text -.align 8 - -.globl _libthread_getmcontext -_libthread_getmcontext: - movq $1, 0*8(%rdi) // rax - movq %rbx, 1*8(%rdi) - movq %rcx, 2*8(%rdi) - movq %rdx, 3*8(%rdi) - movq %rsi, 4*8(%rdi) - movq %rdi, 5*8(%rdi) - movq %rbp, 6*8(%rdi) - movq %rsp, 7*8(%rdi) - movq %r8, 8*8(%rdi) - movq %r9, 9*8(%rdi) - movq %r10, 10*8(%rdi) - movq %r11, 11*8(%rdi) - movq %r12, 12*8(%rdi) - movq %r13, 13*8(%rdi) - movq %r14, 14*8(%rdi) - movq %r15, 15*8(%rdi) - movq $0, %rax - ret - -.globl _libthread_setmcontext -_libthread_setmcontext: - movq 0*8(%rdi), %rax - movq 1*8(%rdi), %rbx - movq 2*8(%rdi), %rcx - movq 3*8(%rdi), %rdx - movq 4*8(%rdi), %rsi - // %rdi later - movq 6*8(%rdi), %rbp - movq 7*8(%rdi), %rsp - movq 8*8(%rdi), %r8 - movq 9*8(%rdi), %r9 - movq 10*8(%rdi), %r10 - movq 11*8(%rdi), %r11 - movq 12*8(%rdi), %r12 - movq 13*8(%rdi), %r13 - movq 14*8(%rdi), %r14 - movq 15*8(%rdi), %r15 - movq 5*8(%rdi), %rdi - ret diff --git a/src/libthread/sysofiles.sh b/src/libthread/sysofiles.sh index 20811cdf..833afbe0 100644 --- a/src/libthread/sysofiles.sh +++ b/src/libthread/sysofiles.sh @@ -15,14 +15,14 @@ esac # Various libc don't supply swapcontext, makecontext, so we do. case "$SYSNAME-$OBJTYPE" in -Darwin-x86_64 | Linux-arm | Linux-sparc64 | NetBSD-arm | OpenBSD-386 | OpenBSD-power | OpenBSD-x86_64) +Linux-arm | Linux-sparc64 | NetBSD-arm | OpenBSD-386 | OpenBSD-power | OpenBSD-x86_64) echo $OBJTYPE-ucontext.o ;; esac # A few libc don't supply setcontext, getcontext, so we do. case "$SYSNAME-$OBJTYPE" in -Darwin-x86_64 | Linux-arm | Linux-sparc64 | OpenBSD-386 | OpenBSD-power | OpenBSD-x86_64) +Linux-arm | Linux-sparc64 | OpenBSD-386 | OpenBSD-power | OpenBSD-x86_64) echo $SYSNAME-$OBJTYPE-asm.o ;; esac diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index c7373843..8d22a161 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -7,7 +7,7 @@ #include #if !defined(__OpenBSD__) # if defined(__APPLE__) -# define _XOPEN_SOURCE /* for Snow Leopard */ +# define _XOPEN_SOURCE /* for Snow Leopard */ # endif # include #endif @@ -15,31 +15,6 @@ #include "libc.h" #include "thread.h" -#if defined(__APPLE__) - /* - * OS X before 10.5 (Leopard) does not provide - * swapcontext nor makecontext, so we have to use our own. - * In theory, Leopard does provide them, but when we use - * them, they seg fault. Maybe we're using them wrong. - * So just use our own versions, even on Leopard. - */ -# define mcontext libthread_mcontext -# define mcontext_t libthread_mcontext_t -# define ucontext libthread_ucontext -# define ucontext_t libthread_ucontext_t -# define swapcontext libthread_swapcontext -# define makecontext libthread_makecontext -# if defined(__i386__) -# include "386-ucontext.h" -# elif defined(__x86_64__) -# include "x86_64-ucontext.h" -# elif defined(__ppc__) || defined(__power__) -# include "power-ucontext.h" -# else -# error "unknown architecture" -# endif -#endif - #if defined(__OpenBSD__) # define mcontext libthread_mcontext # define mcontext_t libthread_mcontext_t @@ -82,15 +57,6 @@ enum struct Context { ucontext_t uc; -#ifdef __APPLE__ - /* - * On Snow Leopard, etc., the context routines exist, - * so we use them, but apparently they write past the - * end of the ucontext_t. Sigh. We put some extra - * scratch space here for them. - */ - uchar buf[1024]; -#endif }; struct Execjob -- cgit v1.2.3