mirror of
https://github.com/golang/go
synced 2024-11-25 11:07:59 -07:00
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:
parent
2b39165f1e
commit
dfa5893d4f
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
static struct sigaction sa;
|
||||
|
||||
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);
|
||||
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
|
||||
|
@ -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)
|
||||
{
|
||||
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;
|
||||
static struct sigaction sa;
|
||||
|
||||
for(i = 0; i<NSIG; i++)
|
||||
if(sigtab[i].catch){
|
||||
sys·rt_sigaction(i, &a, (void*)0, 8);
|
||||
int32 i;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
48
src/runtime/signals_darwin.h
Normal file
48
src/runtime/signals_darwin.h
Normal 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
|
48
src/runtime/signals_linux.h
Normal file
48
src/runtime/signals_linux.h
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -56,6 +56,9 @@ BUG: errchk: command succeeded unexpectedly: 6g ./method2.go
|
||||
-9223372036854775808
|
||||
9223372036854775807
|
||||
|
||||
=========== ./sigchld.go
|
||||
survived SIGCHLD
|
||||
|
||||
=========== ./turing.go
|
||||
Hello World!
|
||||
|
||||
|
19
test/sigchld.go
Normal file
19
test/sigchld.go
Normal 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");
|
||||
}
|
Loading…
Reference in New Issue
Block a user