aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xINSTALL7
-rwxr-xr-xbin/9c49
-rwxr-xr-xbin/9l24
-rwxr-xr-xbin/osxvers2
-rwxr-xr-xdist/buildmk2
-rw-r--r--include/draw.h5
-rw-r--r--include/drawfcall.h11
-rw-r--r--include/libc.h6
-rw-r--r--include/u.h10
-rw-r--r--lib/keyboard1
-rw-r--r--man/man1/acid.130
-rw-r--r--man/man1/acme.18
-rw-r--r--man/man1/ed.182
-rw-r--r--man/man1/install.19
-rw-r--r--man/man1/rc.14
-rw-r--r--man/man1/sam.128
-rw-r--r--man/man3/cachechars.32
-rw-r--r--man/man7/keyboard.721
-rw-r--r--src/cmd/9term/AIX.c2
-rw-r--r--src/cmd/9term/bsdpty.c2
-rw-r--r--src/cmd/acme/regx.c3
-rw-r--r--src/cmd/auxstats/AIX.c9
-rw-r--r--src/cmd/devdraw/devdraw.c30
-rw-r--r--src/cmd/devdraw/devdraw.h28
-rw-r--r--src/cmd/devdraw/latin1.c39
-rw-r--r--src/cmd/devdraw/mac-screen.m43
-rw-r--r--src/cmd/devdraw/mklatinkbd.c2
-rw-r--r--src/cmd/devdraw/srv.c35
-rw-r--r--src/cmd/devdraw/x11-screen.c21
-rw-r--r--src/cmd/diff/diffreg.c3
-rw-r--r--src/cmd/draw/mc.c3
-rw-r--r--src/cmd/ed.c41
-rw-r--r--src/cmd/fontsrv/a.h9
-rw-r--r--src/cmd/fontsrv/mac.c6
-rw-r--r--src/cmd/fontsrv/main.c53
-rw-r--r--src/cmd/fontsrv/x11.c22
-rw-r--r--src/cmd/mk/archive.c4
-rw-r--r--src/cmd/mk/env.c3
-rw-r--r--src/cmd/mkfile2
-rw-r--r--src/cmd/rc/rc.h6
-rw-r--r--src/cmd/vbackup/mount-AIX.c1
-rw-r--r--src/lib9/create.c75
-rw-r--r--src/lib9/dirread.c207
-rw-r--r--src/lib9/fmt/fmt.c21
-rw-r--r--src/lib9/mkfile3
-rw-r--r--src/lib9/open.c293
-rw-r--r--src/lib9/readcons.c2
-rw-r--r--src/lib9/seek.c8
-rw-r--r--src/libdiskfs/ext2.h33
-rw-r--r--src/libdiskfs/ffs.h33
-rw-r--r--src/libdraw/drawclient.c2
-rw-r--r--src/libdraw/drawfcall.c15
-rw-r--r--src/libdraw/event.c2
-rw-r--r--src/libdraw/openfont.c2
-rw-r--r--src/libip/AIX.c1
-rw-r--r--src/libmach/AIX.c1
-rw-r--r--src/libthread/Darwin-x86_64-asm.s44
-rw-r--r--src/libthread/channel.c2
-rw-r--r--src/libthread/pthread.c37
-rw-r--r--src/libthread/sysofiles.sh4
-rw-r--r--src/libthread/thread.c92
-rw-r--r--src/libthread/threadimpl.h69
-rw-r--r--src/mkenv1
-rw-r--r--src/mkfile3
-rw-r--r--src/mkhdr3
-rw-r--r--src/mkmk.sh8
66 files changed, 987 insertions, 642 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
diff --git a/bin/9c b/bin/9c
index 0f836d24..a22a0a08 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,7 +84,31 @@ 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}
+ cflags=" \
+ -c \
+ -O0 \
+ -qmaxmem=-1 \
+ -qsuppress=1506-236 \
+ -qsuppress=1506-358 \
+ -qsuppress=1500-010 \
+ -qsuppress=1506-224 \
+ -qsuppress=1506-1300 \
+ -qsuppress=1506-342 \
+ "
+ cflags="$cflags -g -qfullpath"
+ cflags="$cflags $CC9FLAGS"
}
tag="${SYSNAME:-`uname`}-${OBJTYPE:-`uname -m`}-${CC9:-cc}"
@@ -88,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
@@ -117,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*) usegcc
- cflags="$ngflags -g -D__AIX__"
+*AIX*) usexlc
+ 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 a10aab72..b4f91584 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,8 +61,8 @@ case "$tag" in
esac
;;
*AIX*)
- ld=${CC9:-gcc}
- nmflags="-B"
+ ld="${CC9:-xlc_r} -g -O0 $CC9FLAGS"
+ nmflags="-A -B"
;;
*)
echo do not know how to link on "$tag" 1>&2
@@ -113,8 +113,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 +144,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/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
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/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/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/include/libc.h b/include/libc.h
index 4fa86b22..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*);
@@ -747,7 +747,7 @@ extern int awaitnohang(char*, int);
/* extern int bind(char*, char*, int); give up */
/* extern int brk(void*); <unistd.h> */
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/include/u.h b/include/u.h
index 3bea890e..f84e348a 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 */
@@ -20,7 +22,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,10 +35,8 @@ extern "C" {
# define __LONG_LONG_SUPPORTED
#endif
#if defined(__AIX__)
-# define _XOPEN_SOURCE 1
-#endif
-#if defined(__APPLE__)
-# define _DARWIN_NO_64_BIT_INODE /* Snow Leopard */
+# define _ALL_SOURCE
+# undef HAS_SYS_TERMIOS
#endif
#define _LARGEFILE64_SOURCE 1
#define _FILE_OFFSET_BITS 64
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/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/ed.1 b/man/man1/ed.1
index 00eb095a..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
@@ -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 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,
@@ -534,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.
@@ -552,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.
@@ -576,7 +584,7 @@ is determined by counting occurrences of
.L (
starting from the left.
.IP
-A literal
+A literal
.LR & ,
.LR / ,
.L \e
@@ -586,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.
@@ -614,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
@@ -630,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)
@@ -639,7 +647,7 @@ Dot is unchanged.
.TP
.RB (\| .+1 )\|<newline>
An address without a command is taken as a
-.L p
+.L p
command.
A terminal
.L /
@@ -649,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
@@ -671,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
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
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
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/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/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 <errno.h>
#include <grp.h>
#include <termios.h>
+#ifdef HAS_SYS_TERMIOS
#include <sys/termios.h>
+#endif
#ifdef __linux__
#include <pty.h>
#endif
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
*/
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 <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "dat.h"
+
+void (*statfn[])(int) =
+{
+ 0
+};
diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c
index b4c373ad..234cdf1b 100644
--- a/src/cmd/devdraw/devdraw.c
+++ b/src/cmd/devdraw/devdraw.c
@@ -14,6 +14,8 @@
#include <drawfcall.h>
#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);
- rpc_flush(c, fr);
- qlock(&c->drawlk);
+ qunlock(&drawlk);
+ c->impl->rpc_flush(c, fr);
+ 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);
- rpc_flush(c, r);
- qlock(&c->drawlk);
+ qunlock(&drawlk);
+ c->impl->rpc_flush(c, r);
+ 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 6829ab32..261d04d1 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,20 @@ 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);
+};
+
+extern QLock drawlk;
+
struct Client
{
int rfd;
@@ -56,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;
@@ -82,6 +96,7 @@ struct Client
int nname;
DName* name;
int namevers;
+ ClientImpl* impl;
// Only accessed/modified by the graphics thread.
const void* view;
@@ -196,17 +211,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/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<n; i++,k++){
c <<= 4;
if('0'<=*k && *k<='9')
c += *k-'0';
@@ -36,6 +35,8 @@ unicode(Rune *k)
c += 10 + *k-'A';
else
return -1;
+ if(c > 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++)
diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m
index c6e58341..ad9c029e 100644
--- a/src/cmd/devdraw/mac-screen.m
+++ b/src/cmd/devdraw/mac-screen.m
@@ -37,6 +37,26 @@ 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_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 +221,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 +323,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 +340,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 +365,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 +481,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;
@@ -474,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;
@@ -506,7 +527,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 +562,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 +717,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 +1116,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/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 570091bc..05a08fda 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;
@@ -225,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);
@@ -232,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;
@@ -241,35 +246,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 +311,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;
}
@@ -353,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++];
@@ -513,7 +522,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){
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;
}
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;
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 <u.h>
#include <sys/ioctl.h>
+#include <termios.h>
+#ifdef HAS_SYS_TERMIOS
#include <sys/termios.h>
+#endif
#include <libc.h>
#include <draw.h>
#include <bio.h>
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;
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; i<nelem(f->range); 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; j<nelem(f->range); 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; i<nelem(f->range); 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; i<f->nfile; 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..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;
@@ -78,27 +79,30 @@ 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)) {
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; i<nelem(f->range); i++)
+ if(f->range[i])
+ f->file[f->nfile++] = i;
+
f->loaded = 1;
}
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 "<bigaf>\n"
+#else
#define ARMAG "!<arch>\n"
+#endif
#define SARMAG (sizeof(ARMAG) - sizeof(""))
#define ARFMAG "`\n"
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;
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/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;
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/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 <u.h>
-#define NOPLAN9DEFINES
-#include <sys/file.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <libc.h>
-#include <sys/stat.h>
-#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 <u.h>
-#define NOPLAN9DEFINES
-#include <libc.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-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; i<n; i++){
- de = (struct dirent*)p;
- memset(&lst, 0, sizeof lst);
- if(de->d_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; i<n; i++){
- de = (struct dirent*)p;
- if(de->d_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/fmt/fmt.c b/src/lib9/fmt/fmt.c
index a86482c3..47b186a4 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 <stdarg.h>
#include <string.h>
+
+/*
+ * 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.9).
+ * AIX is using its own IBM compiler (XL C).
+ */
+#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))
+#define atomic_store(x, y) (*(x)=(y))
+#define ATOMIC_VAR_INIT(x) (x)
+#else
#include <stdatomic.h>
+#endif
+
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
diff --git a/src/lib9/mkfile b/src/lib9/mkfile
index 7c37de42..db267dfe 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\
@@ -141,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 a0573ae7..2354268b 100644
--- a/src/lib9/open.c
+++ b/src/lib9/open.c
@@ -1,11 +1,140 @@
#define _GNU_SOURCE /* for Linux O_DIRECT */
#include <u.h>
-#define NOPLAN9DEFINES
+#include <dirent.h>
+#include <errno.h>
#include <sys/file.h>
+#include <sys/stat.h>
+#define NOPLAN9DEFINES
#include <libc.h>
-#ifndef O_DIRECT
-#define O_DIRECT 0
-#endif
+
+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<nd; i++)
+ dp[i] = nil;
+ dirs.d = dp;
+ dirs.nd = nd;
+ }
+ dirs.d[fd] = d;
+ unlock(&dirs.lk);
+ return 0;
+}
+
+static DIR*
+dirget(int fd)
+{
+ DIR *d;
+
+ lock(&dirs.lk);
+ d = nil;
+ if(0 <= fd && fd < dirs.nd)
+ d = dirs.d[fd];
+ unlock(&dirs.lk);
+ return d;
+}
+
+static DIR*
+dirdel(int fd)
+{
+ DIR *d;
+
+ lock(&dirs.lk);
+ d = nil;
+ if(0 <= fd && fd < dirs.nd) {
+ d = dirs.d[fd];
+ dirs.d[fd] = nil;
+ }
+ unlock(&dirs.lk);
+ return d;
+}
+
+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)
@@ -13,6 +142,8 @@ p9open(char *name, int mode)
int cexec, rclose;
int fd, umode, lock, rdwr;
struct flock fl;
+ struct stat st;
+ DIR *d;
rdwr = mode&3;
umode = rdwr;
@@ -55,8 +186,162 @@ p9open(char *name, int mode)
}
if(cexec)
fcntl(fd, F_SETFL, FD_CLOEXEC);
+ if(fstat(fd, &st) >= 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);
}
return fd;
}
+
+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);
+}
+
+typedef struct DirBuild DirBuild;
+struct DirBuild {
+ Dir *d;
+ int nd;
+ int md;
+ char *str;
+ char *estr;
+};
+
+extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*);
+
+static int
+dirbuild1(DirBuild *b, struct stat *lst, struct stat *st, char *name)
+{
+ 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; i<b->nd; 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;
+ }
+ _p9dir(lst, st, name, &b->d[b->nd], &b->str, b->estr);
+ b->nd++;
+ return 0;
+}
+
+static long
+dirreadmax(int fd, Dir **dp, int max)
+{
+ int i;
+ DIR *dir;
+ DirBuild b;
+ struct dirent *de;
+ struct stat st, lst;
+
+ if((dir = dirget(fd)) == nil) {
+ werrstr("not a directory");
+ return -1;
+ }
+
+ memset(&b, 0, sizeof b);
+ for(i=0; max == -1 || i<max; i++) { // max = not too many, not too few
+ errno = 0;
+ de = readdir(dir);
+ if(de == nil) {
+ if(b.nd == 0 && errno != 0)
+ return -1;
+ break;
+ }
+ // 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)
+ 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);
+ }
+ *dp = b.d;
+ return b.nd;
+}
+
+long
+dirread(int fd, Dir **dp)
+{
+ return dirreadmax(fd, dp, 10);
+}
+
+long
+dirreadall(int fd, Dir **dp)
+{
+ return dirreadmax(fd, dp, -1);
+}
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 <libc.h>
#include <termios.h>
+#ifdef HAS_SYS_TERMIOS
#include <sys/termios.h>
+#endif
static int
rawx(int fd, int echoing)
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 <u.h>
-#include <libc.h>
-
-vlong
-seek(int fd, vlong offset, int whence)
-{
- return lseek(fd, offset, whence);
-}
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,
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)
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);
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"
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/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..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;
}
@@ -99,6 +101,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 +135,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/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/thread.c b/src/libthread/thread.c
index f657b5b2..902942d9 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*);
@@ -53,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*
@@ -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,37 @@ 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)
+{
+ _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");
+ }
+ 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);
+}
+
void
_threadswitch(void)
{
@@ -216,9 +252,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 +386,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 +450,13 @@ 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);
+ _threaddebug("back in scheduler");
/*print("back in scheduler\n"); */
goto Top;
}
@@ -545,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;
}
@@ -569,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;
}
@@ -757,10 +819,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") == nil && getenv("NOLIBTHREADDAEMONIZE") == nil)
_threadsetupdaemonize();
threadargc = argc;
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
index cceb1b8e..8d22a161 100644
--- a/src/libthread/threadimpl.h
+++ b/src/libthread/threadimpl.h
@@ -7,7 +7,7 @@
#include <signal.h>
#if !defined(__OpenBSD__)
# if defined(__APPLE__)
-# define _XOPEN_SOURCE /* for Snow Leopard */
+# define _XOPEN_SOURCE /* for Snow Leopard */
# endif
# include <ucontext.h>
#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
@@ -102,6 +68,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 +89,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 +102,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 +121,7 @@ struct Proc
#endif
Lock lock;
int nswitch;
+ _Thread *thread0;
_Thread *thread;
_Thread *pinthread;
_Threadlist runqueue;
@@ -157,6 +130,8 @@ struct Proc
uint nthread;
uint sysproc;
_Procrendez runrend;
+ Lock schedlock;
+ _Thread *schedthread;
Context schedcontext;
void *udata;
Jmp sigjmp;
@@ -188,6 +163,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))
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 dae87ddf..dfccd369 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
@@ -75,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
@@ -109,6 +106,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 +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 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 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,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 ..