diff options
| author | Russ Cox <rsc@golang.org> | 2008-12-03 14:21:28 -0800 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2008-12-03 14:21:28 -0800 |
| commit | b592d8aa993770b52cf48dba588ed6baa8364040 (patch) | |
| tree | c5608a8146ee938d88da7942dd5bb4a17dc904ea | |
| parent | ba6aabb92da924bfdcc9ae541c370bfee48185f8 (diff) | |
| download | golang-b592d8aa993770b52cf48dba588ed6baa8364040.tar.gz | |
preparation for exec.
* syscall:
add syscall.RawSyscall, which doesn't use sys.entersyscall/sys.exitsyscall
add syscall.dup2
add syscall.BytePtrPtr
add syscall.Rusage, RusagePtr
add syscall.F_GETFD, F_SETFD, FD_CLOEXEC
* runtime:
clean up, correct signal handling.
can now survive (continue running after) a signal.
R=r
DELTA=394 (286 added, 51 deleted, 57 changed)
OCL=20351
CL=20369
| -rw-r--r-- | src/lib/syscall/Makefile | 5 | ||||
| -rw-r--r-- | src/lib/syscall/asm_amd64_darwin.s | 18 | ||||
| -rw-r--r-- | src/lib/syscall/asm_amd64_linux.s | 19 | ||||
| -rw-r--r-- | src/lib/syscall/cast_amd64.s | 10 | ||||
| -rw-r--r-- | src/lib/syscall/file_darwin.go | 6 | ||||
| -rw-r--r-- | src/lib/syscall/file_linux.go | 6 | ||||
| -rw-r--r-- | src/lib/syscall/syscall.go | 2 | ||||
| -rw-r--r-- | src/lib/syscall/types_amd64_darwin.go | 28 | ||||
| -rw-r--r-- | src/lib/syscall/types_amd64_linux.go | 28 | ||||
| -rw-r--r-- | src/runtime/rt1_amd64_darwin.c | 75 | ||||
| -rw-r--r-- | src/runtime/rt1_amd64_linux.c | 65 | ||||
| -rw-r--r-- | src/runtime/runtime.h | 11 | ||||
| -rw-r--r-- | src/runtime/signals.h | 40 | ||||
| -rw-r--r-- | src/runtime/signals_darwin.h | 48 | ||||
| -rw-r--r-- | src/runtime/signals_linux.h | 48 | ||||
| -rw-r--r-- | src/runtime/sys_amd64_darwin.s | 14 | ||||
| -rw-r--r-- | src/runtime/sys_amd64_linux.s | 10 | ||||
| -rw-r--r-- | test/golden.out | 3 | ||||
| -rw-r--r-- | test/sigchld.go | 19 |
19 files changed, 349 insertions, 106 deletions
diff --git a/src/lib/syscall/Makefile b/src/lib/syscall/Makefile index 8dd3d2fe0..5f613b9b4 100644 --- a/src/lib/syscall/Makefile +++ b/src/lib/syscall/Makefile @@ -5,7 +5,7 @@ # DO NOT EDIT. Automatically generated by gobuild. # gobuild -m errstr_darwin.go file_darwin.go socket_darwin.go\ # syscall_amd64_darwin.go time_amd64_darwin.go types_amd64_darwin.go\ -# asm_amd64_darwin.s cast_amd64.s syscall.go >Makefile +# asm_amd64_darwin.s cast_amd64.s syscall.go signal_amd64_darwin.go >Makefile O=6 GC=$(O)g CC=$(O)c -w @@ -40,6 +40,7 @@ O1=\ asm_$(GOARCH)_$(GOOS).$O\ cast_$(GOARCH).$O\ syscall.$O\ + signal_$(GOARCH)_$(GOOS).$O\ O2=\ file_$(GOOS).$O\ @@ -49,7 +50,7 @@ O2=\ syscall.a: a1 a2 a1: $(O1) - $(AR) grc syscall.a errstr_$(GOOS).$O syscall_$(GOARCH)_$(GOOS).$O types_$(GOARCH)_$(GOOS).$O asm_$(GOARCH)_$(GOOS).$O cast_$(GOARCH).$O syscall.$O + $(AR) grc syscall.a errstr_$(GOOS).$O syscall_$(GOARCH)_$(GOOS).$O types_$(GOARCH)_$(GOOS).$O asm_$(GOARCH)_$(GOOS).$O cast_$(GOARCH).$O syscall.$O signal_$(GOARCH)_$(GOOS).$O rm -f $(O1) a2: $(O2) diff --git a/src/lib/syscall/asm_amd64_darwin.s b/src/lib/syscall/asm_amd64_darwin.s index 3cf6aad83..dbc345c19 100644 --- a/src/lib/syscall/asm_amd64_darwin.s +++ b/src/lib/syscall/asm_amd64_darwin.s @@ -54,3 +54,21 @@ ok6: MOVQ $0, 80(SP) // errno CALL sys·exitsyscall(SB) RET + +TEXT syscall·RawSyscall(SB),7,$0 + MOVQ 16(SP), DI + MOVQ 24(SP), SI + MOVQ 32(SP), DX + MOVQ 8(SP), AX // syscall entry + ADDQ $0x2000000, AX + SYSCALL + JCC ok1 + MOVQ $-1, 40(SP) // r1 + MOVQ $0, 48(SP) // r2 + MOVQ AX, 56(SP) // errno + RET +ok1: + MOVQ AX, 40(SP) // r1 + MOVQ DX, 48(SP) // r2 + MOVQ $0, 56(SP) // errno + RET diff --git a/src/lib/syscall/asm_amd64_linux.s b/src/lib/syscall/asm_amd64_linux.s index e0c115387..2826c1b58 100644 --- a/src/lib/syscall/asm_amd64_linux.s +++ b/src/lib/syscall/asm_amd64_linux.s @@ -57,3 +57,22 @@ ok6: MOVQ $0, 80(SP) // errno CALL sys·exitsyscall(SB) RET + +TEXT syscall·RawSyscall(SB),7,$0 + MOVQ 16(SP), DI + MOVQ 24(SP), SI + MOVQ 32(SP), DX + MOVQ 8(SP), AX // syscall entry + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS ok1 + MOVQ $-1, 40(SP) // r1 + MOVQ $0, 48(SP) // r2 + NEGQ AX + MOVQ AX, 56(SP) // errno + RET +ok1: + MOVQ AX, 40(SP) // r1 + MOVQ DX, 48(SP) // r2 + MOVQ $0, 56(SP) // errno + RET diff --git a/src/lib/syscall/cast_amd64.s b/src/lib/syscall/cast_amd64.s index c2205b990..3eaa5e70e 100644 --- a/src/lib/syscall/cast_amd64.s +++ b/src/lib/syscall/cast_amd64.s @@ -8,6 +8,11 @@ TEXT syscall·BytePtr(SB),7,$-8 MOVQ AX, 16(SP) RET +TEXT syscall·BytePtrPtr(SB),7,$-8 + MOVQ 8(SP), AX + MOVQ AX, 16(SP) + RET + TEXT syscall·Int32Ptr(SB),7,$-8 MOVQ 8(SP), AX MOVQ AX, 16(SP) @@ -53,6 +58,11 @@ TEXT syscall·TimevalPtr(SB),7,$-8 MOVQ AX, 16(SP) RET +TEXT syscall·RusagePtr(SB),7,$-8 + MOVQ 8(SP), AX + MOVQ AX, 16(SP) + RET + TEXT syscall·SockaddrToSockaddrInet4(SB),7,$-8 MOVQ 8(SP), AX MOVQ AX, 16(SP) diff --git a/src/lib/syscall/file_darwin.go b/src/lib/syscall/file_darwin.go index 2cb78ffe5..0c6a38a3a 100644 --- a/src/lib/syscall/file_darwin.go +++ b/src/lib/syscall/file_darwin.go @@ -94,3 +94,9 @@ export func mkdir(name string, perm int64) (ret int64, errno int64) { r1, r2, err := Syscall(SYS_MKDIR, BytePtr(&namebuf[0]), perm, 0); return r1, err; } + +export func dup2(fd1, fd2 int64) (ret int64, errno int64) { + r1, r2, err := Syscall(SYS_DUP2, fd1, fd2, 0); + return r1, err; +} + diff --git a/src/lib/syscall/file_linux.go b/src/lib/syscall/file_linux.go index af7728a6b..3fa2588af 100644 --- a/src/lib/syscall/file_linux.go +++ b/src/lib/syscall/file_linux.go @@ -95,3 +95,9 @@ export func mkdir(name string, perm int64) (ret int64, errno int64) { r1, r2, err := Syscall(SYS_MKDIR, BytePtr(&namebuf[0]), perm, 0); return r1, err; } + +export func dup2(fd1, fd2 int64) (ret int64, errno int64) { + r1, r2, err := Syscall(SYS_DUP2, fd1, fd2, 0); + return r1, err; +} + diff --git a/src/lib/syscall/syscall.go b/src/lib/syscall/syscall.go index 6420684ce..eb1ad36a6 100644 --- a/src/lib/syscall/syscall.go +++ b/src/lib/syscall/syscall.go @@ -10,10 +10,12 @@ package syscall export func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64); export func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64); +export func RawSyscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64); export func BytePtr(b *byte) int64; export func Int32Ptr(p *int32) int64; export func Int64Ptr(p *int64) int64; +export func BytePtrPtr(b **byte) int64; /* * Used to convert file names to byte arrays for passing to kernel, diff --git a/src/lib/syscall/types_amd64_darwin.go b/src/lib/syscall/types_amd64_darwin.go index bb715ccb1..2c98fd521 100644 --- a/src/lib/syscall/types_amd64_darwin.go +++ b/src/lib/syscall/types_amd64_darwin.go @@ -23,6 +23,29 @@ export type Timeval struct { export func TimevalPtr(t *Timeval) int64; +// Processes + +export type Rusage struct { + utime Timeval; + stime Timeval; + maxrss int64; + ixrss int64; + idrss int64; + isrss int64; + minflt int64; + majflt int64; + nswap int64; + inblock int64; + oublock int64; + msgsnd int64; + msgrcv int64; + nsignals int64; + nvcsw int64; + nivcsw int64; +} +export func RusagePtr(r *Rusage) int64; + + // Files export const ( @@ -38,8 +61,13 @@ export const ( O_SYNC = 0x80; O_TRUNC = 0x400; + F_GETFD = 1; + F_SETFD = 2; + F_GETFL = 3; F_SETFL = 4; + + FD_CLOEXEC = 1; ) export type Stat struct { diff --git a/src/lib/syscall/types_amd64_linux.go b/src/lib/syscall/types_amd64_linux.go index 534827e3e..ccca2671c 100644 --- a/src/lib/syscall/types_amd64_linux.go +++ b/src/lib/syscall/types_amd64_linux.go @@ -23,6 +23,29 @@ export type Timeval struct { export func TimevalPtr(t *Timeval) int64; +// Processes + +export type Rusage struct { + utime Timeval; + stime Timeval; + maxrss int64; + ixrss int64; + idrss int64; + isrss int64; + minflt int64; + majflt int64; + nswap int64; + inblock int64; + oublock int64; + msgsnd int64; + msgrcv int64; + nsignals int64; + nvcsw int64; + nivcsw int64; +} +export func RusagePtr(r *Rusage) int64; + + // Files export const ( @@ -38,8 +61,13 @@ export const ( O_SYNC = 0x1000; O_TRUNC = 0x200; + F_GETFD = 1; + F_SETFD = 2; + F_GETFL = 3; F_SETFL = 4; + + FD_CLOEXEC = 1; ) export type Stat struct { diff --git a/src/runtime/rt1_amd64_darwin.c b/src/runtime/rt1_amd64_darwin.c index 82999b89f..7bd7c78fd 100644 --- a/src/runtime/rt1_amd64_darwin.c +++ b/src/runtime/rt1_amd64_darwin.c @@ -4,7 +4,7 @@ #include "runtime.h" #include "amd64_darwin.h" -#include "signals.h" +#include "signals_darwin.h" typedef uint64 __uint64_t; @@ -100,15 +100,14 @@ static _STRUCT_X86_FLOAT_STATE64 *get___fs(_STRUCT_MCONTEXT64 *ptr) { /* * This assembler routine takes the args from registers, puts them on the stack, - * and calls sighandler(). + * and calls the registered handler. */ -extern void sigtramp(); - +extern void sigtramp(void); /* * Rudimentary reverse-engineered definition of signal interface. * You'd think it would be documented. */ -typedef struct siginfo { +struct siginfo { int32 si_signo; /* signal number */ int32 si_errno; /* errno association */ int32 si_code; /* signal code */ @@ -117,21 +116,17 @@ typedef struct siginfo { int32 si_status; /* exit value */ void *si_addr; /* faulting address */ /* more stuff here */ -} siginfo; - +}; -typedef struct sigaction { - union { - void (*sa_handler)(int32); - void (*sa_sigaction)(int32, siginfo *, void *); - } u; /* signal handler */ - void (*sa_trampoline)(void); /* kernel callback point; calls sighandler() */ - uint8 sa_mask[4]; /* signal mask to apply */ - int32 sa_flags; /* see signal options below */ -} sigaction; +struct sigaction { + void (*sa_handler)(int32, struct siginfo*, void*); // actual handler + void (*sa_trampoline)(void); // assembly trampoline + uint32 sa_mask; // signal mask during handler + int32 sa_flags; // flags below +}; void -sighandler(int32 sig, siginfo *info, void *context) +sighandler(int32 sig, struct siginfo *info, void *context) { if(panicking) // traceback already printed sys·exit(2); @@ -159,15 +154,17 @@ sighandler(int32 sig, siginfo *info, void *context) sys·exit(2); } +void +sigignore(int32, struct siginfo*, void*) +{ +} + struct stack_t { byte *sp; int64 size; int32 flags; }; -sigaction a; -extern void sigtramp(void); - void signalstack(byte *p, int32 n) { @@ -179,21 +176,39 @@ signalstack(byte *p, int32 n) sigaltstack(&st, nil); } +void sigaction(int64, void*, void*); + +enum { + SA_SIGINFO = 0x40, + SA_RESTART = 0x02, + SA_ONSTACK = 0x01, + SA_USERTRAMP = 0x100, + SA_64REGSET = 0x200, +}; + void initsig(void) { int32 i; - - a.u.sa_sigaction = (void*)sigtramp; - a.sa_flags |= 0x41; /* SA_SIGINFO, SA_ONSTACK */ - for(i=0; i<sizeof(a.sa_mask); i++) - a.sa_mask[i] = 0xFF; - a.sa_trampoline = sigtramp; - - for(i = 0; i <NSIG; i++) - if(sigtab[i].catch){ - sys·sigaction(i, &a, (void*)0); + static struct sigaction sa; + + sa.sa_flags |= SA_SIGINFO|SA_ONSTACK; + sa.sa_mask = 0; // 0xFFFFFFFFU; + sa.sa_trampoline = sigtramp; + for(i = 0; i<NSIG; i++) { + if(sigtab[i].flags) { + if(sigtab[i].flags & SigCatch) { + sa.sa_handler = sighandler; + } else { + sa.sa_handler = sigignore; + } + if(sigtab[i].flags & SigRestart) + sa.sa_flags |= SA_RESTART; + else + sa.sa_flags &= ~SA_RESTART; + sigaction(i, &sa, nil); } + } } static void diff --git a/src/runtime/rt1_amd64_linux.c b/src/runtime/rt1_amd64_linux.c index ff9245a20..30a041066 100644 --- a/src/runtime/rt1_amd64_linux.c +++ b/src/runtime/rt1_amd64_linux.c @@ -4,7 +4,7 @@ #include "runtime.h" #include "amd64_linux.h" -#include "signals.h" +#include "signals_linux.h" /* From /usr/include/asm-x86_64/sigcontext.h */ struct _fpstate { @@ -105,37 +105,34 @@ print_sigcontext(struct sigcontext *sc) * This assembler routine takes the args from registers, puts them on the stack, * and calls sighandler(). */ -extern void sigtramp(); +extern void sigtramp(void); +extern void sigignore(void); // just returns +extern void sigreturn(void); // calls sigreturn /* * Rudimentary reverse-engineered definition of signal interface. * You'd think it would be documented. */ /* From /usr/include/bits/siginfo.h */ -typedef struct siginfo { +struct siginfo { int32 si_signo; /* signal number */ int32 si_errno; /* errno association */ int32 si_code; /* signal code */ int32 si_status; /* exit value */ void *si_addr; /* faulting address */ /* more stuff here */ -} siginfo; - +}; -/* From /usr/include/bits/sigaction.h */ -/* (gri) Is this correct? See e.g. /usr/include/asm-x86_64/signal.h */ -typedef struct sigaction { - union { - void (*sa_handler)(int32); - void (*sa_sigaction)(int32, siginfo *, void *); - } u; /* signal handler */ - uint8 sa_mask[128]; /* signal mask to apply. 128? are they KIDDING? */ - int32 sa_flags; /* see signal options below */ - void (*sa_restorer) (void); /* unused here; needed to return from trap? */ -} sigaction; +// This is a struct sigaction from /usr/include/asm/signal.h +struct sigaction { + void (*sa_handler)(int32, struct siginfo*, void*); + uint64 sa_flags; + void (*sa_restorer)(void); + uint64 sa_mask; +}; void -sighandler(int32 sig, siginfo* info, void** context) +sighandler(int32 sig, struct siginfo* info, void** context) { if(panicking) // traceback already printed sys·exit(2); @@ -182,21 +179,37 @@ signalstack(byte *p, int32 n) sigaltstack(&st, nil); } -static sigaction a; +void rt_sigaction(int64, void*, void*, uint64); + +enum { + SA_RESTART = 0x10000000, + SA_ONSTACK = 0x08000000, + SA_RESTORER = 0x04000000, + SA_SIGINFO = 0x00000004, +}; void initsig(void) { + static struct sigaction sa; + int32 i; - a.u.sa_sigaction = (void*)sigtramp; - a.sa_flags = 0x08000004; /* SA_ONSTACK, SA_SIGINFO */ - for(i=0; i<sizeof(a.sa_mask); i++) - a.sa_mask[i] = 0xFF; - - for(i = 0; i<NSIG; i++) - if(sigtab[i].catch){ - sys·rt_sigaction(i, &a, (void*)0, 8); + sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; + sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; + sa.sa_restorer = (void*)sigreturn; + for(i = 0; i<NSIG; i++) { + if(sigtab[i].flags) { + if(sigtab[i].flags & SigCatch) + sa.sa_handler = (void*)sigtramp; + else + sa.sa_handler = (void*)sigignore; + if(sigtab[i].flags & SigRestart) + sa.sa_flags |= SA_RESTART; + else + sa.sa_flags &= ~SA_RESTART; + rt_sigaction(i, &sa, nil, 8); } + } } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 4b282c126..e37786e4f 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -48,6 +48,7 @@ typedef union Note Note; typedef struct Stktop Stktop; typedef struct String *string; typedef struct Usema Usema; +typedef struct SigTab SigTab; /* * per cpu declaration @@ -179,9 +180,15 @@ struct Alg }; struct SigTab { - int32 catch; + int32 flags; int8 *name; }; +enum +{ + SigCatch = 1<<0, + SigIgnore = 1<<1, + SigRestart = 1<<2, +}; // (will be) shared with go; edit ../cmd/6g/sys.go too. // should move out of sys.go eventually. @@ -305,8 +312,6 @@ uint8* sys·mmap(byte*, uint32, int32, int32, int32, uint32); void sys·memclr(byte*, uint32); void sys·setcallerpc(void*, void*); void* sys·getcallerpc(void*); -void sys·sigaction(int64, void*, void*); -void sys·rt_sigaction(int64, void*, void*, uint64); /* * runtime go-called diff --git a/src/runtime/signals.h b/src/runtime/signals.h deleted file mode 100644 index 475f6752b..000000000 --- a/src/runtime/signals.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - - -static struct SigTab sigtab[] = { - /* 0 */ 0, "SIGNONE: no trap", - /* 1 */ 0, "SIGHUP: terminal line hangup", - /* 2 */ 0, "SIGINT: interrupt program", - /* 3 */ 1, "SIGQUIT: quit program", - /* 4 */ 1, "SIGILL: illegal instruction", - /* 5 */ 1, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */ - /* 6 */ 1, "SIGABRT: abort program", - /* 7 */ 1, "SIGEMT: emulate instruction executed", - /* 8 */ 1, "SIGFPE: floating-point exception", - /* 9 */ 0, "SIGKILL: kill program", - /* 10 */ 1, "SIGBUS: bus error", - /* 11 */ 1, "SIGSEGV: segmentation violation", - /* 12 */ 1, "SIGSYS: non-existent system call invoked", - /* 13 */ 0, "SIGPIPE: write on a pipe with no reader", - /* 14 */ 0, "SIGALRM: real-time timer expired", - /* 15 */ 0, "SIGTERM: software termination signal", - /* 16 */ 0, "SIGURG: urgent condition present on socket", - /* 17 */ 0, "SIGSTOP: stop", - /* 18 */ 0, "SIGTSTP: stop signal generated from keyboard", - /* 19 */ 0, "SIGCONT: continue after stop", - /* 20 */ 0, "SIGCHLD: child status has changed", - /* 21 */ 0, "SIGTTIN: background read attempted from control terminal", - /* 22 */ 0, "SIGTTOU: background write attempted to control terminal", - /* 23 */ 0, "SIGIO: I/O is possible on a descriptor", - /* 24 */ 0, "SIGXCPU: cpu time limit exceeded", - /* 25 */ 0, "SIGXFSZ: file size limit exceeded", - /* 26 */ 0, "SIGVTALRM: virtual time alarm", - /* 27 */ 0, "SIGPROF: profiling timer alarm", - /* 28 */ 0, "SIGWINCH: Window size change", - /* 29 */ 0, "SIGINFO: status request from keyboard", - /* 30 */ 0, "SIGUSR1: User defined signal 1", - /* 31 */ 0, "SIGUSR2: User defined signal 2", -}; -#define NSIG 32 diff --git a/src/runtime/signals_darwin.h b/src/runtime/signals_darwin.h new file mode 100644 index 000000000..c4d586049 --- /dev/null +++ b/src/runtime/signals_darwin.h @@ -0,0 +1,48 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + + +#define C SigCatch +#define I SigIgnore +#define R SigRestart + +static SigTab sigtab[] = { + /* 0 */ 0, "SIGNONE: no trap", + /* 1 */ 0, "SIGHUP: terminal line hangup", + /* 2 */ 0, "SIGINT: interrupt", + /* 3 */ C, "SIGQUIT: quit", + /* 4 */ C, "SIGILL: illegal instruction", + /* 5 */ C, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */ + /* 6 */ C, "SIGABRT: abort", + /* 7 */ C, "SIGEMT: emulate instruction executed", + /* 8 */ C, "SIGFPE: floating-point exception", + /* 9 */ 0, "SIGKILL: kill", + /* 10 */ C, "SIGBUS: bus error", + /* 11 */ C, "SIGSEGV: segmentation violation", + /* 12 */ C, "SIGSYS: bad system call", + /* 13 */ 0, "SIGPIPE: write to broken pipe", + /* 14 */ 0, "SIGALRM: alarm clock", + /* 15 */ 0, "SIGTERM: termination", + /* 16 */ 0, "SIGURG: urgent condition on socket", + /* 17 */ 0, "SIGSTOP: stop", + /* 18 */ 0, "SIGTSTP: keyboard stop", + /* 19 */ 0, "SIGCONT: continue after stop", + /* 20 */ I+R, "SIGCHLD: child status has changed", + /* 21 */ 0, "SIGTTIN: background read from tty", + /* 22 */ 0, "SIGTTOU: background write to tty", + /* 23 */ 0, "SIGIO: i/o now possible", + /* 24 */ 0, "SIGXCPU: cpu limit exceeded", + /* 25 */ 0, "SIGXFSZ: file size limit exceeded", + /* 26 */ 0, "SIGVTALRM: virtual alarm clock", + /* 27 */ 0, "SIGPROF: profiling alarm clock", + /* 28 */ I+R, "SIGWINCH: window size change", + /* 29 */ 0, "SIGINFO: status request from keyboard", + /* 30 */ 0, "SIGUSR1: user-defined signal 1", + /* 31 */ 0, "SIGUSR2: user-defined signal 2", +}; +#undef C +#undef I +#undef R + +#define NSIG 32 diff --git a/src/runtime/signals_linux.h b/src/runtime/signals_linux.h new file mode 100644 index 000000000..9e770e92f --- /dev/null +++ b/src/runtime/signals_linux.h @@ -0,0 +1,48 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + + +#define C SigCatch +#define I SigIgnore +#define R SigRestart + +static SigTab sigtab[] = { + /* 0 */ 0, "SIGNONE: no trap", + /* 1 */ 0, "SIGHUP: terminal line hangup", + /* 2 */ 0, "SIGINT: interrupt", + /* 3 */ C, "SIGQUIT: quit", + /* 4 */ C, "SIGILL: illegal instruction", + /* 5 */ C, "SIGTRAP: trace trap", + /* 6 */ C, "SIGABRT: abort", + /* 7 */ C, "SIGBUS: bus error", + /* 8 */ C, "SIGFPE: floating-point exception", + /* 9 */ 0, "SIGKILL: kill", + /* 10 */ 0, "SIGUSR1: user-defined signal 1", + /* 11 */ C, "SIGSEGV: segmentation violation", + /* 12 */ 0, "SIGUSR2: user-defined signal 2", + /* 13 */ 0, "SIGPIPE: write to broken pipe", + /* 14 */ 0, "SIGALRM: alarm clock", + /* 15 */ 0, "SIGTERM: termination", + /* 16 */ 0, "SIGSTKFLT: stack fault", + /* 17 */ I+R, "SIGCHLD: child status has changed", + /* 18 */ 0, "SIGCONT: continue", + /* 19 */ 0, "SIGSTOP: stop, unblockable", + /* 20 */ 0, "SIGTSTP: keyboard stop", + /* 21 */ 0, "SIGTTIN: background read from tty", + /* 22 */ 0, "SIGTTOU: background write to tty", + /* 23 */ 0, "SIGURG: urgent condition on socket", + /* 24 */ 0, "SIGXCPU: cpu limit exceeded", + /* 25 */ 0, "SIGXFSZ: file size limit exceeded", + /* 26 */ 0, "SIGVTALRM: virtual alarm clock", + /* 27 */ 0, "SIGPROF: profiling alarm clock", + /* 28 */ I+R, "SIGWINCH: window size change", + /* 29 */ 0, "SIGIO: i/o now possible", + /* 30 */ 0, "SIGPWR: power failure restart", + /* 31 */ C, "SIGSYS: bad system call", +}; +#undef C +#undef I +#undef R + +#define NSIG 32 diff --git a/src/runtime/sys_amd64_darwin.s b/src/runtime/sys_amd64_darwin.s index 6110362a7..a276576d9 100644 --- a/src/runtime/sys_amd64_darwin.s +++ b/src/runtime/sys_amd64_darwin.s @@ -73,7 +73,7 @@ TEXT write(SB),7,$-8 SYSCALL RET -TEXT sys·sigaction(SB),7,$-8 +TEXT sigaction(SB),7,$-8 MOVL 8(SP), DI // arg 1 sig MOVQ 16(SP), SI // arg 2 act MOVQ 24(SP), DX // arg 3 oact @@ -85,13 +85,19 @@ TEXT sys·sigaction(SB),7,$-8 CALL notok(SB) RET -TEXT sigtramp(SB),7,$24 +TEXT sigtramp(SB),7,$40 MOVQ 32(R14), R15 // g = m->gsignal MOVL DX,0(SP) MOVQ CX,8(SP) MOVQ R8,16(SP) - CALL sighandler(SB) - RET + MOVQ R8, 24(SP) // save ucontext + MOVQ SI, 32(SP) // save infostyle + CALL DI + MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle) + MOVQ 24(SP), DI // saved ucontext + MOVQ 32(SP), SI // saved infostyle + SYSCALL + INT $3 // not reached TEXT sys·mmap(SB),7,$-8 MOVQ 8(SP), DI // arg 1 addr diff --git a/src/runtime/sys_amd64_linux.s b/src/runtime/sys_amd64_linux.s index 581bf15ab..d385bb43e 100644 --- a/src/runtime/sys_amd64_linux.s +++ b/src/runtime/sys_amd64_linux.s @@ -63,7 +63,7 @@ TEXT sys·write(SB),7,$0-24 SYSCALL RET -TEXT sys·rt_sigaction(SB),7,$0-32 +TEXT rt_sigaction(SB),7,$0-32 MOVL 8(SP), DI MOVQ 16(SP), SI MOVQ 24(SP), DX @@ -80,6 +80,14 @@ TEXT sigtramp(SB),7,$24-16 CALL sighandler(SB) RET +TEXT sigignore(SB),7,$0 + RET + +TEXT sigreturn(SB),7,$0 + MOVL $15, AX // rt_sigreturn + SYSCALL + INT $3 // not reached + TEXT sys·mmap(SB),7,$0-32 MOVQ 8(SP), DI MOVQ $0, SI diff --git a/test/golden.out b/test/golden.out index 24f56b63a..4489d69cb 100644 --- a/test/golden.out +++ b/test/golden.out @@ -56,6 +56,9 @@ BUG: errchk: command succeeded unexpectedly: 6g ./method2.go -9223372036854775808 9223372036854775807 +=========== ./sigchld.go +survived SIGCHLD + =========== ./turing.go Hello World! diff --git a/test/sigchld.go b/test/sigchld.go new file mode 100644 index 000000000..417b833c7 --- /dev/null +++ b/test/sigchld.go @@ -0,0 +1,19 @@ +// $G $D/$F.go && $L $F.$A && ./$A.out + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "syscall" + +func getpid() int64 { + r1, r2, err := syscall.Syscall(syscall.SYS_GETPID, 0, 0, 0); + return r1; +} + +func main() { + syscall.Syscall(syscall.SYS_KILL, getpid(), syscall.SIGCHLD, 0); + println("survived SIGCHLD"); +} |
