summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-23 00:30:12 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-23 00:30:12 +0000
commit6e425a9de8c003b5a733621a6b6730ec3cc902b8 (patch)
tree314123bcab78ff295f38f85f31dc141e5fe22d15 /emu
parent74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (diff)
20061220
Diffstat (limited to 'emu')
-rw-r--r--emu/FreeBSD/asm-386.S3
-rw-r--r--emu/FreeBSD/cmd.c25
-rw-r--r--emu/FreeBSD/ipif.c5
-rw-r--r--emu/Hp/cmd.c26
-rw-r--r--emu/Irix/cmd.c26
-rw-r--r--emu/Linux/asm-386.S6
-rw-r--r--emu/Linux/asm-arm.S131
-rw-r--r--emu/Linux/asm-power.S72
-rw-r--r--emu/Linux/cmd.c26
-rw-r--r--emu/Linux/emu-g96
-rw-r--r--emu/Linux/mkfile2
-rw-r--r--emu/Linux/os.c12
-rw-r--r--emu/Linux/segflush-power.c27
-rw-r--r--emu/MacOSX/NOTICE1
-rw-r--r--emu/MacOSX/asm-386.s28
-rw-r--r--emu/MacOSX/cmd.c25
-rw-r--r--emu/MacOSX/mkfile5
-rw-r--r--emu/MacOSX/os.c2
-rw-r--r--emu/NOTICE1
-rw-r--r--emu/Nt/cmd.c84
-rw-r--r--emu/Nt/os.c105
-rw-r--r--emu/Nt/win.c130
-rw-r--r--emu/Plan9/cmd.c29
-rw-r--r--emu/Plan9/win.c69
-rw-r--r--emu/Solaris/cmd.c28
-rw-r--r--emu/Unixware/cmd.c28
-rw-r--r--emu/mkfile2
-rw-r--r--emu/port/chan.c1
-rw-r--r--emu/port/dev.c2
-rw-r--r--emu/port/devcmd.c88
-rw-r--r--emu/port/devcons.c334
-rw-r--r--emu/port/devmem.c1
-rw-r--r--emu/port/devprof.c18
-rw-r--r--emu/port/error.h3
-rw-r--r--emu/port/exportfs.c2
-rw-r--r--emu/port/fns.h2
-rw-r--r--emu/port/inferno.c3
37 files changed, 898 insertions, 550 deletions
diff --git a/emu/FreeBSD/asm-386.S b/emu/FreeBSD/asm-386.S
index 2d11c6da..35269c8f 100644
--- a/emu/FreeBSD/asm-386.S
+++ b/emu/FreeBSD/asm-386.S
@@ -95,10 +95,7 @@ FPrestore:
.type getcallerpc,@function
.global getcallerpc
getcallerpc:
- pushl %ebp
- movl %esp, %ebp
movl 4(%ebp), %eax
- popl %ebp
ret
.type _tas,@function
diff --git a/emu/FreeBSD/cmd.c b/emu/FreeBSD/cmd.c
index 55ead029..ed4cabab 100644
--- a/emu/FreeBSD/cmd.c
+++ b/emu/FreeBSD/cmd.c
@@ -21,7 +21,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -43,15 +43,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -82,10 +84,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -93,14 +95,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -130,6 +134,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -137,6 +142,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -145,8 +151,9 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -157,6 +164,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/FreeBSD/ipif.c b/emu/FreeBSD/ipif.c
index 491eff15..07065714 100644
--- a/emu/FreeBSD/ipif.c
+++ b/emu/FreeBSD/ipif.c
@@ -273,7 +273,8 @@ int
so_gethostbyname(char *host, char**hostv, int n)
{
int i;
- unsigned char buf[32], *p;
+ char buf[32];
+ uchar *p;
struct hostent *hp;
hp = gethostbyname(host);
@@ -282,7 +283,7 @@ so_gethostbyname(char *host, char**hostv, int n)
for(i = 0; hp->h_addr_list[i] && i < n; i++) {
p = hp->h_addr_list[i];
- sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
+ snprint(buf, sizeof(buf), "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
hostv[i] = strdup(buf);
if(hostv[i] == 0)
break;
diff --git a/emu/Hp/cmd.c b/emu/Hp/cmd.c
index 97e303ac..bff1f03b 100644
--- a/emu/Hp/cmd.c
+++ b/emu/Hp/cmd.c
@@ -21,7 +21,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -43,15 +43,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -82,11 +84,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
- Dir *d;
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -94,14 +95,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -131,6 +134,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -138,6 +142,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -146,8 +151,9 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -158,6 +164,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/Irix/cmd.c b/emu/Irix/cmd.c
index 97e303ac..bff1f03b 100644
--- a/emu/Irix/cmd.c
+++ b/emu/Irix/cmd.c
@@ -21,7 +21,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -43,15 +43,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -82,11 +84,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
- Dir *d;
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -94,14 +95,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -131,6 +134,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -138,6 +142,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -146,8 +151,9 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -158,6 +164,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/Linux/asm-386.S b/emu/Linux/asm-386.S
index caa1f79a..31946335 100644
--- a/emu/Linux/asm-386.S
+++ b/emu/Linux/asm-386.S
@@ -94,12 +94,6 @@ FPrestore:
popl %ebp
ret
- .type getcallerpc,@function
- .global getcallerpc
-getcallerpc:
- movl 4(%ebp), %eax
- ret
-
.type _tas,@function
.globl _tas
_tas:
diff --git a/emu/Linux/asm-arm.S b/emu/Linux/asm-arm.S
new file mode 100644
index 00000000..1cdac444
--- /dev/null
+++ b/emu/Linux/asm-arm.S
@@ -0,0 +1,131 @@
+ .file "asm-Linux-arm.S"
+#include "syscall.h"
+ .text
+
+/*
+ * void executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
+ */
+
+ .align 2
+ .global executeonnewstack
+ .type executeonnewstack, %function
+executeonnewstack:
+ @ args = 0, pretend = 0, frame = 12
+ @ frame_needed = 1, uses_anonymous_args = 0
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #12
+ str r0, [fp, #-16] /* store tos */
+ str r1, [fp, #-20] /* store tramp */
+ str r2, [fp, #-24] /* store arg */
+ ldr r0, [fp, #-24] /* get arg */
+ ldr r2, [fp, #-16] /* get tos */
+ mov sp, r2 /* set new stack */
+ mov lr, pc
+ blx r1 /* call tramp*/
+
+ /* if we return here, tramp didn't do it's job */
+ swi SYS_exit
+ ldmea fp, {fp, sp, pc}
+ .size executeonnewstack, .-executeonnewstack
+
+/*
+ * void unlockandexit(int *key)
+ *
+ * NB: the return status may be garbaged if the stack is reused
+ * between the unlock and the system call, but this should
+ * not matter since no task is waiting for the result
+ */
+
+ .align 2
+ .global unlockandexit
+ .type unlockandexit, %function
+unlockandexit:
+ @ args = 0, pretend = 0, frame = 4
+ @ frame_needed = 1, uses_anonymous_args = 0
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #4
+ mov r1, #0
+ str r1, [r0]
+ swi SYS_exit
+ ldmea fp, {fp, sp, pc}
+ .size unlockandexit, .-unlockandexit
+
+/*
+ * ulong umult(ulong m1, ulong m2, ulong *hi)
+ */
+
+ .align 2
+ .global umult
+ .type umult, %function
+umult:
+ @ args = 0, pretend = 0, frame = 12
+ @ frame_needed = 1, uses_anonymous_args = 0
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #12
+ str r0, [fp, #-16]
+ str r1, [fp, #-20]
+ str r2, [fp, #-24]
+ ldr r1, [fp, #-16]
+ ldr r2, [fp, #-20]
+ umull r0, r3, r1, r2
+ ldr r1, [fp, #-24]
+ str r3, [r1]
+ ldmea fp, {fp, sp, pc}
+ .size umult, .-umult
+
+/*
+ * void FPsave(void*);
+ */
+
+ .align 2
+ .global FPsave
+ .type FPsave, %function
+FPsave:
+ @ args = 0, pretend = 0, frame = 4
+ @ frame_needed = 1, uses_anonymous_args = 0
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #4
+ str r0, [fp, #-16]
+ ldmea fp, {fp, sp, pc}
+ .size FPsave, .-FPsave
+
+/*
+ * void FPrestore(void*);
+ */
+ .align 2
+ .global FPrestore
+ .type FPrestore, %function
+FPrestore:
+ @ args = 0, pretend = 0, frame = 4
+ @ frame_needed = 1, uses_anonymous_args = 0
+ mov ip, sp
+ stmfd sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #4
+ str r0, [fp, #-16]
+ ldmea fp, {fp, sp, pc}
+ .size FPrestore, .-FPrestore
+
+/*
+ * ulong _tas(ulong*);
+ */
+ .align 2
+ .global _tas
+ .type _tas, %function
+_tas:
+ @ args = 0, pretend = 0, frame = 0
+ @ frame_needed = 0, uses_anonymous_args = 0
+ @ link register save eliminated.
+ @ lr needed for prologue
+ mov r3, #1
+ swp r0, r3, [r0]
+ mov pc, lr
+ .size _tas, .-_tas
diff --git a/emu/Linux/asm-power.S b/emu/Linux/asm-power.S
new file mode 100644
index 00000000..ff5f97cd
--- /dev/null
+++ b/emu/Linux/asm-power.S
@@ -0,0 +1,72 @@
+#include <asm-ppc/reg.h>
+
+ .file "asm-power.S"
+ .section ".text"
+ .align 2
+ .globl FPsave
+ .type FPsave, @function
+FPsave:
+ .set _framesize,0
+ mffs f0
+ stfd f0,0(r3)
+ blr
+ .size FPsave,.-FPsave
+
+ .align 2
+ .globl FPrestore
+FPrestore:
+ lfd f0,0(r3)
+ mtfsf 0xff,f0
+ blr
+ .size FPrestore, .-FPrestore
+
+ .align 2
+ .globl _tas
+_tas:
+ sync
+ mr r4,r3
+ addi r5,0,0x1
+1:
+ lwarx r3,0,r4
+ cmpwi r3,0x0
+ bne- 2f
+ stwcx. r5,0,r4
+ bne- 1b /* Lost reservation, try again */
+2:
+ sync
+ blr
+ .size _tas,.-_tas
+
+/*
+ * void executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
+ */
+ .align 2
+ .globl executeonnewstack:
+executeonnewstack:
+ mr r1,r3 /* change stacks */
+ stwu 1,-16(r1) /* save lr to aid the traceback */
+ li r0,0
+ stw r0,20(r1)
+ mr r3,r5
+ mtctr r4
+ bctrl /* tramp(arg) */
+ br . /* failed */
+ .size executeonnewstack,.-executeonnewstack
+
+/*
+ * void unlockandexit(int *key)
+ *
+ * NB: the return status may be garbaged if the stack is reused
+ * between the unlock and the system call, but this should
+ * not matter since no task is waiting for the result
+ */
+ .align 2
+ .globl unlockandexit
+unlockandexit:
+ li r0,0x0
+ stw r0,0(r3) /* unlock */
+ li r0,1 /* sys exit; 234 is exit group */
+ li r3,0 /* exit status */
+ sc
+ br . /* not reached */
+ .size unlockandexit,.-unlockandexit
diff --git a/emu/Linux/cmd.c b/emu/Linux/cmd.c
index 2f55c427..0b8c960b 100644
--- a/emu/Linux/cmd.c
+++ b/emu/Linux/cmd.c
@@ -21,7 +21,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -43,15 +43,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -82,10 +84,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -93,14 +95,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -130,6 +134,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -137,6 +142,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -145,19 +151,21 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
r = errno;
- free(t);
if(Debug)
print("oscmd: %q\n",strerror(r));
close(fd0[0]);
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/Linux/emu-g b/emu/Linux/emu-g
new file mode 100644
index 00000000..8892d7a9
--- /dev/null
+++ b/emu/Linux/emu-g
@@ -0,0 +1,96 @@
+dev
+ root
+ cons
+ env
+ mnt
+ pipe
+ prog
+ prof
+ srv
+ dup
+ ssl
+ cap
+ fs
+ cmd cmd
+ indir
+
+ ip ipif-posix ipaux
+ eia
+# audio audio
+ mem
+
+lib
+ interp
+ math
+ keyring
+ sec
+ mp
+
+ 9
+
+link
+
+mod
+ sys
+ math
+ srv srv
+ keyring
+ loader
+
+port
+ alloc
+ cache
+ chan
+ dev
+ dial
+ dis
+ discall
+ env
+ error
+ errstr
+ exception
+ exportfs
+ inferno
+ latin1
+ main
+ parse
+ pgrp
+ print
+ proc
+ qio
+ random
+ sysfile
+ uqid
+
+code
+ int dontcompile = 1;
+ int macjit = 1;
+ void setpointer(int x, int y){USED(x); USED(y);}
+ ulong strtochan(char *s){USED(s); return ~0;}
+
+init
+ emuinit
+
+root
+ /dev /
+ /fd /
+ /prog /
+ /net /
+ /net.alt /
+ /chan /
+ /nvfs /
+ /env /
+# /chan
+# /dev
+# /dis
+# /env
+# /n
+# /net
+# /nvfs /
+# /prog
+# /icons
+# /osinit.dis
+# /dis/emuinit.dis
+# /dis/lib/auth.dis
+# /dis/lib/ssl.dis
+# /n/local /
diff --git a/emu/Linux/mkfile b/emu/Linux/mkfile
index fd6e89e7..ee2152d0 100644
--- a/emu/Linux/mkfile
+++ b/emu/Linux/mkfile
@@ -1,8 +1,6 @@
SYSTARG=Linux
-OBJTYPE=386
<../../mkconfig
SYSTARG=Linux
-OBJTYPE=386
#Configurable parameters
diff --git a/emu/Linux/os.c b/emu/Linux/os.c
index f541311f..336d0443 100644
--- a/emu/Linux/os.c
+++ b/emu/Linux/os.c
@@ -521,3 +521,15 @@ stackalloc(Proc *p, void **tos)
*(Proc **)rv = p;
return rv;
}
+
+#ifdef LINUX_ARM
+#define SYS_cacheflush __ARM_NR_cacheflush
+
+int
+segflush(void *a, ulong n)
+{
+ if(n)
+ syscall(SYS_cacheflush, a, (char*)a+n-1, 1);
+ return 0;
+}
+#endif
diff --git a/emu/Linux/segflush-power.c b/emu/Linux/segflush-power.c
new file mode 100644
index 00000000..07f9a3cb
--- /dev/null
+++ b/emu/Linux/segflush-power.c
@@ -0,0 +1,27 @@
+/*
+ * from geoff collyer's port
+ * invalidate instruction cache and write back data cache from a to a+n-1,
+ * at least.
+ */
+void
+segflush(void *a, ulong n)
+{
+ ulong *p;
+
+ // cache blocks are often eight words (32 bytes) long, sometimes 16 bytes.
+ // need to determine it dynamically?
+ for (p = (ulong *)((ulong)a & ~3UL); (char *)p < (char *)a + n; p++)
+ __asm__("dcbst 0,%0\n\t" // not dcbf, which writes back, then invalidates
+ "icbi 0,%0\n\t"
+ : // no output
+ : "ar" (p)
+ );
+ __asm__("sync\n\t"
+ : // no output
+ :
+ );
+ __asm__("isync\n\t"
+ : // no output
+ :
+ );
+}
diff --git a/emu/MacOSX/NOTICE b/emu/MacOSX/NOTICE
index cf4f254f..a14c52c9 100644
--- a/emu/MacOSX/NOTICE
+++ b/emu/MacOSX/NOTICE
@@ -1,2 +1,3 @@
MacOSX port Copyright © 2001-2003 Corpus Callosum Corporation,
with portions Copyright © 2001-2003 Geoff Collyer
+MacOSX-x86 Copyright © 2006 Corpus Callosum Corporation
diff --git a/emu/MacOSX/asm-386.s b/emu/MacOSX/asm-386.s
new file mode 100644
index 00000000..fc903bcb
--- /dev/null
+++ b/emu/MacOSX/asm-386.s
@@ -0,0 +1,28 @@
+/*
+ * these are the same as on the PC (eg, Linux)
+*/
+
+ .globl _FPsave
+_FPsave:
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ fstenv (%eax)
+ popl %ebp
+ ret
+
+ .globl _FPrestore
+_FPrestore:
+ pushl %ebp
+ movl %esp, %ebp
+ movl 8(%ebp), %eax
+ fldenv (%eax)
+ popl %ebp
+ ret
+
+ .globl __tas
+__tas:
+ movl $1, %eax
+ movl 4(%esp), %ecx
+ xchgl %eax, 0(%ecx)
+ ret
diff --git a/emu/MacOSX/cmd.c b/emu/MacOSX/cmd.c
index 49825f3c..58f6dba7 100644
--- a/emu/MacOSX/cmd.c
+++ b/emu/MacOSX/cmd.c
@@ -22,7 +22,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -44,15 +44,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -83,10 +85,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -94,14 +96,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -131,6 +135,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -138,6 +143,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -146,8 +152,9 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -158,6 +165,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/MacOSX/mkfile b/emu/MacOSX/mkfile
index 693eaf33..25fb99c6 100644
--- a/emu/MacOSX/mkfile
+++ b/emu/MacOSX/mkfile
@@ -1,8 +1,8 @@
SYSTARG=MacOSX
-OBJTYPE=power
+#OBJTYPE=power
<../../mkconfig
SYSTARG=MacOSX
-OBJTYPE=power
+#OBJTYPE=power
#Configurable parameters
@@ -30,6 +30,7 @@ OBJ=\
HFILES=\
CFLAGS='-DROOT="'$ROOT'"'\
+ '-DOBJTYPE="'$OBJTYPE'"'\
-DEMU -I. -I../port\
-I$ROOT/$SYSTARG/$OBJTYPE/include\
-I$ROOT/include -I$ROOT/libinterp\
diff --git a/emu/MacOSX/os.c b/emu/MacOSX/os.c
index e246f625..3363b5ad 100644
--- a/emu/MacOSX/os.c
+++ b/emu/MacOSX/os.c
@@ -42,7 +42,7 @@ enum
DELETE = 0x7F
};
char *hosttype = "MacOSX";
-char *cputype = "power";
+char *cputype = OBJTYPE;
static pthread_key_t prdakey;
diff --git a/emu/NOTICE b/emu/NOTICE
index 39682bb2..b071f58e 100644
--- a/emu/NOTICE
+++ b/emu/NOTICE
@@ -10,6 +10,7 @@ file such as NOTICE, LICENCE or COPYING.
Portions Copyright © 1997-1999 Vita Nuova Limited
Portions Copyright © 2000-2006 Vita Nuova Holdings Limited (www.vitanuova.com)
Revisions Copyright © 2000-2006 Lucent Technologies Inc. and others
+ Portions Copyright © 2005 Russ Cox, MIT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/emu/Nt/cmd.c b/emu/Nt/cmd.c
index a03b949b..764d328b 100644
--- a/emu/Nt/cmd.c
+++ b/emu/Nt/cmd.c
@@ -104,11 +104,11 @@ exporthandle(HANDLE h, int close)
/* TO DO: check that oserrstr will have the right text on error */
void*
-oscmd(char **args, int nice, char *dir, int *rpfd, int *wpfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
STARTUPINFO si;
SECURITY_ATTRIBUTES sec;
- HANDLE rh, wh, srh, swh;
+ HANDLE rh, wh, eh, srh, swh, seh;
PROCESS_INFORMATION pinfo;
char *cmd;
wchar_t *wcmd, *wdir;
@@ -126,35 +126,22 @@ oscmd(char **args, int nice, char *dir, int *rpfd, int *wpfd)
sec.nLength = sizeof(sec);
sec.lpSecurityDescriptor = 0;
sec.bInheritHandle = 0;
- if(!CreatePipe(&rh, &swh, &sec, 0)) {
- print("can't create pipe\n");
- free(cmd);
- free(wcmd);
- free(wdir);
- return nil;
- }
- if(!CreatePipe(&srh, &wh, &sec, 0)) {
- print("can't create pipe\n");
- CloseHandle(rh);
- CloseHandle(swh);
- free(cmd);
- free(wcmd);
- free(wdir);
- return nil;
- }
+ rh = wh = eh = srh = swh = seh = nil;
+ if(!CreatePipe(&rh, &swh, &sec, 0))
+ goto Error;
+ if(!CreatePipe(&srh, &wh, &sec, 0))
+ goto Error;
+ if(!CreatePipe(&seh, &eh, &sec, 0))
+ goto Error;
rh = exporthandle(rh, 1);
+ if(rh == nil)
+ goto Error;
wh = exporthandle(wh, 1);
- if (rh == nil || wh == nil) {
- print("can't dup pipes\n");
- CloseHandle(rh);
- CloseHandle(swh);
- CloseHandle(wh);
- CloseHandle(srh);
- free(cmd);
- free(wcmd);
- free(wdir);
- return nil;
- }
+ if(wh == nil)
+ goto Error;
+ eh = exporthandle(eh, 1);
+ if(eh == nil)
+ goto Error;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
@@ -162,7 +149,7 @@ oscmd(char **args, int nice, char *dir, int *rpfd, int *wpfd)
si.wShowWindow = SW_SHOW;
si.hStdInput = rh;
si.hStdOutput = wh;
- si.hStdError = exporthandle(wh, 0);
+ si.hStdError = eh;
prio = 0;
if(nice){
@@ -175,21 +162,14 @@ oscmd(char **args, int nice, char *dir, int *rpfd, int *wpfd)
if(!CreateProcess(nil/*wpath*/, wcmd, 0, 0, 1,
CREATE_NEW_PROCESS_GROUP|CREATE_DEFAULT_ERROR_MODE|prio,
0 /*env*/, wdir, &si, &pinfo)){
- print("can't create process '%Q' %d\n", wcmd, GetLastError());
- CloseHandle(si.hStdInput);
- CloseHandle(swh);
- CloseHandle(si.hStdOutput);
- CloseHandle(si.hStdError);
- CloseHandle(srh);
- free(cmd);
- free(wcmd);
- free(wdir);
- return nil;
+ //print("can't create process '%Q' %d\n", wcmd, GetLastError());
+ goto Error;
}
- *rpfd = nth2fd(srh);
- *wpfd = nth2fd(swh);
- if(*wpfd == 1 || *wpfd == 2)
+ fd[0] = nth2fd(swh);
+ fd[1] = nth2fd(srh);
+ fd[2] = nth2fd(seh);
+ if(fd[1] == 1 || fd[2] == 2)
panic("invalid mapping of handle to fd");
CloseHandle(si.hStdInput);
CloseHandle(si.hStdOutput);
@@ -209,6 +189,24 @@ oscmd(char **args, int nice, char *dir, int *rpfd, int *wpfd)
free(wcmd);
free(wdir);
return pinfo.hProcess;
+
+Error:
+ if(rh)
+ CloseHandle(rh);
+ if(wh)
+ CloseHandle(wh);
+ if(eh)
+ CloseHandle(eh);
+ if(srh)
+ CloseHandle(srh);
+ if(swh)
+ CloseHandle(swh);
+ if(seh)
+ CloseHandle(seh);
+ free(cmd);
+ free(wcmd);
+ free(wdir);
+ return nil;
}
int
diff --git a/emu/Nt/os.c b/emu/Nt/os.c
index 023d47c3..3f7156d9 100644
--- a/emu/Nt/os.c
+++ b/emu/Nt/os.c
@@ -64,24 +64,24 @@ pfree(Proc *p)
}
free(e->user);
free(p->prog);
+ CloseHandle((HANDLE)p->os);
free(p);
}
-static ulong erendezvous(void*, ulong);
-
void
osblock(void)
{
- erendezvous(up, 0);
+ if(WaitForSingleObject((HANDLE)up->os, INFINITE) != WAIT_OBJECT_0)
+ panic("osblock failed");
}
void
osready(Proc *p)
{
- erendezvous(p, 0);
+ if(SetEvent((HANDLE)p->os) == FALSE)
+ panic("osready failed");
}
-
void
pexit(char *msg, int t)
{
@@ -118,11 +118,9 @@ tramp(LPVOID p)
up = p;
up->func(up->arg);
pexit("", 0);
- // should never get here but tidy up anyway
- _asm {
- mov fs:[0],-1
- add esp, 8
- }
+ /* not reached */
+ for(;;)
+ panic("tramp");
return 0;
}
@@ -140,6 +138,12 @@ kproc(char *name, void (*func)(void*), void *arg, int flags)
print("out of kernel processes\n");
return -1;
}
+ p->os = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if(p->os == NULL){
+ pfree(p);
+ print("can't allocate os event\n");
+ return -1;
+ }
if(flags & KPDUPPG) {
pg = up->env->pgrp;
@@ -429,7 +433,7 @@ libinit(char *imod)
lasterror = GetLastError();
if(PlatformId == VER_PLATFORM_WIN32_NT || lasterror != ERROR_NOT_LOGGED_ON)
print("cannot GetUserName: %d\n", lasterror);
- } else {
+ }else{
uns = narrowen(wuname);
snprint(uname, sizeof(uname), "%s", uns);
free(uns);
@@ -439,85 +443,6 @@ libinit(char *imod)
emuinit(imod);
}
-enum
-{
- NHLOG = 7,
- NHASH = (1<<NHLOG)
-};
-
-typedef struct Tag Tag;
-struct Tag
-{
- void* tag;
- ulong val;
- HANDLE pid;
- Tag* next;
-};
-
-static Tag* ht[NHASH];
-static Tag* ft;
-static Lock hlock;
-static int nsema;
-
-static ulong
-erendezvous(void *tag, ulong value)
-{
- int h;
- ulong rval;
- Tag *t, **l, *f;
-
-
- h = (ulong)tag & (NHASH-1);
-
- lock(&hlock);
- l = &ht[h];
- for(t = ht[h]; t; t = t->next) {
- if(t->tag == tag) {
- rval = t->val;
- t->val = value;
- t->tag = 0;
- unlock(&hlock);
- if(SetEvent(t->pid) == FALSE)
- panic("Release failed\n");
- return rval;
- }
- }
-
- t = ft;
- if(t == 0) {
- t = malloc(sizeof(Tag));
- if(t == nil)
- panic("rendezvous: no memory");
- t->pid = CreateEvent(0, 0, 0, 0);
- }
- else
- ft = t->next;
-
- t->tag = tag;
- t->val = value;
- t->next = *l;
- *l = t;
- unlock(&hlock);
-
- if(WaitForSingleObject(t->pid, INFINITE) != WAIT_OBJECT_0)
- panic("WaitForSingleObject failed\n");
-
- lock(&hlock);
- rval = t->val;
- for(f = *l; f; f = f->next) {
- if(f == t) {
- *l = f->next;
- break;
- }
- l = &f->next;
- }
- t->next = ft;
- ft = t;
- unlock(&hlock);
-
- return rval;
-}
-
void
FPsave(void *fptr)
{
diff --git a/emu/Nt/win.c b/emu/Nt/win.c
index f9a6aa7d..2e984642 100644
--- a/emu/Nt/win.c
+++ b/emu/Nt/win.c
@@ -1,74 +1,42 @@
-#define Unknown win_Unknown
+#define Unknown WUnknown
+#define Colormap WColormap
+#define Cursor WCursor
+#define Display WDisplay
+#define Drawable WDrawable
+#define Font WFont
+#define GC WGC
+#define Point WPoint
+#define Rectangle WRectangle
+#define Screen WScreen
+#define Visual WVisual
+#define Window WWindow
+
#include <windows.h>
+
+#undef Colormap
+#undef Cursor
+#undef Display
+#undef XDrawable
+#undef Font
+#undef GC
+#undef Point
+#undef Rectangle
+#undef Screen
+#undef Visual
+#undef Window
#undef Unknown
+
#include "dat.h"
#include "fns.h"
#include "error.h"
-
+#include <draw.h>
#include "keyboard.h"
#include "cursor.h"
-/*
- * image channel descriptors - copied from draw.h as it clashes with windows.h on many things
- */
-enum {
- CRed = 0,
- CGreen,
- CBlue,
- CGrey,
- CAlpha,
- CMap,
- CIgnore,
- NChan,
-};
-
-#define __DC(type, nbits) ((((type)&15)<<4)|((nbits)&15))
-#define CHAN1(a,b) __DC(a,b)
-#define CHAN2(a,b,c,d) (CHAN1((a),(b))<<8|__DC((c),(d)))
-#define CHAN3(a,b,c,d,e,f) (CHAN2((a),(b),(c),(d))<<8|__DC((e),(f)))
-#define CHAN4(a,b,c,d,e,f,g,h) (CHAN3((a),(b),(c),(d),(e),(f))<<8|__DC((g),(h)))
-
-#define NBITS(c) ((c)&15)
-#define TYPE(c) (((c)>>4)&15)
-
-enum {
- GREY1 = CHAN1(CGrey, 1),
- GREY2 = CHAN1(CGrey, 2),
- GREY4 = CHAN1(CGrey, 4),
- GREY8 = CHAN1(CGrey, 8),
- CMAP8 = CHAN1(CMap, 8),
- RGB15 = CHAN4(CIgnore, 1, CRed, 5, CGreen, 5, CBlue, 5),
- RGB16 = CHAN3(CRed, 5, CGreen, 6, CBlue, 5),
- RGB24 = CHAN3(CRed, 8, CGreen, 8, CBlue, 8),
- RGBA32 = CHAN4(CRed, 8, CGreen, 8, CBlue, 8, CAlpha, 8),
- ARGB32 = CHAN4(CAlpha, 8, CRed, 8, CGreen, 8, CBlue, 8), /* stupid VGAs */
- XRGB32 = CHAN4(CIgnore, 8, CRed, 8, CGreen, 8, CBlue, 8),
-};
-
extern ulong displaychan;
-extern void drawend(void);
-
-/*
- * defs for image types to overcome name conflicts
- */
-typedef struct IPoint IPoint;
-typedef struct IRectangle IRectangle;
-
-struct IPoint
-{
- LONG x;
- LONG y;
-};
-
-struct IRectangle
-{
- IPoint min;
- IPoint max;
-};
-
extern char* runestoutf(char*, Rune*, int);
-extern int bytesperline(IRectangle, int);
+extern int bytesperline(Rectangle, int);
extern int main(int argc, char **argv);
static void dprint(char*, ...);
static DWORD WINAPI winproc(LPVOID);
@@ -105,7 +73,7 @@ WinMain(HINSTANCE winst, HINSTANCE wprevinst, LPSTR cmdline, int wcmdshow)
return 0;
}
-void
+static void
dprint(char *fmt, ...)
{
va_list arg;
@@ -118,17 +86,6 @@ dprint(char *fmt, ...)
OutputDebugString(buf);
}
-int
-col(int v, int n)
-{
- int i, c;
-
- c = 0;
- for(i = 0; i < 8; i += n)
- c |= v << (16-(n+i));
- return c >> 8;
-}
-
static void
graphicscmap(PALETTEENTRY *pal)
{
@@ -190,11 +147,13 @@ autochan(void)
return CMAP8;
if (bpp < 24)
return RGB15;
- return RGB24;
+ if (bpp < 32)
+ return RGB24;
+ return XRGB32;
}
uchar*
-attachscreen(IRectangle *r, ulong *chan, int *d, int *width, int *softscreen)
+attachscreen(Rectangle *r, ulong *chan, int *d, int *width, int *softscreen)
{
int i, k;
ulong c;
@@ -314,7 +273,7 @@ attachscreen(IRectangle *r, ulong *chan, int *d, int *width, int *softscreen)
}
void
-flushmemscreen(IRectangle r)
+flushmemscreen(Rectangle r)
{
RECT wr;
@@ -385,11 +344,12 @@ WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
b |= 1;
if(wparam & MK_MBUTTON)
b |= 2;
- if(wparam & MK_RBUTTON)
+ if(wparam & MK_RBUTTON) {
if(wparam & MK_CONTROL)
b |= 2; //simulate middle button
else
b |= 4; //right button
+ }
mousetrack(b, x, y, 0);
break;
case WM_SYSKEYDOWN:
@@ -590,8 +550,7 @@ winproc(LPVOID x)
if(AdjustWindowRect(&size, ws, 0)) {
maxxsize = size.right - size.left;
maxysize = size.bottom - size.top;
- }
- else {
+ }else{
maxxsize = Xsize + 40;
maxysize = Ysize + 40;
}
@@ -611,8 +570,7 @@ winproc(LPVOID x)
inst, /* program handle */
NULL /* create parms */
);
- }
- else {
+ }else{
window = CreateWindowExA(
0, /* extended style */
"inferno", /* class */
@@ -644,15 +602,13 @@ winproc(LPVOID x)
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
- }
- else {
+ }else{
while(GetMessageA(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
}
attached = 0;
- /* drawend(); */
ExitThread(msg.wParam);
return 0;
}
@@ -663,7 +619,7 @@ setpointer(int x, int y)
POINT pt;
pt.x = x; pt.y = y;
- ClientToScreen(window, (LPPOINT)&pt);
+ ClientToScreen(window, &pt);
SetCursorPos(pt.x, pt.y);
}
@@ -671,7 +627,7 @@ void
drawcursor(Drawcursor* c)
{
HCURSOR nh, oh;
- IRectangle ir;
+ Rectangle ir;
int i, h, j, bpl, ch, cw;
uchar *bs, *bc, *and, *xor, *cand, *cxor;
@@ -690,7 +646,6 @@ drawcursor(Drawcursor* c)
ir.min.y = c->miny;
ir.max.x = c->maxx;
ir.max.y = c->maxy;
- /* passing IRectangle to Rectangle is safe */
bpl = bytesperline(ir, 1);
h = (c->maxy-c->miny)/2;
@@ -728,8 +683,7 @@ drawcursor(Drawcursor* c)
SendMessage(window, WM_SETCURSOR, (int)window, 0);
if(oh != NULL)
DestroyCursor(oh);
- }
- else {
+ }else{
print("CreateCursor error %d\n", GetLastError());
print("CXCURSOR=%d\n", GetSystemMetrics(SM_CXCURSOR));
print("CYCURSOR=%d\n", GetSystemMetrics(SM_CYCURSOR));
diff --git a/emu/Plan9/cmd.c b/emu/Plan9/cmd.c
index d3822f50..8d311f2a 100644
--- a/emu/Plan9/cmd.c
+++ b/emu/Plan9/cmd.c
@@ -12,7 +12,7 @@ extern void vstack(void*);
typedef struct Targ Targ;
struct Targ
{
- int fd[2];
+ int fd[3]; /* standard input, output and error */
int wfd;
int* spin;
char** args;
@@ -41,18 +41,21 @@ exectramp(Targ *t)
nfd = MAXNFD; /* TO DO: should read from /fd */
for(i = 0; i < nfd; i++)
- if(i != fd[0] && i != fd[1] && i != t->wfd)
+ if(i != fd[0] && i != fd[1] && i != fd[2] && i != t->wfd)
close(i);
if(fd[0] != 0){
dup(fd[0], 0);
close(fd[0]);
}
- if(fd[0] != 1){
+ if(fd[1] != 1){
dup(fd[1], 1);
close(fd[1]);
}
- dup(1, 2);
+ if(fd[2] != 2){
+ dup(fd[2], 2);
+ close(fd[2]);
+ }
if(t->dir != nil && chdir(t->dir) < 0){
if(t->wfd > 0)
@@ -79,10 +82,10 @@ exectramp(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
Targ *t;
- int spin, *spinptr, fd0[2], fd1[2], wfd[2], n;
+ int spin, *spinptr, fd0[2], fd1[2], fd2[2], wfd[2], n;
Dir *d;
up->genbuf[0] = 0;
@@ -94,6 +97,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
t->nice = nice;
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
if(dir != nil){
d = dirstat(dir);
@@ -101,7 +105,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
goto Error;
free(d);
}
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
spinptr = &spin;
@@ -109,6 +113,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->spin = spinptr;
switch(rfork(RFPROC|RFMEM|RFREND|RFNOTEG|RFFDG|RFNAMEG|RFENVG)) {
@@ -128,20 +133,24 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
+
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
close(wfd[0]);
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
up->genbuf[n] = 0;
errstr(up->genbuf, sizeof(up->genbuf));
free(t);
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -150,6 +159,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
free(t);
diff --git a/emu/Plan9/win.c b/emu/Plan9/win.c
index d86eea15..2f280853 100644
--- a/emu/Plan9/win.c
+++ b/emu/Plan9/win.c
@@ -16,14 +16,14 @@ enum
extern Memimage *screenimage;
-ulong* attachwindow(Rectangle*, ulong*, int*, int*);
+static ulong* attachwindow(Rectangle*, ulong*, int*, int*);
static void plan9readmouse(void*);
static void plan9readkeybd(void*);
static int mapspecials(char *s1, char *s2, int *n);
-int pixels = 1;
int usenewwin = 1;
+int kbdiscons;
static int truedepth;
static int datafd;
@@ -84,31 +84,35 @@ attachscreen(Rectangle *r, ulong *chan, int *d, int *width, int *softscreen)
fprint(2, "attachscreen: can't mount window manager: %r\n");
return nil;
}
+ if(bind("/mnt/wsys", "/dev", MBEFORE) < 0){
+ fprint(2, "attachscreen: can't bind /mnt/wsys before /dev: %r\n");
+ return nil;
+ }
}
- cursfd = open("/mnt/wsys/cursor", OWRITE);
+ cursfd = open("/dev/cursor", OWRITE);
if(cursfd < 0) {
fprint(2, "attachscreen: open cursor: %r\n");
return nil;
}
/* Set up graphics window console (chars->gkbdq) */
- keybdfd = open("/mnt/wsys/cons", OREAD);
+ keybdfd = open("/dev/cons", OREAD);
if(keybdfd < 0) {
fprint(2, "attachscreen: open keyboard: %r\n");
return nil;
}
- mousefd = open("/mnt/wsys/mouse", ORDWR);
+ mousefd = open("/dev/mouse", ORDWR);
if(mousefd < 0){
fprint(2, "attachscreen: can't open mouse: %r\n");
return nil;
}
- if(usenewwin){
- fd = open("/mnt/wsys/consctl", OWRITE);
+ if(usenewwin || 1){
+ fd = open("/dev/consctl", OWRITE);
if(fd < 0)
- fprint(2, "attachscreen: open /mnt/wsys/consctl: %r\n");
+ fprint(2, "attachscreen: open /dev/consctl: %r\n");
if(write(fd, "rawon", 5) != 5)
- fprint(2, "attachscreen: write /mnt/wsys/consctl: %r\n");
+ fprint(2, "attachscreen: write /dev/consctl: %r\n");
}
/* Set up graphics files */
@@ -148,11 +152,11 @@ attachscreen(Rectangle *r, ulong *chan, int *d, int *width, int *softscreen)
mousepid = kproc("readmouse", plan9readmouse, nil, 0);
keybdpid = kproc("readkbd", plan9readkeybd, nil, 0);
- bind("/mnt/wsys", "/dev", MBEFORE);
fd = open("/dev/label", OWRITE);
- if (fd >= 0) {
- write(fd, "inferno", 7);
+ if(fd >= 0){
+ snprint(buf, sizeof(buf), "inferno %d", getpid());
+ write(fd, buf, strlen(buf));
close(fd);
}
@@ -160,35 +164,7 @@ attachscreen(Rectangle *r, ulong *chan, int *d, int *width, int *softscreen)
return (uchar*)data;
}
-static int
-depthof(char *s)
-{
- char *es;
- int n, c, d;
-
- es = s+12;
- while(s<es && *s==' ')
- s++;
- if(s == es)
- return -1;
- if('0'<=*s && *s<='9'){
- truedepth = 1<<atoi(s);
- return truedepth;
- }
-
- d = 0;
- while(s<es && *s!=' '){
- c = *s++; /* skip letter */
- n = strtoul(s, &s, 10);
- d += n;
- if(c != 'r' && c != 'g' && c != 'b' && c != 'k' && c != 'm')
- return -1;
- }
- truedepth = d;
- return d;
-}
-
-ulong*
+static ulong*
attachwindow(Rectangle *r, ulong *chan, int *d, int *width)
{
int n, fd, nb;
@@ -231,7 +207,8 @@ attachwindow(Rectangle *r, ulong *chan, int *d, int *width)
return nil;
}
imagechan = strtochan(buf+2*12);
- if(depthof(buf+2*12) < 0){
+ truedepth = chantodepth(imagechan);
+ if(truedepth == 0){
fprint(2, "attachwindow: cannot handle window depth specifier %.12s\n", buf+2*12);
return nil;
}
@@ -272,7 +249,7 @@ attachwindow(Rectangle *r, ulong *chan, int *d, int *width)
return data;
}
-int
+static int
plan9loadimage(Rectangle r, uchar *data, int ndata)
{
long dy;
@@ -396,7 +373,7 @@ drawcursor(Drawcursor *c)
write(cursfd, curs, sizeof curs);
}
-int
+static int
checkmouse(char *buf, int n)
{
int x, y, tick, b;
@@ -453,12 +430,12 @@ plan9readmouse(void *v)
}
static void
-plan9readkeybd(void *v)
+plan9readkeybd(void*)
{
int n, partial;
char buf[32];
char dbuf[32 * 3]; /* overestimate but safe */
- USED(v);
+
partial = 0;
for(;;){
n = read(keybdfd, buf + partial, sizeof(buf) - partial);
diff --git a/emu/Solaris/cmd.c b/emu/Solaris/cmd.c
index 897490c7..bff1f03b 100644
--- a/emu/Solaris/cmd.c
+++ b/emu/Solaris/cmd.c
@@ -21,7 +21,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -43,15 +43,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -82,11 +84,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
- Dir *d;
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -94,14 +95,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -113,7 +116,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
t->uid = uidnobody;
signal(SIGCHLD, SIG_DFL);
- switch(pid = fork1()) {
+ switch(pid = fork()) {
case -1:
goto Error;
case 0:
@@ -131,6 +134,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -138,6 +142,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -146,8 +151,9 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -158,6 +164,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/Unixware/cmd.c b/emu/Unixware/cmd.c
index 897490c7..bff1f03b 100644
--- a/emu/Unixware/cmd.c
+++ b/emu/Unixware/cmd.c
@@ -21,7 +21,7 @@ enum
typedef struct Targ Targ;
struct Targ
{
- int fd[2]; /* fd[0] is standard input, fd[1] is standard output */
+ int fd[3]; /* fd[0] is standard input, fd[1] is standard output, fd[2] is standard error */
char** args;
char* dir;
int pid;
@@ -43,15 +43,17 @@ childproc(Targ *t)
nfd = getdtablesize();
for(i = 0; i < nfd; i++)
- if(i != t->fd[0] && i != t->fd[1] && i != t->wfd)
+ if(i != t->fd[0] && i != t->fd[1] && i != t->fd[2] && i != t->wfd)
close(i);
dup2(t->fd[0], 0);
dup2(t->fd[1], 1);
- dup2(t->fd[1], 2);
+ dup2(t->fd[2], 2);
close(t->fd[0]);
close(t->fd[1]);
+ close(t->fd[2]);
+ /* should have an auth file to do host-specific authorisation? */
if(t->gid != -1){
if(setgid(t->gid) < 0 && getegid() == 0){
fprint(t->wfd, "can't set gid %d: %s", t->gid, strerror(errno));
@@ -82,11 +84,10 @@ childproc(Targ *t)
}
void*
-oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
+oscmd(char **args, int nice, char *dir, int *fd)
{
- Dir *d;
Targ *t;
- int r, fd0[2], fd1[2], wfd[2], n, pid;
+ int r, fd0[2], fd1[2], fd2[2], wfd[2], n, pid;
t = mallocz(sizeof(*t), 1);
if(t == nil)
@@ -94,14 +95,16 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
fd0[0] = fd0[1] = -1;
fd1[0] = fd1[1] = -1;
+ fd2[0] = fd2[1] = -1;
wfd[0] = wfd[1] = -1;
- if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(wfd) < 0)
+ if(pipe(fd0) < 0 || pipe(fd1) < 0 || pipe(fd2) < 0 || pipe(wfd) < 0)
goto Error;
if(fcntl(wfd[1], F_SETFD, FD_CLOEXEC) < 0) /* close on exec to give end of file on success */
goto Error;
t->fd[0] = fd0[0];
t->fd[1] = fd1[1];
+ t->fd[2] = fd2[1];
t->wfd = wfd[1];
t->args = args;
t->dir = dir;
@@ -113,7 +116,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
t->uid = uidnobody;
signal(SIGCHLD, SIG_DFL);
- switch(pid = fork1()) {
+ switch(pid = fork()) {
case -1:
goto Error;
case 0:
@@ -131,6 +134,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
close(fd0[0]);
close(fd1[1]);
+ close(fd2[1]);
close(wfd[1]);
n = read(wfd[0], up->genbuf, sizeof(up->genbuf)-1);
@@ -138,6 +142,7 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
if(n > 0){
close(fd0[1]);
close(fd1[0]);
+ close(fd2[0]);
free(t);
up->genbuf[n] = 0;
if(Debug)
@@ -146,8 +151,9 @@ oscmd(char **args, int nice, char *dir, int *rfd, int *sfd)
return nil;
}
- *sfd = fd0[1];
- *rfd = fd1[0];
+ fd[0] = fd0[1];
+ fd[1] = fd1[0];
+ fd[2] = fd2[0];
return t;
Error:
@@ -158,6 +164,8 @@ Error:
close(fd0[1]);
close(fd1[0]);
close(fd1[1]);
+ close(fd2[0]);
+ close(fd2[1]);
close(wfd[0]);
close(wfd[1]);
error(strerror(r));
diff --git a/emu/mkfile b/emu/mkfile
index 72da0cc1..779e5f16 100644
--- a/emu/mkfile
+++ b/emu/mkfile
@@ -8,7 +8,7 @@ nuke:V: nuke-$HOSTMODEL
&-Posix:QV:
echo "(cd $SYSTARG; mk $MKFLAGS $stem)"
- (cd $SYSTARG; mk $MKFLAGS $stem)
+ (cd $SYSTARG; mk $MKFLAGS $stem) || exit 1
&-Nt:QV:
echo '@{builtin cd' $SYSTARG '; mk $MKFLAGS $stem}'
diff --git a/emu/port/chan.c b/emu/port/chan.c
index 697d92c4..997cb876 100644
--- a/emu/port/chan.c
+++ b/emu/port/chan.c
@@ -1297,7 +1297,6 @@ if(c->umh != nil){
omode |= OTRUNC;
goto Open;
}
- panic("namec: not reached");
default:
panic("unknown namec access %d\n", amode);
diff --git a/emu/port/dev.c b/emu/port/dev.c
index 8bd1da5f..5df62ecc 100644
--- a/emu/port/dev.c
+++ b/emu/port/dev.c
@@ -249,8 +249,6 @@ devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen)
}
break;
}
- error(Egreg); /* not reached? */
- return -1;
}
long
diff --git a/emu/port/devcmd.c b/emu/port/devcmd.c
index 4822c49a..f6cccf39 100644
--- a/emu/port/devcmd.c
+++ b/emu/port/devcmd.c
@@ -10,6 +10,7 @@ enum
Qconvdir,
Qconvbase,
Qdata = Qconvbase,
+ Qstderr,
Qctl,
Qstatus,
Qwait,
@@ -25,10 +26,8 @@ struct Conv
{
int x;
int inuse;
- int wcount;
- int rcount;
- int rfd;
- int wfd;
+ int fd[3]; /* stdin, stdout, and stderr */
+ int count[3]; /* number of readers on stdin/stdout/stderr */
int perm;
char* owner;
char* state;
@@ -69,6 +68,10 @@ cmd3gen(Chan *c, int i, Dir *dp)
mkqid(&q, QID(CONV(c->qid), Qdata), 0, QTFILE);
devdir(c, q, "data", 0, cv->owner, cv->perm, dp);
return 1;
+ case Qstderr:
+ mkqid(&q, QID(CONV(c->qid), Qstderr), 0, QTFILE);
+ devdir(c, q, "stderr", 0, cv->owner, 0444, dp);
+ return 1;
case Qctl:
mkqid(&q, QID(CONV(c->qid), Qctl), 0, QTFILE);
devdir(c, q, "ctl", 0, cv->owner, cv->perm, dp);
@@ -143,6 +146,7 @@ cmdgen(Chan *c, char *name, Dirtab *d, int nd, int s, Dir *dp)
case Qconvdir:
return cmd3gen(c, Qconvbase+s, dp);
case Qdata:
+ case Qstderr:
case Qctl:
case Qstatus:
case Qwait:
@@ -154,7 +158,7 @@ cmdgen(Chan *c, char *name, Dirtab *d, int nd, int s, Dir *dp)
static void
cmdinit(void)
{
- cmd.maxconv = 100;
+ cmd.maxconv = 1000;
cmd.conv = mallocz(sizeof(Conv*)*(cmd.maxconv+1), 1);
/* cmd.conv is checked by cmdattach, below */
}
@@ -228,6 +232,7 @@ cmdopen(Chan *c, int omode)
mkqid(&c->qid, QID(cv->x, Qctl), 0, QTFILE);
break;
case Qdata:
+ case Qstderr:
case Qctl:
case Qwait:
qlock(&cmd.l);
@@ -247,10 +252,14 @@ cmdopen(Chan *c, int omode)
switch(TYPE(c->qid)){
case Qdata:
if(omode == OWRITE || omode == ORDWR)
- cv->wcount++;
+ cv->count[0]++;
if(omode == OREAD || omode == ORDWR)
- cv->rcount++;
- c->mode = omode;
+ cv->count[1]++;
+ break;
+ case Qstderr:
+ if(omode != OREAD)
+ error(Eperm);
+ cv->count[2]++;
break;
case Qwait:
if(cv->waitq == nil)
@@ -269,7 +278,7 @@ cmdopen(Chan *c, int omode)
qunlock(&cmd.l);
break;
}
- c->mode = openmode(omode);
+ c->mode = omode;
c->flag |= COPEN;
c->offset = 0;
return c;
@@ -296,6 +305,15 @@ closeconv(Conv *c)
}
static void
+cmdfdclose(Conv *c, int fd)
+{
+ if(--c->count[fd] == 0 && c->fd[fd] != -1){
+ close(c->fd[fd]);
+ c->fd[fd] = -1;
+ }
+}
+
+static void
cmdclose(Chan *c)
{
Conv *cc;
@@ -307,23 +325,17 @@ cmdclose(Chan *c)
switch(TYPE(c->qid)) {
case Qctl:
case Qdata:
+ case Qstderr:
case Qwait:
cc = cmd.conv[CONV(c->qid)];
qlock(&cc->l);
if(TYPE(c->qid) == Qdata){
- if(c->mode == OWRITE || c->mode == ORDWR){
- if(--cc->wcount == 0 && cc->wfd != -1){
- close(cc->wfd);
- cc->wfd = -1;
- }
- }
- if(c->mode == OREAD || c->mode == ORDWR){
- if(--cc->rcount == 0 && cc->rfd != -1){
- close(cc->rfd);
- cc->rfd = -1;
- }
- }
- }
+ if(c->mode == OWRITE || c->mode == ORDWR)
+ cmdfdclose(cc, 0);
+ if(c->mode == OREAD || c->mode == ORDWR)
+ cmdfdclose(cc, 1);
+ }else if(TYPE(c->qid) == Qstderr)
+ cmdfdclose(cc, 2);
r = --cc->inuse;
if(cc->child != nil){
@@ -345,6 +357,7 @@ cmdread(Chan *ch, void *a, long n, vlong offset)
{
Conv *c;
char *p, *cmds;
+ int fd;
USED(offset);
@@ -368,15 +381,19 @@ cmdread(Chan *ch, void *a, long n, vlong offset)
c->x, c->inuse, c->state, c->dir, cmds);
return readstr(offset, p, n, up->genbuf);
case Qdata:
+ case Qstderr:
+ fd = 1;
+ if(TYPE(ch->qid) == Qstderr)
+ fd = 2;
c = cmd.conv[CONV(ch->qid)];
qlock(&c->l);
- if(c->rfd == -1){
+ if(c->fd[fd] == -1){
qunlock(&c->l);
return 0;
}
qunlock(&c->l);
osenter();
- n = read(c->rfd, a, n);
+ n = read(c->fd[fd], a, n);
osleave();
if(n < 0)
oserror();
@@ -393,7 +410,7 @@ cmdstarted(void *a)
Conv *c;
c = a;
- return c->child != nil || c->error != nil;
+ return c->child != nil || c->error != nil || strcmp(c->state, "Execute") != 0;
}
enum
@@ -417,7 +434,7 @@ Cmdtab cmdtab[] = {
static long
cmdwrite(Chan *ch, void *a, long n, vlong offset)
{
- int r;
+ int i, r;
Conv *c;
Cmdbuf *cb;
Cmdtab *ct;
@@ -447,8 +464,11 @@ cmdwrite(Chan *ch, void *a, long n, vlong offset)
free(cb);
nexterror();
}
- if(c->child != nil || c->cmd != nil || c->wfd != -1 || c->rfd != -1)
+ if(c->child != nil || c->cmd != nil)
error(Einuse);
+ for(i = 0; i < nelem(c->fd); i++)
+ if(c->fd[i] != -1)
+ error(Einuse);
if(cb->nf < 1)
error(Etoosmall);
kproc("cmdproc", cmdproc, c, 0); /* cmdproc held back until unlock below */
@@ -490,13 +510,13 @@ cmdwrite(Chan *ch, void *a, long n, vlong offset)
case Qdata:
c = cmd.conv[CONV(ch->qid)];
qlock(&c->l);
- if(c->wfd == -1){
+ if(c->fd[0] == -1){
qunlock(&c->l);
error(Ehungup);
}
qunlock(&c->l);
osenter();
- r = write(c->wfd, a, n);
+ r = write(c->fd[0], a, n);
osleave();
if(r == 0)
error(Ehungup);
@@ -520,6 +540,7 @@ cmdwstat(Chan *c, uchar *dp, int n)
error(Eperm);
case Qctl:
case Qdata:
+ case Qstderr:
d = malloc(sizeof(*d)+n);
if(d == nil)
error(Enomem);
@@ -548,6 +569,7 @@ static Conv*
cmdclone(char *user)
{
Conv *c, **pp, **ep;
+ int i;
c = nil;
ep = &cmd.conv[cmd.maxconv];
@@ -578,8 +600,8 @@ cmdclone(char *user)
kstrdup(&c->dir, rootdir);
c->perm = 0660;
c->state = "Closed";
- c->rfd = -1;
- c->wfd = -1;
+ for(i=0; i<nelem(c->fd); i++)
+ c->fd[i] = -1;
qunlock(&c->l);
return c;
@@ -606,7 +628,7 @@ cmdproc(void *a)
Wakeup(&c->startr);
pexit("cmdproc", 0);
}
- t = oscmd(c->cmd->f+1, c->nice, c->dir, &c->rfd, &c->wfd);
+ t = oscmd(c->cmd->f+1, c->nice, c->dir, c->fd);
if(t == nil)
oserror();
c->child = t; /* to allow oscmdkill */
@@ -629,7 +651,7 @@ cmdproc(void *a)
oscmdfree(t);
if(Debug){
status[n]=0;
- print("done %d %d: %q\n", c->rfd, c->wfd, status);
+ print("done %d %d %d: %q\n", c->fd[0], c->fd[1], c->fd[2], status);
}
if(c->inuse > 0){
c->state = "Done";
diff --git a/emu/port/devcons.c b/emu/port/devcons.c
index efe49838..8e823839 100644
--- a/emu/port/devcons.c
+++ b/emu/port/devcons.c
@@ -107,11 +107,19 @@ kbdslave(void *a)
USED(a);
for(;;) {
b = readkbd();
- if(kbd.raw == 0)
- write(1, &b, 1);
+ if(kbd.raw == 0){
+ switch(b){
+ case 0x15:
+ write(1, "^U\n", 3);
+ break;
+ default:
+ write(1, &b, 1);
+ break;
+ }
+ }
qproduce(kbdq, &b, 1);
}
- pexit("kbdslave", 0);
+ /* pexit("kbdslave", 0); */ /* not reached */
}
void
@@ -152,13 +160,13 @@ gkbdputc(Queue *q, int ch)
void
consinit(void)
{
- kbdq = qopen(512, 0, 0, 0);
+ kbdq = qopen(512, 0, nil, nil);
if(kbdq == 0)
panic("no memory");
- lineq = qopen(512, 0, 0, 0);
+ lineq = qopen(2*1024, 0, nil, nil);
if(lineq == 0)
panic("no memory");
- gkbdq = qopen(512, 0, 0, 0);
+ gkbdq = qopen(512, 0, nil, nil);
if(gkbdq == 0)
panic("no memory");
randominit();
@@ -178,9 +186,9 @@ consattach(char *spec)
{
static int kp;
- if (kp == 0 && !dflag) {
- kproc("kbd", kbdslave, 0, 0);
+ if(kp == 0 && !dflag) {
kp = 1;
+ kproc("kbd", kbdslave, 0, 0);
}
return devattach('c', spec);
}
@@ -205,34 +213,37 @@ consopen(Chan *c, int omode)
case Qconsctl:
incref(&kbd.ctl);
break;
+
case Qscancode:
qlock(&kbd.gq);
- if(gkscanq || !gkscanid) {
+ if(gkscanq != nil || gkscanid == nil) {
qunlock(&kbd.q);
c->flag &= ~COPEN;
if(gkscanq)
error(Einuse);
else
- error(Ebadarg);
+ error("not supported");
}
gkscanq = qopen(256, 0, nil, nil);
qunlock(&kbd.gq);
break;
+
case Qkprint:
wlock(&kprintq.l);
- if(kprintq.q != nil){
+ if(waserror()){
wunlock(&kprintq.l);
c->flag &= ~COPEN;
- error(Einuse);
+ nexterror();
}
- kprintq.q = qopen(32*1024, 0, 0, 0);
- if(kprintq.q == nil){
- wunlock(&kprintq.l);
- c->flag &= ~COPEN;
+ if(kprintq.q != nil)
+ error(Einuse);
+ kprintq.q = qopen(32*1024, Qcoalesce, nil, nil);
+ if(kprintq.q == nil)
error(Enomem);
- }
qnoblock(kprintq.q, 1);
+ poperror();
wunlock(&kprintq.l);
+ c->iounit = qiomaxatomic;
break;
}
return c;
@@ -246,17 +257,20 @@ consclose(Chan *c)
switch((ulong)c->qid.path) {
case Qconsctl:
+ /* last close of control file turns off raw */
if(decref(&kbd.ctl) == 0)
kbd.raw = 0;
break;
+
case Qscancode:
qlock(&kbd.gq);
if(gkscanq) {
qfree(gkscanq);
- gkscanq = 0;
+ gkscanq = nil;
}
qunlock(&kbd.gq);
break;
+
case Qkprint:
wlock(&kprintq.l);
qfree(kprintq.q);
@@ -267,62 +281,82 @@ consclose(Chan *c)
}
static long
-consread(Chan *c, void *va, long count, vlong offset)
+consread(Chan *c, void *va, long n, vlong offset)
{
- int i, n, ch, eol;
- char *p, buf[64];
+ ulong l;
+ int i, send;
+ char *p, buf[64], ch;
if(c->qid.type & QTDIR)
- return devdirread(c, va, count, contab, nelem(contab), devgen);
+ return devdirread(c, va, n, contab, nelem(contab), devgen);
switch((ulong)c->qid.path) {
default:
error(Egreg);
+
case Qsysctl:
- return readstr(offset, va, count, VERSION);
+ return readstr(offset, va, n, VERSION);
+
case Qsysname:
if(ossysname == nil)
return 0;
- return readstr(offset, va, count, ossysname);
+ return readstr(offset, va, n, ossysname);
+
case Qrandom:
- return randomread(va, count);
+ return randomread(va, n);
+
case Qnotquiterandom:
- genrandom(va, count);
- return count;
+ genrandom(va, n);
+ return n;
+
case Qpin:
p = "pin set";
if(up->env->pgrp->pin == Nopin)
p = "no pin";
- return readstr(offset, va, count, p);
+ return readstr(offset, va, n, p);
+
case Qhostowner:
- return readstr(offset, va, count, eve);
+ return readstr(offset, va, n, eve);
+
case Qhoststdin:
- return read(0, va, count); /* should be pread */
+ return read(0, va, n); /* should be pread */
+
case Quser:
- return readstr(offset, va, count, up->env->user);
+ return readstr(offset, va, n, up->env->user);
+
case Qjit:
snprint(buf, sizeof(buf), "%d", cflag);
- return readstr(offset, va, count, buf);
+ return readstr(offset, va, n, buf);
+
case Qtime:
snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime());
- return readstr(offset, va, count, buf);
+ return readstr(offset, va, n, buf);
+
case Qdrivers:
p = malloc(READSTR);
if(p == nil)
error(Enomem);
- n = 0;
+ l = 0;
for(i = 0; devtab[i] != nil; i++)
- n += snprint(p+n, READSTR-n, "#%C %s\n", devtab[i]->dc, devtab[i]->name);
- n = readstr(offset, va, count, p);
+ l += snprint(p+l, READSTR-l, "#%C %s\n", devtab[i]->dc, devtab[i]->name);
+ if(waserror()){
+ free(p);
+ nexterror();
+ }
+ n = readstr(offset, va, n, p);
+ poperror();
free(p);
return n;
+
case Qmemory:
- return poolread(va, count, offset);
+ return poolread(va, n, offset);
case Qnull:
return 0;
+
case Qmsec:
- return readnum(offset, va, count, osmillisec(), NUMSIZE);
+ return readnum(offset, va, n, osmillisec(), NUMSIZE);
+
case Qcons:
qlock(&kbd.q);
if(waserror()){
@@ -334,53 +368,60 @@ consread(Chan *c, void *va, long count, vlong offset)
error(Enonexist);
while(!qcanread(lineq)) {
- qread(kbdq, &kbd.line[kbd.x], 1);
- ch = kbd.line[kbd.x];
- if(kbd.raw){
- qiwrite(lineq, &kbd.line[kbd.x], 1);
+ if(qread(kbdq, &ch, 1) == 0)
continue;
- }
- eol = 0;
- switch(ch) {
- case '\b':
- if(kbd.x)
- kbd.x--;
- break;
- case 0x15:
- kbd.x = 0;
- break;
- case '\n':
- case 0x04:
- eol = 1;
- default:
+ send = 0;
+ if(ch == 0){
+ /* flush output on rawoff -> rawon */
+ if(kbd.x > 0)
+ send = !qcanread(kbdq);
+ }else if(kbd.raw){
kbd.line[kbd.x++] = ch;
- break;
+ send = !qcanread(kbdq);
+ }else{
+ switch(ch){
+ case '\b':
+ if(kbd.x)
+ kbd.x--;
+ break;
+ case 0x15:
+ kbd.x = 0;
+ break;
+ case 0x04:
+ send = 1;
+ break;
+ case '\n':
+ send = 1;
+ default:
+ kbd.line[kbd.x++] = ch;
+ break;
+ }
}
- if(kbd.x == sizeof(kbd.line) || eol){
- if(ch == 0x04)
- kbd.x--;
+ if(send || kbd.x == sizeof kbd.line){
qwrite(lineq, kbd.line, kbd.x);
kbd.x = 0;
}
}
- n = qread(lineq, va, count);
+ n = qread(lineq, va, n);
qunlock(&kbd.q);
poperror();
return n;
+
case Qscancode:
if(offset == 0)
- return readstr(0, va, count, gkscanid);
- else
- return qread(gkscanq, va, count);
+ return readstr(0, va, n, gkscanid);
+ return qread(gkscanq, va, n);
+
case Qkeyboard:
- return qread(gkbdq, va, count);
+ return qread(gkbdq, va, n);
+
case Qkprint:
rlock(&kprintq.l);
if(waserror()){
runlock(&kprintq.l);
nexterror();
}
- n = qread(kprintq.q, va, count);
+ n = qread(kprintq.q, va, n);
poperror();
runlock(&kprintq.l);
return n;
@@ -388,19 +429,18 @@ consread(Chan *c, void *va, long count, vlong offset)
}
static long
-conswrite(Chan *c, void *va, long count, vlong offset)
+conswrite(Chan *c, void *va, long n, vlong offset)
{
- char buf[128];
+ char buf[128], *a, ch;
int x;
- USED(offset);
-
if(c->qid.type & QTDIR)
error(Eperm);
switch((ulong)c->qid.path) {
default:
error(Egreg);
+
case Qcons:
if(canrlock(&kprintq.l)){
if(kprintq.q != nil){
@@ -408,105 +448,129 @@ conswrite(Chan *c, void *va, long count, vlong offset)
runlock(&kprintq.l);
nexterror();
}
- qwrite(kprintq.q, va, count);
+ qwrite(kprintq.q, va, n);
poperror();
runlock(&kprintq.l);
- return count;
+ return n;
}
runlock(&kprintq.l);
}
- return write(1, va, count);
+ return write(1, va, n);
+
case Qsysctl:
- return sysconwrite(va, count);
+ return sysconwrite(va, n);
+
case Qconsctl:
- if(count >= sizeof(buf))
- count = sizeof(buf)-1;
- strncpy(buf, va, count);
- buf[count] = 0;
- if(strncmp(buf, "rawon", 5) == 0) {
- kbd.raw = 1;
- return count;
- }
- else
- if(strncmp(buf, "rawoff", 6) == 0) {
- kbd.raw = 0;
- return count;
+ if(n >= sizeof(buf))
+ n = sizeof(buf)-1;
+ strncpy(buf, va, n);
+ buf[n] = 0;
+ for(a = buf; a;){
+ if(strncmp(a, "rawon", 5) == 0){
+ kbd.raw = 1;
+ /* clumsy hack - wake up reader */
+ ch = 0;
+ qwrite(kbdq, &ch, 1);
+ } else if(strncmp(buf, "rawoff", 6) == 0){
+ kbd.raw = 0;
+ }
+ if((a = strchr(a, ' ')) != nil)
+ a++;
}
- error(Ebadctl);
+ break;
+
case Qkeyboard:
- for(x=0; x<count; ) {
+ for(x=0; x<n; ) {
Rune r;
x += chartorune(&r, &((char*)va)[x]);
gkbdputc(gkbdq, r);
}
- return count;
+ break;
+
case Qnull:
- return count;
+ break;
+
case Qpin:
if(up->env->pgrp->pin != Nopin)
error("pin already set");
- if(count >= sizeof(buf))
- count = sizeof(buf)-1;
- strncpy(buf, va, count);
- buf[count] = '\0';
+ if(n >= sizeof(buf))
+ n = sizeof(buf)-1;
+ strncpy(buf, va, n);
+ buf[n] = '\0';
up->env->pgrp->pin = atoi(buf);
- return count;
+ break;
+
case Qtime:
- if(count >= sizeof(buf))
- count = sizeof(buf)-1;
- strncpy(buf, va, count);
- buf[count] = '\0';
+ if(n >= sizeof(buf))
+ n = sizeof(buf)-1;
+ strncpy(buf, va, n);
+ buf[n] = '\0';
timeoffset = strtoll(buf, 0, 0)-osusectime();
- return count;
- case Quser:
- if(count >= sizeof(buf))
+ break;
+
+ case Qhostowner:
+ if(!iseve())
+ error(Eperm);
+ if(offset != 0 || n >= sizeof(buf))
error(Ebadarg);
- strncpy(buf, va, count);
- buf[count] = '\0';
- if(count > 0 && buf[count-1] == '\n')
- buf[--count] = '\0';
- if(count == 0)
+ memmove(buf, va, n);
+ buf[n] = '\0';
+ if(n > 0 && buf[n-1] == '\n')
+ buf[--n] = '\0';
+ if(n == 0)
error(Ebadarg);
- if(strcmp(up->env->user, eve) != 0)
+ /* renameuser(eve, buf); */
+ /* renameproguser(eve, buf); */
+ kstrdup(&eve, buf);
+ kstrdup(&up->env->user, buf);
+ break;
+
+ case Quser:
+ if(!iseve())
error(Eperm);
- setid(buf, 0);
- return count;
- case Qhostowner:
- if(count >= sizeof(buf))
+ if(offset != 0)
error(Ebadarg);
- strncpy(buf, va, count);
- buf[count] = '\0';
- if(count > 0 && buf[count-1] == '\n')
- buf[--count] = '\0';
- if(count == 0)
+ if(n <= 0 || n >= sizeof(buf))
error(Ebadarg);
- if(strcmp(up->env->user, eve) != 0)
- error(Eperm);
- kstrdup(&eve, buf);
- return count;
+ strncpy(buf, va, n);
+ buf[n] = '\0';
+ if(n > 0 && buf[n-1] == '\n')
+ buf[--n] = '\0';
+ if(n == 0)
+ error(Ebadarg);
+ setid(buf, 0);
+ break;
+
case Qhoststdout:
- return write(1, va, count);
+ return write(1, va, n);
+
case Qhoststderr:
- return write(2, va, count);
+ return write(2, va, n);
+
case Qjit:
- if(count >= sizeof(buf))
- count = sizeof(buf)-1;
- strncpy(buf, va, count);
- buf[count] = '\0';
+ if(n >= sizeof(buf))
+ n = sizeof(buf)-1;
+ strncpy(buf, va, n);
+ buf[n] = '\0';
x = atoi(buf);
- if (x < 0 || x > 9)
+ if(x < 0 || x > 9)
error(Ebadarg);
cflag = x;
- return count;
+ break;
+
case Qsysname:
- if(count >= sizeof(buf))
- count = sizeof(buf)-1;
- strncpy(buf, va, count);
- buf[count] = '\0';
+ if(offset != 0)
+ error(Ebadarg);
+ if(n < 0 || n >= sizeof(buf))
+ error(Ebadarg);
+ strncpy(buf, va, n);
+ buf[n] = '\0';
+ if(buf[n-1] == '\n')
+ buf[n-1] = 0;
kstrdup(&ossysname, buf);
- return count;
+ break;
}
- return 0;
+ return n;
}
static int
diff --git a/emu/port/devmem.c b/emu/port/devmem.c
index 6c09aaad..78f772c6 100644
--- a/emu/port/devmem.c
+++ b/emu/port/devmem.c
@@ -438,7 +438,6 @@ memread(Chan *c, void *va, long count, vlong offset)
free(s);
return count;
}
- return 0;
}
static long
diff --git a/emu/port/devprof.c b/emu/port/devprof.c
index f3a768c3..86d6d962 100644
--- a/emu/port/devprof.c
+++ b/emu/port/devprof.c
@@ -666,8 +666,6 @@ enum{
Mialloc,
};
-#ifdef HEAP_ALIGN
-
static void
memprof(int c, void *v, ulong n)
{
@@ -703,7 +701,7 @@ memprof(int c, void *v, ulong n)
i = p-r->base;
k = (r->id<<24) | i;
if(c == Mhalloc){
- h->pad = k;
+ h->hprof = k;
j = hmsize(h)-sizeof(Heap);
}
else if(c == Mmalloc){
@@ -721,7 +719,7 @@ memprof(int c, void *v, ulong n)
else if(c == Mifree)
k = ((ulong*)v)[1];
else
- k = h->pad;
+ k = h->hprof;
if((r = getrec(k>>24)) == nil){
unlock(&profile.l);
return;
@@ -766,18 +764,6 @@ memprof(int c, void *v, ulong n)
unlock(&profile.l);
}
-#else
-
-static void
-memprof(int c, void *v, ulong n)
-{
- USED(c);
- USED(v);
- USED(n);
-}
-
-#endif
-
/* main and image memory */
static void
memprofmi(int c, ulong pc, ulong v, ulong n)
diff --git a/emu/port/error.h b/emu/port/error.h
index b1911397..e6d61d9d 100644
--- a/emu/port/error.h
+++ b/emu/port/error.h
@@ -32,9 +32,6 @@ extern char Ehungup[]; /* i/o on hungup channel */
extern char Ebadctl[]; /* bad process or channel control request */
extern char Enodev[]; /* no free devices */
extern char Enoenv[]; /* no free environment resources */
-extern char Emuxshutdown[]; /* mux server shut down */
-extern char Emuxbusy[]; /* all mux channels busy */
-extern char Emuxmsg[]; /* bad mux message format or mismatch */
extern char Ethread[]; /* thread exited */
extern char Enochild[]; /* no living children */
extern char Eioload[]; /* i/o error in demand load */
diff --git a/emu/port/exportfs.c b/emu/port/exportfs.c
index e88c5ad3..1feae7ae 100644
--- a/emu/port/exportfs.c
+++ b/emu/port/exportfs.c
@@ -610,8 +610,6 @@ exslave(void *a)
notkilled();
exfreeq(q);
}
- print("exslave %ld shut down", up->pid); /* not reached */
- pexit("exslave shut down", 0);
}
static void
diff --git a/emu/port/fns.h b/emu/port/fns.h
index 393a5c35..effdbe33 100644
--- a/emu/port/fns.h
+++ b/emu/port/fns.h
@@ -118,7 +118,7 @@ void nexterror(void);
void notkilled(void);
int openmode(ulong);
void osblock(void);
-void* oscmd(char**, int, char*, int*, int*);
+void* oscmd(char**, int, char*, int*);
int oscmdwait(void*, char*, int);
int oscmdkill(void*);
void oscmdfree(void*);
diff --git a/emu/port/inferno.c b/emu/port/inferno.c
index 736644be..1149d623 100644
--- a/emu/port/inferno.c
+++ b/emu/port/inferno.c
@@ -585,6 +585,7 @@ Sys_dial(void *fp)
return;
f->ret->t1.dfd = mkfd(f->ret->t0);
+ f->ret->t0 = 0;
f->ret->t1.cfd = mkfd(cfd);
retstr(dir, &f->ret->t1.dir);
}
@@ -608,6 +609,7 @@ Sys_announce(void *fp)
return;
f->ret->t1.cfd = mkfd(f->ret->t0);
+ f->ret->t0 = 0;
retstr(dir, &f->ret->t1.dir);
}
@@ -631,6 +633,7 @@ Sys_listen(void *fp)
return;
f->ret->t1.cfd = mkfd(f->ret->t0);
+ f->ret->t0 = 0;
retstr(dir, &f->ret->t1.dir);
}