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
This commit is contained in:
Russ Cox 2008-12-03 14:21:28 -08:00
parent 2b39165f1e
commit dfa5893d4f
19 changed files with 348 additions and 105 deletions

View file

@ -5,7 +5,7 @@
# DO NOT EDIT. Automatically generated by gobuild. # DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m errstr_darwin.go file_darwin.go socket_darwin.go\ # gobuild -m errstr_darwin.go file_darwin.go socket_darwin.go\
# syscall_amd64_darwin.go time_amd64_darwin.go types_amd64_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 O=6
GC=$(O)g GC=$(O)g
CC=$(O)c -w CC=$(O)c -w
@ -40,6 +40,7 @@ O1=\
asm_$(GOARCH)_$(GOOS).$O\ asm_$(GOARCH)_$(GOOS).$O\
cast_$(GOARCH).$O\ cast_$(GOARCH).$O\
syscall.$O\ syscall.$O\
signal_$(GOARCH)_$(GOOS).$O\
O2=\ O2=\
file_$(GOOS).$O\ file_$(GOOS).$O\
@ -49,7 +50,7 @@ O2=\
syscall.a: a1 a2 syscall.a: a1 a2
a1: $(O1) 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) rm -f $(O1)
a2: $(O2) a2: $(O2)

View file

@ -54,3 +54,21 @@ ok6:
MOVQ $0, 80(SP) // errno MOVQ $0, 80(SP) // errno
CALL sys·exitsyscall(SB) CALL sys·exitsyscall(SB)
RET 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

View file

@ -57,3 +57,22 @@ ok6:
MOVQ $0, 80(SP) // errno MOVQ $0, 80(SP) // errno
CALL sys·exitsyscall(SB) CALL sys·exitsyscall(SB)
RET 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

View file

@ -8,6 +8,11 @@ TEXT syscall·BytePtr(SB),7,$-8
MOVQ AX, 16(SP) MOVQ AX, 16(SP)
RET RET
TEXT syscall·BytePtrPtr(SB),7,$-8
MOVQ 8(SP), AX
MOVQ AX, 16(SP)
RET
TEXT syscall·Int32Ptr(SB),7,$-8 TEXT syscall·Int32Ptr(SB),7,$-8
MOVQ 8(SP), AX MOVQ 8(SP), AX
MOVQ AX, 16(SP) MOVQ AX, 16(SP)
@ -53,6 +58,11 @@ TEXT syscall·TimevalPtr(SB),7,$-8
MOVQ AX, 16(SP) MOVQ AX, 16(SP)
RET RET
TEXT syscall·RusagePtr(SB),7,$-8
MOVQ 8(SP), AX
MOVQ AX, 16(SP)
RET
TEXT syscall·SockaddrToSockaddrInet4(SB),7,$-8 TEXT syscall·SockaddrToSockaddrInet4(SB),7,$-8
MOVQ 8(SP), AX MOVQ 8(SP), AX
MOVQ AX, 16(SP) MOVQ AX, 16(SP)

View file

@ -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); r1, r2, err := Syscall(SYS_MKDIR, BytePtr(&namebuf[0]), perm, 0);
return r1, err; 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;
}

View file

@ -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); r1, r2, err := Syscall(SYS_MKDIR, BytePtr(&namebuf[0]), perm, 0);
return r1, err; 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;
}

View file

@ -10,10 +10,12 @@ package syscall
export func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64); 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 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 BytePtr(b *byte) int64;
export func Int32Ptr(p *int32) int64; export func Int32Ptr(p *int32) int64;
export func Int64Ptr(p *int64) 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, * Used to convert file names to byte arrays for passing to kernel,

View file

