| // Copyright 2013 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 syscall |
| |
| import ( |
| "sync" |
| "unsafe" |
| ) |
| |
| //sys naclClose(fd int) (err error) = sys_close |
| //sys Exit(code int) (err error) |
| //sys naclFstat(fd int, stat *Stat_t) (err error) = sys_fstat |
| //sys naclRead(fd int, b []byte) (n int, err error) = sys_read |
| //sys naclSeek(fd int, off *int64, whence int) (err error) = sys_lseek |
| //sys naclGetRandomBytes(b []byte) (err error) = sys_get_random_bytes |
| |
| const direntSize = 8 + 8 + 2 + 256 |
| |
| // native_client/src/trusted/service_runtime/include/sys/dirent.h |
| type Dirent struct { |
| Ino int64 |
| Off int64 |
| Reclen uint16 |
| Name [256]byte |
| } |
| |
| func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) { |
| origlen := len(buf) |
| count = 0 |
| for max != 0 && len(buf) > 0 { |
| dirent := (*Dirent)(unsafe.Pointer(&buf[0])) |
| buf = buf[dirent.Reclen:] |
| if dirent.Ino == 0 { // File absent in directory. |
| continue |
| } |
| bytes := (*[512 + PathMax]byte)(unsafe.Pointer(&dirent.Name[0])) |
| var name = string(bytes[0:clen(bytes[:])]) |
| if name == "." || name == ".." { // Useless names |
| continue |
| } |
| max-- |
| count++ |
| names = append(names, name) |
| } |
| return origlen - len(buf), count, names |
| } |
| |
| func clen(n []byte) int { |
| for i := 0; i < len(n); i++ { |
| if n[i] == 0 { |
| return i |
| } |
| } |
| return len(n) |
| } |
| |
| const PathMax = 256 |
| |
| // An Errno is an unsigned number describing an error condition. |
| // It implements the error interface. The zero Errno is by convention |
| // a non-error, so code to convert from Errno to error should use: |
| // err = nil |
| // if errno != 0 { |
| // err = errno |
| // } |
| type Errno uintptr |
| |
| func (e Errno) Error() string { |
| if 0 <= int(e) && int(e) < len(errorstr) { |
| s := errorstr[e] |
| if s != "" { |
| return s |
| } |
| } |
| return "errno " + itoa(int(e)) |
| } |
| |
| func (e Errno) Temporary() bool { |
| return e == EINTR || e == EMFILE || e.Timeout() |
| } |
| |
| func (e Errno) Timeout() bool { |
| return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT |
| } |
| |
| // A Signal is a number describing a process signal. |
| // It implements the os.Signal interface. |
| type Signal int |
| |
| const ( |
| _ Signal = iota |
| SIGCHLD |
| SIGINT |
| SIGKILL |
| SIGTRAP |
| SIGQUIT |
| ) |
| |
| 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(int(s)) |
| } |
| |
| var signals = [...]string{} |
| |
| // File system |
| |
| const ( |
| Stdin = 0 |
| Stdout = 1 |
| Stderr = 2 |
| ) |
| |
| // native_client/src/trusted/service_runtime/include/sys/fcntl.h |
| const ( |
| O_RDONLY = 0 |
| O_WRONLY = 1 |
| O_RDWR = 2 |
| O_ACCMODE = 3 |
| |
| O_CREAT = 0100 |
| O_CREATE = O_CREAT // for ken |
| O_TRUNC = 01000 |
| O_APPEND = 02000 |
| O_EXCL = 0200 |
| O_NONBLOCK = 04000 |
| O_NDELAY = O_NONBLOCK |
| O_SYNC = 010000 |
| O_FSYNC = O_SYNC |
| O_ASYNC = 020000 |
| |
| O_CLOEXEC = 0 |
| |
| FD_CLOEXEC = 1 |
| ) |
| |
| // native_client/src/trusted/service_runtime/include/sys/fcntl.h |
| const ( |
| F_DUPFD = 0 |
| F_GETFD = 1 |
| F_SETFD = 2 |
| F_GETFL = 3 |
| F_SETFL = 4 |
| F_GETOWN = 5 |
| F_SETOWN = 6 |
| F_GETLK = 7 |
| F_SETLK = 8 |
| F_SETLKW = 9 |
| F_RGETLK = 10 |
| F_RSETLK = 11 |
| F_CNVT = 12 |
| F_RSETLKW = 13 |
| |
| F_RDLCK = 1 |
| F_WRLCK = 2 |
| F_UNLCK = 3 |
| F_UNLKSYS = 4 |
| ) |
| |
| // native_client/src/trusted/service_runtime/include/bits/stat.h |
| const ( |
| S_IFMT = 0000370000 |
| S_IFSHM_SYSV = 0000300000 |
| S_IFSEMA = 0000270000 |
| S_IFCOND = 0000260000 |
| S_IFMUTEX = 0000250000 |
| S_IFSHM = 0000240000 |
| S_IFBOUNDSOCK = 0000230000 |
| S_IFSOCKADDR = 0000220000 |
| S_IFDSOCK = 0000210000 |
| |
| S_IFSOCK = 0000140000 |
| S_IFLNK = 0000120000 |
| S_IFREG = 0000100000 |
| S_IFBLK = 0000060000 |
| S_IFDIR = 0000040000 |
| S_IFCHR = 0000020000 |
| S_IFIFO = 0000010000 |
| |
| S_UNSUP = 0000370000 |
| |
| S_ISUID = 0004000 |
| S_ISGID = 0002000 |
| S_ISVTX = 0001000 |
| |
| S_IREAD = 0400 |
| S_IWRITE = 0200 |
| S_IEXEC = 0100 |
| |
| S_IRWXU = 0700 |
| S_IRUSR = 0400 |
| S_IWUSR = 0200 |
| S_IXUSR = 0100 |
| |
| S_IRWXG = 070 |
| S_IRGRP = 040 |
| S_IWGRP = 020 |
| S_IXGRP = 010 |
| |
| S_IRWXO = 07 |
| S_IROTH = 04 |
| S_IWOTH = 02 |
| S_IXOTH = 01 |
| ) |
| |
| // native_client/src/trusted/service_runtime/include/sys/stat.h |
| // native_client/src/trusted/service_runtime/include/machine/_types.h |
| type Stat_t struct { |
| Dev int64 |
| Ino uint64 |
| Mode uint32 |
| Nlink uint32 |
| Uid uint32 |
| Gid uint32 |
| Rdev int64 |
| Size int64 |
| Blksize int32 |
| Blocks int32 |
| Atime int64 |
| AtimeNsec int64 |
| Mtime int64 |
| MtimeNsec int64 |
| Ctime int64 |
| CtimeNsec int64 |
| } |
| |
| // Processes |
| // Not supported on NaCl - just enough for package os. |
| |
| var ForkLock sync.RWMutex |
| |
| type WaitStatus uint32 |
| |
| func (w WaitStatus) Exited() bool { return false } |
| func (w WaitStatus) ExitStatus() int { return 0 } |
| func (w WaitStatus) Signaled() bool { return false } |
| func (w WaitStatus) Signal() Signal { return 0 } |
| func (w WaitStatus) CoreDump() bool { return false } |
| func (w WaitStatus) Stopped() bool { return false } |
| func (w WaitStatus) Continued() bool { return false } |
| func (w WaitStatus) StopSignal() Signal { return 0 } |
| func (w WaitStatus) TrapCause() int { return 0 } |
| |
| // XXX made up |
| type Rusage struct { |
| Utime Timeval |
| Stime Timeval |
| } |
| |
| // XXX made up |
| type ProcAttr struct { |
| Dir string |
| Env []string |
| Files []uintptr |
| Sys *SysProcAttr |
| } |
| |
| type SysProcAttr struct { |
| } |
| |
| // System |
| |
| func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) |
| func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { return 0, 0, ENOSYS } |
| func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { return 0, 0, ENOSYS } |
| func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { |
| return 0, 0, ENOSYS |
| } |
| |
| func Sysctl(key string) (string, error) { |
| if key == "kern.hostname" { |
| return "naclbox", nil |
| } |
| return "", ENOSYS |
| } |
| |
| // Unimplemented Unix midden heap. |
| |
| const ImplementsGetwd = false |
| |
| func Getwd() (wd string, err error) { return "", ENOSYS } |
| func Getegid() int { return 1 } |
| func Geteuid() int { return 1 } |
| func Getgid() int { return 1 } |
| func Getgroups() ([]int, error) { return []int{1}, nil } |
| func Getpagesize() int { return 65536 } |
| func Getppid() int { return 2 } |
| func Getpid() int { return 3 } |
| func Getuid() int { return 1 } |
| func Kill(pid int, signum Signal) error { return ENOSYS } |
| func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
| return 0, ENOSYS |
| } |
| func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { |
| return 0, 0, ENOSYS |
| } |
| func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { |
| return 0, ENOSYS |
| } |
| func RouteRIB(facility, param int) ([]byte, error) { return nil, ENOSYS } |
| func ParseRoutingMessage(b []byte) ([]RoutingMessage, error) { return nil, ENOSYS } |
| func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { return nil, ENOSYS } |
| func SysctlUint32(name string) (value uint32, err error) { return 0, ENOSYS } |