Files
llgo/runtime/internal/lib/syscall/syscall_linux.go
2025-02-14 19:02:32 +08:00

138 lines
3.4 KiB
Go

// 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.
// Linux system calls.
// This file is compiled as ordinary Go code,
// but it is also input to mksyscall,
// which parses the //sys lines and generates system call stubs.
// Note that sometimes we use a lowercase //sys name and
// wrap it in our own nicer implementation.
package syscall
import (
origSyscall "syscall"
_ "unsafe"
c "github.com/goplus/llgo/runtime/internal/clite"
"github.com/goplus/llgo/runtime/internal/clite/os"
"github.com/goplus/llgo/runtime/internal/clite/syscall"
)
// -----------------------------------------------------------------------------
type WaitStatus uint32
// Wait status is 7 bits at bottom, either 0 (exited),
// 0x7F (stopped), or a signal number that caused an exit.
// The 0x80 bit is whether there was a core dump.
// An extra number (exit code, signal causing a stop)
// is in the high bits. At least that's the idea.
// There are various irregularities. For example, the
// "continued" status is 0xFFFF, distinguishing itself
// from stopped via the core dump bit.
const (
mask = 0x7F
core = 0x80
exited = 0x00
stopped = 0x7F
shift = 8
)
func (w WaitStatus) Exited() bool { return w&mask == exited }
func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
func (w WaitStatus) Continued() bool { return w == 0xFFFF }
func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
func (w WaitStatus) ExitStatus() int {
if !w.Exited() {
return -1
}
return int(w>>shift) & 0xFF
}
func (w WaitStatus) Signal() Signal {
if !w.Signaled() {
return -1
}
return Signal(w & mask)
}
func (w WaitStatus) StopSignal() Signal {
if !w.Stopped() {
return -1
}
return Signal(w>>shift) & 0xFF
}
func (w WaitStatus) TrapCause() int {
/*
if w.StopSignal() != SIGTRAP {
return -1
}
return int(w>>shift) >> 8
*/
panic("todo: syscall.WaitStatus.TrapCause")
}
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *syscall.Rusage) (wpid int, err error) {
var status c.Int
wpid, err = wait4(pid, &status, options, rusage)
if wstatus != nil {
*wstatus = WaitStatus(status)
}
return
}
// -----------------------------------------------------------------------------
// int pipe2(int pipefd[2], int flags);
//
//go:linkname pipe2 C.pipe2
func pipe2(pipefd *[2]c.Int, flags c.Int) c.Int
func Pipe2(p []int, flags int) error {
if len(p) != 2 {
return Errno(syscall.EINVAL)
}
var pp [2]c.Int
ret := pipe2(&pp, c.Int(flags))
if ret == 0 {
p[0] = int(pp[0])
p[1] = int(pp[1])
return nil
}
return Errno(ret)
}
// -----------------------------------------------------------------------------
func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
ret := faccessat(c.Int(dirfd), c.AllocaCStr(path), c.Int(mode), c.Int(flags))
if ret != 0 {
return Errno(os.Errno())
}
return nil
}
//go:linkname faccessat C.faccessat
func faccessat(dirfd c.Int, path *c.Char, mode c.Int, flags c.Int) c.Int
// -----------------------------------------------------------------------------
func Accept4(fd int, flags int) (nfd int, sa origSyscall.Sockaddr, err error) {
panic("todo: syscall.Accept4")
}
func Uname(buf *origSyscall.Utsname) (err error) {
panic("todo: syscall.Uname")
}