diff --git a/GNUmakefile b/GNUmakefile index f06f28a18c..d3982e8976 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -338,6 +338,7 @@ TEST_PACKAGES_FAST = \ net/http/internal/ascii \ net/mail \ os \ + os/signal \ path \ reflect \ sync \ diff --git a/lib/musl b/lib/musl index 7a43f6fea9..0784374d56 160000 --- a/lib/musl +++ b/lib/musl @@ -1 +1 @@ -Subproject commit 7a43f6fea9081bdd53d8a11cef9e9fab0348c53d +Subproject commit 0784374d561435f7c787a555aeab8ede699ed298 diff --git a/loader/goroot.go b/loader/goroot.go index 8661bf67e0..80f1f9fe76 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -247,6 +247,7 @@ func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool { "net/": true, "net/http/": false, "os/": true, + "os/signal": false, "os/user/": false, "reflect/": false, "runtime/": false, diff --git a/src/os/exec.go b/src/os/exec.go index cf295e6fb7..fada70f479 100644 --- a/src/os/exec.go +++ b/src/os/exec.go @@ -47,6 +47,10 @@ func (p *ProcessState) Sys() interface{} { return nil // TODO } +func (p *ProcessState) Exited() bool { + return false // TODO +} + // ExitCode returns the exit code of the exited process, or -1 // if the process hasn't exited or was terminated by a signal. func (p *ProcessState) ExitCode() int { diff --git a/src/os/signal/signal_linux.go b/src/os/signal/signal_linux.go new file mode 100644 index 0000000000..391fb5c7d9 --- /dev/null +++ b/src/os/signal/signal_linux.go @@ -0,0 +1,54 @@ +// Copyright 2012 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. + +//go:build !plan9 && !windows && !js && !wasm && !wasip1 && !wasip2 +// +build !plan9,!windows,!js,!wasm,!wasip1,!wasip2 + +package signal + +import ( + "os" + "syscall" +) + +const ( + numSig = 65 // max across all systems +) + +type Signal interface { + String() string + Signal() // to distinguish from other Stringers +} + +// Defined by the runtime package and used by syscall/sigqueue.go. +func signal_disable(uint32) +func signal_enable(uint32) +func signal_ignore(uint32) +func signal_ignored(uint32) bool +func signal_recv() uint32 + +func signum(sig os.Signal) int { + switch sig := sig.(type) { + case syscall.Signal: + i := int(sig) + if i < 0 || i >= numSig { + return -1 + } + return i + default: + return -1 + } +} + +func enableSignal(sig int) { + signal_enable(uint32(sig)) +} + +func disableSignal(sig int) { + signal_disable(uint32(sig)) +} + +func ignoreSignal(sig int) { + signal_ignore(uint32(sig)) +} diff --git a/src/os/signal/signal_linux_test.go b/src/os/signal/signal_linux_test.go new file mode 100644 index 0000000000..9c58cafd35 --- /dev/null +++ b/src/os/signal/signal_linux_test.go @@ -0,0 +1,30 @@ +//go:build !plan9 && !windows && !js && !wasm && !wasip1 && !wasip2 +// +build !plan9,!windows,!js,!wasm,!wasip1,!wasip2 + +package signal + +import ( + "runtime" + "testing" +) + +// The file sigqueue.go contains preliminary stubs for signal handling. +// Since tinygo ultimately lacks support for signals, these stubs are +// placeholders for future work. +// There might be userland applications that rely on these functions +// from the upstream go package os/signal that we want to enable +// building and linking. + +func TestSignalHandling(t *testing.T) { + if runtime.GOOS == "wasip1" || runtime.GOOS == "wasip2" { + t.Skip() + } + + // This test is a placeholder for future work. + // It is here to ensure that the stubs in sigqueue.go + // are correctly linked and can be called from userland + // applications. + enableSignal(0) + disableSignal(0) + ignoreSignal(0) +} diff --git a/src/runtime/sigqueue.go b/src/runtime/sigqueue.go new file mode 100644 index 0000000000..ff789a605f --- /dev/null +++ b/src/runtime/sigqueue.go @@ -0,0 +1,26 @@ +// 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. + +//go:build !plan9 +// +build !plan9 + +package runtime + +// Stub definitions copied from upstream golang +// TODO: implement a minimal functional version of these functions + +// go: linkname os/signal.signal_disable signal_disable +func signal_disable(_ uint32) {} + +// go: linkname os/signal.signal_enable signal_enable +func signal_enable(_ uint32) {} + +// go: linkname os/signal.signal_ignore signal_ignore +func signal_ignore(_ uint32) {} + +// go: linkname os/signal.signal_ignored signal_ignored +func signal_ignored(_ uint32) bool { return true } + +// go: linkname os/signal.signal_recv signal_recv +func signal_recv() uint32 { return 0 } diff --git a/src/syscall/syscall_libc_darwin.go b/src/syscall/syscall_libc_darwin.go index d64f1061f3..0ca9c56ada 100644 --- a/src/syscall/syscall_libc_darwin.go +++ b/src/syscall/syscall_libc_darwin.go @@ -81,18 +81,39 @@ type Signal int // Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/signal.h const ( - SIGINT Signal = 2 /* interrupt */ - SIGQUIT Signal = 3 /* quit */ - SIGILL Signal = 4 /* illegal instruction (not reset when caught) */ - SIGTRAP Signal = 5 /* trace trap (not reset when caught) */ - SIGABRT Signal = 6 /* abort() */ - SIGFPE Signal = 8 /* floating point exception */ - SIGKILL Signal = 9 /* kill (cannot be caught or ignored) */ - SIGBUS Signal = 10 /* bus error */ - SIGSEGV Signal = 11 /* segmentation violation */ - SIGPIPE Signal = 13 /* write on a pipe with no one to read it */ - SIGTERM Signal = 15 /* software termination signal from kill */ - SIGCHLD Signal = 20 /* to parent on child stop or exit */ + SIGHUP Signal = 1 /* hangup */ + SIGINT Signal = 2 /* interrupt */ + SIGQUIT Signal = 3 /* quit */ + SIGILL Signal = 4 /* illegal instruction (not reset when caught) */ + SIGTRAP Signal = 5 /* trace trap (not reset when caught) */ + SIGABRT Signal = 6 /* abort() */ + SIGPOLL Signal = 7 /* pollable event ([XSR] generated, not supported) */ + SIGIOT Signal = SIGABRT /* compatibility */ + SIGEMT Signal = 7 /* EMT instruction */ + SIGFPE Signal = 8 /* floating point exception */ + SIGKILL Signal = 9 /* kill (cannot be caught or ignored) */ + SIGBUS Signal = 10 /* bus error */ + SIGSEGV Signal = 11 /* segmentation violation */ + SIGSYS Signal = 12 /* bad argument to system call */ + SIGPIPE Signal = 13 /* write on a pipe with no one to read it */ + SIGALRM Signal = 14 /* alarm clock */ + SIGTERM Signal = 15 /* software termination signal from kill */ + SIGURG Signal = 16 /* urgent condition on IO channel */ + SIGSTOP Signal = 17 /* sendable stop signal not from tty */ + SIGTSTP Signal = 18 /* stop signal from tty */ + SIGCONT Signal = 19 /* continue a stopped process */ + SIGCHLD Signal = 20 /* to parent on child stop or exit */ + SIGTTIN Signal = 21 /* to readers pgrp upon background tty read */ + SIGTTOU Signal = 22 /* like TTIN for output if (tp->t_local<OSTOP) */ + SIGIO Signal = 23 /* input/output possible signal */ + SIGXCPU Signal = 24 /* exceeded CPU time limit */ + SIGXFSZ Signal = 25 /* exceeded file size limit */ + SIGVTALRM Signal = 26 /* virtual time alarm */ + SIGPROF Signal = 27 /* profiling time alarm */ + SIGWINCH Signal = 28 /* window size changes */ + SIGINFO Signal = 29 /* information request */ + SIGUSR1 Signal = 30 /* user defined signal 1 */ + SIGUSR2 Signal = 31 /* user defined signal 2 */ ) func (s Signal) Signal() {}