@ -23,6 +23,29 @@ export type Timeval struct {
export func TimevalPtr(t *Timeval) int64; 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 // Files
export const ( export const (
@ -38,8 +61,13 @@ export const (
O_SYNC = 0x80; O_SYNC = 0x80;
O_TRUNC = 0x400; O_TRUNC = 0x400;
F_GETFD = 1;
F_SETFD = 2;
F_GETFL = 3; F_GETFL = 3;
F_SETFL = 4; F_SETFL = 4;
FD_CLOEXEC = 1;
) )
export type Stat struct { export type Stat struct {

View file

@ -23,6 +23,29 @@ export type Timeval struct {
export func TimevalPtr(t *Timeval) int64; 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 // Files
export const ( export const (
@ -38,8 +61,13 @@ export const (
O_SYNC = 0x1000; O_SYNC = 0x1000;
O_TRUNC = 0x200; O_TRUNC = 0x200;
F_GETFD = 1;
F_SETFD = 2;
F_GETFL = 3; F_GETFL = 3;
F_SETFL = 4; F_SETFL = 4;
FD_CLOEXEC = 1;
) )
export type Stat struct { export type Stat struct {

View file

@ -4,7 +4,7 @@
#include "runtime.h" #include "runtime.h"
#include "amd64_darwin.h" #include "amd64_darwin.h"
#include "signals.h" #include "signals_darwin.h"
typedef uint64 __uint64_t; 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, * 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. * Rudimentary reverse-engineered definition of signal interface.
* You'd think it would be documented. * You'd think it would be documented.
*/ */
typedef struct siginfo { struct siginfo {
int32 si_signo; /* signal number */ int32 si_signo; /* signal number */
int32 si_errno; /* errno association */ int32 si_errno; /* errno association */
int32 si_code; /* signal code */ int32 si_code; /* signal code */
@ -117,21 +116,17 @@ typedef struct siginfo {
int32 si_status; /* exit value */ int32 si_status; /* exit value */
void *si_addr; /* faulting address */ void *si_addr; /* faulting address */
/* more stuff here */ /* more stuff here */
} siginfo; };
struct sigaction {
typedef struct sigaction { void (*sa_handler)(int32, struct siginfo*, void*); // actual handler
union { void (*sa_trampoline)(void); // assembly trampoline
void (*sa_handler)(int32); uint32 sa_mask; // signal mask during handler
void (*sa_sigaction)(int32, siginfo *, void *); int32 sa_flags; // flags below
} 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;
void void
sighandler(int32 sig, siginfo *info, void *context) sighandler(int32 sig, struct siginfo *info, void *context)
{ {
if(panicking) // traceback already printed if(panicking) // traceback already printed
sys·exit(2); sys·exit(2);
@ -159,15 +154,17 @@ sighandler(int32 sig, siginfo *info, void *context)
sys·exit(2); sys·exit(2);
} }
void
sigignore(int32, struct siginfo*, void*)
{
}
struct stack_t { struct stack_t {
byte *sp; byte *sp;
int64 size; int64 size;
int32 flags; int32 flags;
}; };
sigaction a;
extern void sigtramp(void);
void void
signalstack(byte *p, int32 n) signalstack(byte *p, int32 n)
{ {
@ -179,21 +176,39 @@ signalstack(byte *p, int32 n)
sigaltstack(&st, nil); 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 void
initsig(void) initsig(void)
{ {
int32 i; int32 i;
static struct sigaction sa;
a.u.sa_sigaction = (void*)sigtramp; sa.sa_flags |= SA_SIGINFO|SA_ONSTACK;
a.sa_flags |= 0x41; /* SA_SIGINFO, SA_ONSTACK */ sa.sa_mask = 0; // 0xFFFFFFFFU;
for(i=0; i<sizeof(a.sa_mask); i++) sa.sa_trampoline = sigtramp;
a.sa_mask[i] = 0xFF; for(i = 0; i<NSIG; i++) {
a.sa_trampoline = sigtramp; if(sigtab[i].flags) {
if(sigtab[i].flags & SigCatch) {
for(i = 0; i <NSIG; i++) sa.sa_handler = sighandler;
if(sigtab[i].catch){ } else {
sys·sigaction(i, &a, (void*)0); 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 static void

View file

@ -4,7 +4,7 @@
#include "runtime.h" #include "runtime.h"
#include "amd64_linux.h" #include "amd64_linux.h"
#include "signals.h" #include "signals_linux.h"
/* From /usr/include/asm-x86_64/sigcontext.h */ /* From /usr/include/asm-x86_64/sigcontext.h */
struct _fpstate { struct _fpstate {
@ -105,37 +105,34 @@ print_sigcontext(struct sigcontext *sc)
* This assembler routine takes the args from registers, puts them on the stack, * This assembler routine takes the args from registers, puts them on the stack,
* and calls sighandler(). * 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. * Rudimentary reverse-engineered definition of signal interface.
* You'd think it would be documented. * You'd think it would be documented.
*/ */
/* From /usr/include/bits/siginfo.h */ /* From /usr/include/bits/siginfo.h */
typedef struct siginfo { struct siginfo {
int32 si_signo; /* signal number */ int32 si_signo; /* signal number */
int32 si_errno; /* errno association */ int32 si_errno; /* errno association */
int32 si_code; /* signal code */ int32 si_code; /* signal code */
int32 si_status; /* exit value */ int32 si_status; /* exit value */
void *si_addr; /* faulting address */ void *si_addr; /* faulting address */
/* more stuff here */ /* more stuff here */
} siginfo; };
// This is a struct sigaction from /usr/include/asm/signal.h
/* From /usr/include/bits/sigaction.h */ struct sigaction {
/* (gri) Is this correct? See e.g. /usr/include/asm-x86_64/signal.h */ void (*sa_handler)(int32, struct siginfo*, void*);
typedef struct sigaction { uint64 sa_flags;
union { void (*sa_restorer)(void);
void (*sa_handler)(int32); uint64 sa_mask;
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;
void void
sighandler(int32 sig, siginfo* info, void** context) sighandler(int32 sig, struct siginfo* info, void** context)
{ {
if(panicking) // traceback already printed if(panicking) // traceback already printed
sys·exit(2); sys·exit(2);
@ -182,21 +179,37 @@ signalstack(byte *p, int32 n)
sigaltstack(&st, nil); 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 void
initsig(void) initsig(void)
{ {
int32 i; static struct sigaction sa;
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++) int32 i;
if(sigtab[i].catch){ sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
sys·rt_sigaction(i, &a, (void*)0, 8); 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);
} }
}
} }

View file

@ -48,6 +48,7 @@ typedef union Note Note;
typedef struct Stktop Stktop; typedef struct Stktop Stktop;
typedef struct String *string; typedef struct String *string;
typedef struct Usema Usema; typedef struct Usema Usema;
typedef struct SigTab SigTab;
/* /*
* per cpu declaration * per cpu declaration
@ -179,9 +180,15 @@ struct Alg
}; };
struct SigTab struct SigTab
{ {
int32 catch; int32 flags;
int8 *name; int8 *name;
}; };
enum
{
SigCatch = 1<<0,
SigIgnore = 1<<1,
SigRestart = 1<<2,
};
// (will be) shared with go; edit ../cmd/6g/sys.go too. // (will be) shared with go; edit ../cmd/6g/sys.go too.
// should move out of sys.go eventually. // 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·memclr(byte*, uint32);
void sys·setcallerpc(void*, void*); void sys·setcallerpc(void*, void*);
void* sys·getcallerpc(void*); void* sys·getcallerpc(void*);
void sys·sigaction(int64, void*, void*);
void sys·rt_sigaction(int64, void*, void*, uint64);
/* /*
* runtime go-called * runtime go-called

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -73,7 +73,7 @@ TEXT write(SB),7,$-8
SYSCALL SYSCALL
RET RET
TEXT sys·sigaction(SB),7,$-8 TEXT sigaction(SB),7,$-8
MOVL 8(SP), DI // arg 1 sig MOVL 8(SP), DI // arg 1 sig
MOVQ 16(SP), SI // arg 2 act MOVQ 16(SP), SI // arg 2 act
MOVQ 24(SP), DX // arg 3 oact MOVQ 24(SP), DX // arg 3 oact
@ -85,13 +85,19 @@ TEXT sys·sigaction(SB),7,$-8
CALL notok(SB) CALL notok(SB)
RET RET
TEXT sigtramp(SB),7,$24 TEXT sigtramp(SB),7,$40
MOVQ 32(R14), R15 // g = m->gsignal MOVQ 32(R14), R15 // g = m->gsignal
MOVL DX,0(SP) MOVL DX,0(SP)
MOVQ CX,8(SP) MOVQ CX,8(SP)
MOVQ R8,16(SP) MOVQ R8,16(SP)
CALL sighandler(SB) MOVQ R8, 24(SP) // save ucontext
RET 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 TEXT sys·mmap(SB),7,$-8
MOVQ 8(SP), DI // arg 1 addr MOVQ 8(SP), DI // arg 1 addr

View file

@ -63,7 +63,7 @@ TEXT sys·write(SB),7,$0-24
SYSCALL SYSCALL
RET RET
TEXT sys·rt_sigaction(SB),7,$0-32 TEXT rt_sigaction(SB),7,$0-32
MOVL 8(SP), DI MOVL 8(SP), DI
MOVQ 16(SP), SI MOVQ 16(SP), SI
MOVQ 24(SP), DX MOVQ 24(SP), DX
@ -80,6 +80,14 @@ TEXT sigtramp(SB),7,$24-16
CALL sighandler(SB) CALL sighandler(SB)
RET 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 TEXT sys·mmap(SB),7,$0-32
MOVQ 8(SP), DI MOVQ 8(SP), DI
MOVQ $0, SI MOVQ $0, SI

View file

@ -56,6 +56,9 @@ BUG: errchk: command succeeded unexpectedly: 6g ./method2.go
-9223372036854775808 -9223372036854775808
9223372036854775807 9223372036854775807
=========== ./sigchld.go
survived SIGCHLD
=========== ./turing.go =========== ./turing.go
Hello World! Hello World!

19
test/sigchld.go Normal file
View file

@ -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");
}