tinygo/src/syscall/syscall_libc_darwin.go

321 строка
6,5 КиБ
Go

//go:build darwin
package syscall
import (
"internal/itoa"
"unsafe"
)
// This file defines errno and constants to match the darwin libsystem ABI.
// Values have been copied from src/syscall/zerrors_darwin_amd64.go.
// This function returns the error location in the darwin ABI.
// Discovered by compiling the following code using Clang:
//
// #include <errno.h>
// int getErrno() {
// return errno;
// }
//
//export __error
func libc___error() *int32
// getErrno returns the current C errno. It may not have been caused by the last
// call, so it should only be relied upon when the last call indicates an error
// (for example, by returning -1).
func getErrno() Errno {
errptr := libc___error()
return Errno(uintptr(*errptr))
}
func (e Errno) Is(target error) bool {
switch target.Error() {
case "permission denied":
return e == EACCES || e == EPERM
case "file already exists":
return e == EEXIST
case "file does not exist":
return e == ENOENT
}
return false
}
// Source: upstream zerrors_darwin_amd64.go
const (
DT_BLK = 0x6
DT_CHR = 0x2
DT_DIR = 0x4
DT_FIFO = 0x1
DT_LNK = 0xa
DT_REG = 0x8
DT_SOCK = 0xc
DT_UNKNOWN = 0x0
DT_WHT = 0xe
F_GETFL = 0x3
F_SETFL = 0x4
O_NONBLOCK = 0x4
)
// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/errno.h.auto.html
const (
EPERM Errno = 1
ENOENT Errno = 2
EACCES Errno = 13
EEXIST Errno = 17
EINTR Errno = 4
ENOTDIR Errno = 20
EISDIR Errno = 21
EINVAL Errno = 22
EMFILE Errno = 24
EPIPE Errno = 32
EAGAIN Errno = 35
ENOTCONN Errno = 57
ETIMEDOUT Errno = 60
ENOSYS Errno = 78
EWOULDBLOCK Errno = EAGAIN
)
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 */
)
func (s Signal) Signal() {}
func (s Signal) String() string {
if 0 <= s && int(s) < len(signals) {
str := signals[s]
if str != "" {
return str
}
}
return "signal " + itoa.Itoa(int(s))
}
var signals = [...]string{}
const (
Stdin = 0
Stdout = 1
Stderr = 2
)
const (
O_RDONLY = 0x0
O_WRONLY = 0x1
O_RDWR = 0x2
O_APPEND = 0x8
O_SYNC = 0x80
O_CREAT = 0x200
O_TRUNC = 0x400
O_EXCL = 0x800
O_CLOEXEC = 0x01000000
)
// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/mman.h.auto.html
const (
PROT_NONE = 0x00 // no permissions
PROT_READ = 0x01 // pages can be read
PROT_WRITE = 0x02 // pages can be written
PROT_EXEC = 0x04 // pages can be executed
MAP_SHARED = 0x0001 // share changes
MAP_PRIVATE = 0x0002 // changes are private
MAP_FILE = 0x0000 // map from file (default)
MAP_ANON = 0x1000 // allocated from memory, swap space
MAP_ANONYMOUS = MAP_ANON
)
type Timespec struct {
Sec int64
Nsec int64
}
// Unix returns the time stored in ts as seconds plus nanoseconds.
func (ts *Timespec) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}
// Source: upstream ztypes_darwin_amd64.go
type Dirent struct {
Ino uint64
Seekoff uint64
Reclen uint16
Namlen uint16
Type uint8
Name [1024]int8
Pad_cgo_0 [3]byte
}
type Stat_t struct {
Dev int32
Mode uint16
Nlink uint16
Ino uint64
Uid uint32
Gid uint32
Rdev int32
Pad_cgo_0 [4]byte
Atimespec Timespec
Mtimespec Timespec
Ctimespec Timespec
Btimespec Timespec
Size int64
Blocks int64
Blksize int32
Flags uint32
Gen uint32
Lspare int32
Qspare [2]int64
}
// Source: https://github.com/apple/darwin-xnu/blob/main/bsd/sys/_types/_s_ifmt.h
const (
S_IEXEC = 0x40
S_IFBLK = 0x6000
S_IFCHR = 0x2000
S_IFDIR = 0x4000
S_IFIFO = 0x1000
S_IFLNK = 0xa000
S_IFMT = 0xf000
S_IFREG = 0x8000
S_IFSOCK = 0xc000
S_IFWHT = 0xe000
S_IREAD = 0x100
S_IRGRP = 0x20
S_IROTH = 0x4
S_IRUSR = 0x100
S_IRWXG = 0x38
S_IRWXO = 0x7
S_IRWXU = 0x1c0
S_ISGID = 0x400
S_ISTXT = 0x200
S_ISUID = 0x800
S_ISVTX = 0x200
S_IWGRP = 0x10
S_IWOTH = 0x2
S_IWRITE = 0x80
S_IWUSR = 0x80
S_IXGRP = 0x8
S_IXOTH = 0x1
S_IXUSR = 0x40
)
func Stat(path string, p *Stat_t) (err error) {
data := cstring(path)
n := libc_stat(&data[0], unsafe.Pointer(p))
if n < 0 {
err = getErrno()
}
return
}
func Fstat(fd int, p *Stat_t) (err error) {
n := libc_fstat(int32(fd), unsafe.Pointer(p))
if n < 0 {
err = getErrno()
}
return
}
func Lstat(path string, p *Stat_t) (err error) {
data := cstring(path)
n := libc_lstat(&data[0], unsafe.Pointer(p))
if n < 0 {
err = getErrno()
}
return
}
func Fdopendir(fd int) (dir uintptr, err error) {
r0 := libc_fdopendir(int32(fd))
dir = uintptr(r0)
if dir == 0 {
err = getErrno()
}
return
}
func Pipe2(fds []int, flags int) (err error) {
// Mac only has Pipe, which ignores the flags argument
buf := make([]int32, 2)
fail := int(libc_pipe(&buf[0]))
if fail < 0 {
err = getErrno()
} else {
fds[0] = int(buf[0])
fds[1] = int(buf[1])
}
return
}
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) {
e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result))
if e1 != 0 {
err = getErrno()
}
return
}
func Getpagesize() int {
return int(libc_getpagesize())
}
// The following RawSockAddr* types have been copied from the Go source tree and
// are here purely to fix build errors.
type RawSockaddr struct {
Len uint8
Family uint8
Data [14]int8
}
type RawSockaddrInet4 struct {
Len uint8
Family uint8
Port uint16
Addr [4]byte /* in_addr */
Zero [8]int8
}
type RawSockaddrInet6 struct {
Len uint8
Family uint8
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
// int pipe(int32 *fds);
//
//export pipe
func libc_pipe(fds *int32) int32
// int getpagesize();
//
//export getpagesize
func libc_getpagesize() int32
// int open(const char *pathname, int flags, mode_t mode);
//
//export syscall_libc_open
func libc_open(pathname *byte, flags int32, mode uint32) int32