diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-23 00:30:12 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-23 00:30:12 +0000 |
| commit | 6e425a9de8c003b5a733621a6b6730ec3cc902b8 (patch) | |
| tree | 314123bcab78ff295f38f85f31dc141e5fe22d15 /emu | |
| parent | 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (diff) | |
20061220
Diffstat (limited to 'emu')
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; @@ -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)); @@ -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); } |
