Home | History | Annotate | Download | only in syscall
      1 // Copyright 2013 The Go Authors.  All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package syscall
      6 
      7 import (
      8 	"sync"
      9 	"unsafe"
     10 )
     11 
     12 //sys	naclClose(fd int) (err error) = sys_close
     13 //sys	Exit(code int) (err error)
     14 //sys	naclFstat(fd int, stat *Stat_t) (err error) = sys_fstat
     15 //sys	naclRead(fd int, b []byte) (n int, err error) = sys_read
     16 //sys	naclSeek(fd int, off *int64, whence int) (err error) = sys_lseek
     17 //sys	naclGetRandomBytes(b []byte) (err error) = sys_get_random_bytes
     18 
     19 const direntSize = 8 + 8 + 2 + 256
     20 
     21 // native_client/src/trusted/service_runtime/include/sys/dirent.h
     22 type Dirent struct {
     23 	Ino    int64
     24 	Off    int64
     25 	Reclen uint16
     26 	Name   [256]byte
     27 }
     28 
     29 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
     30 	origlen := len(buf)
     31 	count = 0
     32 	for max != 0 && len(buf) > 0 {
     33 		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
     34 		buf = buf[dirent.Reclen:]
     35 		if dirent.Ino == 0 { // File absent in directory.
     36 			continue
     37 		}
     38 		bytes := (*[512 + PathMax]byte)(unsafe.Pointer(&dirent.Name[0]))
     39 		var name = string(bytes[0:clen(bytes[:])])
     40 		if name == "." || name == ".." { // Useless names
     41 			continue
     42 		}
     43 		max--
     44 		count++
     45 		names = append(names, name)
     46 	}
     47 	return origlen - len(buf), count, names
     48 }
     49 
     50 func clen(n []byte) int {
     51 	for i := 0; i < len(n); i++ {
     52 		if n[i] == 0 {
     53 			return i
     54 		}
     55 	}
     56 	return len(n)
     57 }
     58 
     59 const PathMax = 256
     60 
     61 // An Errno is an unsigned number describing an error condition.
     62 // It implements the error interface.  The zero Errno is by convention
     63 // a non-error, so code to convert from Errno to error should use:
     64 //	err = nil
     65 //	if errno != 0 {
     66 //		err = errno
     67 //	}
     68 type Errno uintptr
     69 
     70 func (e Errno) Error() string {
     71 	if 0 <= int(e) && int(e) < len(errorstr) {
     72 		s := errorstr[e]
     73 		if s != "" {
     74 			return s
     75 		}
     76 	}
     77 	return "errno " + itoa(int(e))
     78 }
     79 
     80 func (e Errno) Temporary() bool {
     81 	return e == EINTR || e == EMFILE || e.Timeout()
     82 }
     83 
     84 func (e Errno) Timeout() bool {
     85 	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
     86 }
     87 
     88 // A Signal is a number describing a process signal.
     89 // It implements the os.Signal interface.
     90 type Signal int
     91 
     92 const (
     93 	_ Signal = iota
     94 	SIGCHLD
     95 	SIGINT
     96 	SIGKILL
     97 	SIGTRAP
     98 	SIGQUIT
     99 )
    100 
    101 func (s Signal) Signal() {}
    102 
    103 func (s Signal) String() string {
    104 	if 0 <= s && int(s) < len(signals) {
    105 		str := signals[s]
    106 		if str != "" {
    107 			return str
    108 		}
    109 	}
    110 	return "signal " + itoa(int(s))
    111 }
    112 
    113 var signals = [...]string{}
    114 
    115 // File system
    116 
    117 const (
    118 	Stdin  = 0
    119 	Stdout = 1
    120 	Stderr = 2
    121 )
    122 
    123 // native_client/src/trusted/service_runtime/include/sys/fcntl.h
    124 const (
    125 	O_RDONLY  = 0
    126 	O_WRONLY  = 1
    127 	O_RDWR    = 2
    128 	O_ACCMODE = 3
    129 
    130 	O_CREAT    = 0100
    131 	O_CREATE   = O_CREAT // for ken
    132 	O_TRUNC    = 01000
    133 	O_APPEND   = 02000
    134 	O_EXCL     = 0200
    135 	O_NONBLOCK = 04000
    136 	O_NDELAY   = O_NONBLOCK
    137 	O_SYNC     = 010000
    138 	O_FSYNC    = O_SYNC
    139 	O_ASYNC    = 020000
    140 
    141 	O_CLOEXEC = 0
    142 
    143 	FD_CLOEXEC = 1
    144 )
    145 
    146 // native_client/src/trusted/service_runtime/include/sys/fcntl.h
    147 const (
    148 	F_DUPFD   = 0
    149 	F_GETFD   = 1
    150 	F_SETFD   = 2
    151 	F_GETFL   = 3
    152 	F_SETFL   = 4
    153 	F_GETOWN  = 5
    154 	F_SETOWN  = 6
    155 	F_GETLK   = 7
    156 	F_SETLK   = 8
    157 	F_SETLKW  = 9
    158 	F_RGETLK  = 10
    159 	F_RSETLK  = 11
    160 	F_CNVT    = 12
    161 	F_RSETLKW = 13
    162 
    163 	F_RDLCK   = 1
    164 	F_WRLCK   = 2
    165 	F_UNLCK   = 3
    166 	F_UNLKSYS = 4
    167 )
    168 
    169 // native_client/src/trusted/service_runtime/include/bits/stat.h
    170 const (
    171 	S_IFMT        = 0000370000
    172 	S_IFSHM_SYSV  = 0000300000
    173 	S_IFSEMA      = 0000270000
    174 	S_IFCOND      = 0000260000
    175 	S_IFMUTEX     = 0000250000
    176 	S_IFSHM       = 0000240000
    177 	S_IFBOUNDSOCK = 0000230000
    178 	S_IFSOCKADDR  = 0000220000
    179 	S_IFDSOCK     = 0000210000
    180 
    181 	S_IFSOCK = 0000140000
    182 	S_IFLNK  = 0000120000
    183 	S_IFREG  = 0000100000
    184 	S_IFBLK  = 0000060000
    185 	S_IFDIR  = 0000040000
    186 	S_IFCHR  = 0000020000
    187 	S_IFIFO  = 0000010000
    188 
    189 	S_UNSUP = 0000370000
    190 
    191 	S_ISUID = 0004000
    192 	S_ISGID = 0002000
    193 	S_ISVTX = 0001000
    194 
    195 	S_IREAD  = 0400
    196 	S_IWRITE = 0200
    197 	S_IEXEC  = 0100
    198 
    199 	S_IRWXU = 0700
    200 	S_IRUSR = 0400
    201 	S_IWUSR = 0200
    202 	S_IXUSR = 0100
    203 
    204 	S_IRWXG = 070
    205 	S_IRGRP = 040
    206 	S_IWGRP = 020
    207 	S_IXGRP = 010
    208 
    209 	S_IRWXO = 07
    210 	S_IROTH = 04
    211 	S_IWOTH = 02
    212 	S_IXOTH = 01
    213 )
    214 
    215 // native_client/src/trusted/service_runtime/include/sys/stat.h
    216 // native_client/src/trusted/service_runtime/include/machine/_types.h
    217 type Stat_t struct {
    218 	Dev       int64
    219 	Ino       uint64
    220 	Mode      uint32
    221 	Nlink     uint32
    222 	Uid       uint32
    223 	Gid       uint32
    224 	Rdev      int64
    225 	Size      int64
    226 	Blksize   int32
    227 	Blocks    int32
    228 	Atime     int64
    229 	AtimeNsec int64
    230 	Mtime     int64
    231 	MtimeNsec int64
    232 	Ctime     int64
    233 	CtimeNsec int64
    234 }
    235 
    236 // Processes
    237 // Not supported on NaCl - just enough for package os.
    238 
    239 var ForkLock sync.RWMutex
    240 
    241 type WaitStatus uint32
    242 
    243 func (w WaitStatus) Exited() bool       { return false }
    244 func (w WaitStatus) ExitStatus() int    { return 0 }
    245 func (w WaitStatus) Signaled() bool     { return false }
    246 func (w WaitStatus) Signal() Signal     { return 0 }
    247 func (w WaitStatus) CoreDump() bool     { return false }
    248 func (w WaitStatus) Stopped() bool      { return false }
    249 func (w WaitStatus) Continued() bool    { return false }
    250 func (w WaitStatus) StopSignal() Signal { return 0 }
    251 func (w WaitStatus) TrapCause() int     { return 0 }
    252 
    253 // XXX made up
    254 type Rusage struct {
    255 	Utime Timeval
    256 	Stime Timeval
    257 }
    258 
    259 // XXX made up
    260 type ProcAttr struct {
    261 	Dir   string
    262 	Env   []string
    263 	Files []uintptr
    264 	Sys   *SysProcAttr
    265 }
    266 
    267 type SysProcAttr struct {
    268 }
    269 
    270 // System
    271 
    272 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
    273 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { return 0, 0, ENOSYS }
    274 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)           { return 0, 0, ENOSYS }
    275 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
    276 	return 0, 0, ENOSYS
    277 }
    278 
    279 func Sysctl(key string) (string, error) {
    280 	if key == "kern.hostname" {
    281 		return "naclbox", nil
    282 	}
    283 	return "", ENOSYS
    284 }
    285 
    286 // Unimplemented Unix midden heap.
    287 
    288 const ImplementsGetwd = false
    289 
    290 func Getwd() (wd string, err error)     { return "", ENOSYS }
    291 func Getegid() int                      { return 1 }
    292 func Geteuid() int                      { return 1 }
    293 func Getgid() int                       { return 1 }
    294 func Getgroups() ([]int, error)         { return []int{1}, nil }
    295 func Getpagesize() int                  { return 65536 }
    296 func Getppid() int                      { return 2 }
    297 func Getpid() int                       { return 3 }
    298 func Getuid() int                       { return 1 }
    299 func Kill(pid int, signum Signal) error { return ENOSYS }
    300 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
    301 	return 0, ENOSYS
    302 }
    303 func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
    304 	return 0, 0, ENOSYS
    305 }
    306 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
    307 	return 0, ENOSYS
    308 }
    309 func RouteRIB(facility, param int) ([]byte, error)                { return nil, ENOSYS }
    310 func ParseRoutingMessage(b []byte) ([]RoutingMessage, error)      { return nil, ENOSYS }
    311 func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) { return nil, ENOSYS }
    312 func SysctlUint32(name string) (value uint32, err error)          { return 0, ENOSYS }
    313