]> Cypherpunks repositories - gostls13.git/commitdiff
preparation for exec.
authorRuss Cox <rsc@golang.org>
Wed, 3 Dec 2008 22:21:28 +0000 (14:21 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 3 Dec 2008 22:21:28 +0000 (14:21 -0800)
* 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

19 files changed:
src/lib/syscall/Makefile
src/lib/syscall/asm_amd64_darwin.s
src/lib/syscall/asm_amd64_linux.s
src/lib/syscall/cast_amd64.s
src/lib/syscall/file_darwin.go
src/lib/syscall/file_linux.go
src/lib/syscall/syscall.go
src/lib/syscall/types_amd64_darwin.go
src/lib/syscall/types_amd64_linux.go
src/runtime/rt1_amd64_darwin.c
src/runtime/rt1_amd64_linux.c
src/runtime/runtime.h
src/runtime/signals.h [deleted file]
src/runtime/signals_darwin.h [new file with mode: 0644]
src/runtime/signals_linux.h [new file with mode: 0644]
src/runtime/sys_amd64_darwin.s
src/runtime/sys_amd64_linux.s
test/golden.out
test/sigchld.go [new file with mode: 0644]

index 8dd3d2fe0fb0167c66a6fa88049b68aa8ef8d56a..5f613b9b42117591cadc65c10894e8266812734c 100644 (file)
@@ -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)
index 3cf6aad8310d0db2c1c76f1893ba56365996d045..dbc345c19d61bdac415e0e6bc4eb7efc349e19b5 100644 (file)
@@ -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
index e0c1153878b5bc283c389fa092d9b55efeb29570..2826c1b5806bd143582105308d85431cfeb47d93 100644 (file)
@@ -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
index c2205b990ed7e06d5147c8759aeaeaa97b63eee3..3eaa5e70e6c5fd7bbba83813109c7fb90d65ff41 100644 (file)
@@ -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)
index 2cb78ffe5c96c1be2276babc2accd15aa9facb17..0c6a38a3add3f243f80ae65611045ee10faedfe7 100644 (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);
        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;
+}
+
index af7728a6b1d30179c429f3b0092f51b83c925e75..3fa2588aff98283af30935ef1c0bf28fe56c180e 100644 (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);
        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;
+}
+
index 6420684ce0ccfd78889f4562bacb1959b7fc8636..eb1ad36a64bd3ed1e07944fc3b2b1f89d214e4c8 100644 (file)
@@ -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,
index bb715ccb165fa86ab11ab96d7bce169ad8a779fd..2c98fd521e33f2f0b2b55196c05cc8ff8c625a14 100644 (file)
@@ -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 {
index 534827e3e9637ceecb237e36ff589c2ea0c14609..ccca2671cd501ef785926de7576636ff59bd1b27 100644 (file)
@@ -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 {
index 82999b89f95d48eaf2ec93fa7193fdc1ecf683ed..7bd7c78fdc82c35979ae014382f2aed3c549f3a8 100644 (file)
@@ -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
index ff9245a202dc3694221010a8de22654a5f1145db..30a04106677afdc639014759df640a8425d6474b 100644 (file)
@@ -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);
                }
+       }
 }
 
 
index 4b282c1265746b2f633736013a9136e2138b298c..e37786e4fb6d1833616a93f1d033484f653d8438 100644 (file)
@@ -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 (file)
index 475f675..0000000
+++ /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 (file)
index 0000000..c4d5860
--- /dev/null
@@ -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 (file)
index 0000000..9e770e9
--- /dev/null
@@ -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
index 6110362a7c18bf305b04ddf831d415808140247c..a276576d9d3e1db20d8ed961cf4d3f6369544667 100644 (file)
@@ -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
index 581bf15ab5e974190e9807f0d08e65aa830cd883..d385bb43ecc432a912a6852bb89ca3314032fdaa 100644 (file)
@@ -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
index 24f56b63a293f21b3e8214d0c55bb870486bd5e1..4489d69cbda36ce6eba540712b08456f639910a2 100644 (file)
@@ -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 (file)
index 0000000..417b833
--- /dev/null
@@ -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");
+}