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// +build darwin linux 6 7package interp 8 9import "syscall" 10 11func init() { 12 for k, v := range map[string]externalFn{ 13 "os.Pipe": ext۰os۰Pipe, 14 "syscall.Close": ext۰syscall۰Close, 15 "syscall.Exit": ext۰syscall۰Exit, 16 "syscall.Fchown": ext۰syscall۰Fchown, 17 "syscall.Fstat": ext۰syscall۰Fstat, 18 "syscall.Ftruncate": ext۰syscall۰Ftruncate, 19 "syscall.Getpid": ext۰syscall۰Getpid, 20 "syscall.Getwd": ext۰syscall۰Getwd, 21 "syscall.Kill": ext۰syscall۰Kill, 22 "syscall.Link": ext۰syscall۰Link, 23 "syscall.Lstat": ext۰syscall۰Lstat, 24 "syscall.Mkdir": ext۰syscall۰Mkdir, 25 "syscall.Open": ext۰syscall۰Open, 26 "syscall.ParseDirent": ext۰syscall۰ParseDirent, 27 "syscall.RawSyscall": ext۰syscall۰RawSyscall, 28 "syscall.Read": ext۰syscall۰Read, 29 "syscall.ReadDirent": ext۰syscall۰ReadDirent, 30 "syscall.Readlink": ext۰syscall۰Readlink, 31 "syscall.Rmdir": ext۰syscall۰Rmdir, 32 "syscall.Seek": ext۰syscall۰Seek, 33 "syscall.Stat": ext۰syscall۰Stat, 34 "syscall.Symlink": ext۰syscall۰Symlink, 35 "syscall.Write": ext۰syscall۰Write, 36 "syscall.Unlink": ext۰syscall۰Unlink, 37 "syscall۰UtimesNano": ext۰syscall۰UtimesNano, 38 "syscall.setenv_c": ext۰nop, 39 "syscall.unsetenv_c": ext۰nop, 40 "syscall.runtime_envs": ext۰runtime۰environ, 41 } { 42 externals[k] = v 43 } 44 45 syswrite = syscall.Write 46} 47 48func ext۰os۰Pipe(fr *frame, args []value) value { 49 // func os.Pipe() (r *File, w *File, err error) 50 51 // The portable POSIX pipe(2) call is good enough for our needs. 52 var p [2]int 53 if err := syscall.Pipe(p[:]); err != nil { 54 // TODO(adonovan): fix: return an *os.SyscallError. 55 return tuple{nil, nil, wrapError(err)} 56 } 57 58 NewFile := fr.i.prog.ImportedPackage("os").Func("NewFile") 59 r := call(fr.i, fr, 0, NewFile, []value{uintptr(p[0]), "|0"}) 60 w := call(fr.i, fr, 0, NewFile, []value{uintptr(p[1]), "|1"}) 61 return tuple{r, w, wrapError(nil)} 62} 63 64// overridden on darwin 65var fillStat = func(st *syscall.Stat_t, stat structure) { 66 stat[0] = st.Dev 67 stat[1] = st.Ino 68 stat[2] = st.Nlink 69 stat[3] = st.Mode 70 stat[4] = st.Uid 71 stat[5] = st.Gid 72 stat[7] = st.Rdev 73 stat[8] = st.Size 74 stat[9] = st.Blksize 75 stat[10] = st.Blocks 76 // TODO(adonovan): fix: copy Timespecs. 77 // stat[11] = st.Atim 78 // stat[12] = st.Mtim 79 // stat[13] = st.Ctim 80} 81 82func ext۰syscall۰Close(fr *frame, args []value) value { 83 // func Close(fd int) (err error) 84 return wrapError(syscall.Close(args[0].(int))) 85} 86 87func ext۰syscall۰Exit(fr *frame, args []value) value { 88 panic(exitPanic(args[0].(int))) 89} 90 91func ext۰syscall۰Fchown(fr *frame, args []value) value { 92 fd := args[0].(int) 93 uid := args[1].(int) 94 gid := args[2].(int) 95 return wrapError(syscall.Fchown(fd, uid, gid)) 96} 97 98func ext۰syscall۰Fstat(fr *frame, args []value) value { 99 // func Fstat(fd int, stat *Stat_t) (err error) 100 fd := args[0].(int) 101 stat := (*args[1].(*value)).(structure) 102 103 var st syscall.Stat_t 104 err := syscall.Fstat(fd, &st) 105 fillStat(&st, stat) 106 return wrapError(err) 107} 108 109func ext۰syscall۰Ftruncate(fr *frame, args []value) value { 110 fd := args[0].(int) 111 length := args[1].(int64) 112 return wrapError(syscall.Ftruncate(fd, length)) 113} 114 115func ext۰syscall۰Getpid(fr *frame, args []value) value { 116 return syscall.Getpid() 117} 118 119func ext۰syscall۰Getwd(fr *frame, args []value) value { 120 s, err := syscall.Getwd() 121 return tuple{s, wrapError(err)} 122} 123 124func ext۰syscall۰Kill(fr *frame, args []value) value { 125 // func Kill(pid int, sig Signal) (err error) 126 return wrapError(syscall.Kill(args[0].(int), syscall.Signal(args[1].(int)))) 127} 128 129func ext۰syscall۰Link(fr *frame, args []value) value { 130 path := args[0].(string) 131 link := args[1].(string) 132 return wrapError(syscall.Link(path, link)) 133} 134 135func ext۰syscall۰Lstat(fr *frame, args []value) value { 136 // func Lstat(name string, stat *Stat_t) (err error) 137 name := args[0].(string) 138 stat := (*args[1].(*value)).(structure) 139 140 var st syscall.Stat_t 141 err := syscall.Lstat(name, &st) 142 fillStat(&st, stat) 143 return wrapError(err) 144} 145 146func ext۰syscall۰Mkdir(fr *frame, args []value) value { 147 path := args[0].(string) 148 mode := args[1].(uint32) 149 return wrapError(syscall.Mkdir(path, mode)) 150} 151 152func ext۰syscall۰Open(fr *frame, args []value) value { 153 // func Open(path string, mode int, perm uint32) (fd int, err error) { 154 path := args[0].(string) 155 mode := args[1].(int) 156 perm := args[2].(uint32) 157 fd, err := syscall.Open(path, mode, perm) 158 return tuple{fd, wrapError(err)} 159} 160 161func ext۰syscall۰ParseDirent(fr *frame, args []value) value { 162 // func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) 163 max := args[1].(int) 164 var names []string 165 for _, iname := range args[2].([]value) { 166 names = append(names, iname.(string)) 167 } 168 consumed, count, newnames := syscall.ParseDirent(valueToBytes(args[0]), max, names) 169 var inewnames []value 170 for _, newname := range newnames { 171 inewnames = append(inewnames, newname) 172 } 173 return tuple{consumed, count, inewnames} 174} 175 176func ext۰syscall۰RawSyscall(fr *frame, args []value) value { 177 return tuple{uintptr(0), uintptr(0), uintptr(syscall.ENOSYS)} 178} 179 180func ext۰syscall۰Read(fr *frame, args []value) value { 181 // func Read(fd int, p []byte) (n int, err error) 182 fd := args[0].(int) 183 p := args[1].([]value) 184 b := make([]byte, len(p)) 185 n, err := syscall.Read(fd, b) 186 for i := 0; i < n; i++ { 187 p[i] = b[i] 188 } 189 return tuple{n, wrapError(err)} 190} 191 192func ext۰syscall۰ReadDirent(fr *frame, args []value) value { 193 // func ReadDirent(fd int, buf []byte) (n int, err error) 194 fd := args[0].(int) 195 p := args[1].([]value) 196 b := make([]byte, len(p)) 197 n, err := syscall.ReadDirent(fd, b) 198 for i := 0; i < n; i++ { 199 p[i] = b[i] 200 } 201 return tuple{n, wrapError(err)} 202} 203 204func ext۰syscall۰Readlink(fr *frame, args []value) value { 205 path := args[0].(string) 206 buf := valueToBytes(args[1]) 207 n, err := syscall.Readlink(path, buf) 208 return tuple{n, wrapError(err)} 209} 210 211func ext۰syscall۰Rmdir(fr *frame, args []value) value { 212 return wrapError(syscall.Rmdir(args[0].(string))) 213} 214 215func ext۰syscall۰Seek(fr *frame, args []value) value { 216 fd := args[0].(int) 217 offset := args[1].(int64) 218 whence := args[2].(int) 219 new, err := syscall.Seek(fd, offset, whence) 220 return tuple{new, wrapError(err)} 221} 222 223func ext۰syscall۰Stat(fr *frame, args []value) value { 224 // func Stat(name string, stat *Stat_t) (err error) 225 name := args[0].(string) 226 stat := (*args[1].(*value)).(structure) 227 228 var st syscall.Stat_t 229 err := syscall.Stat(name, &st) 230 fillStat(&st, stat) 231 return wrapError(err) 232} 233 234func ext۰syscall۰Symlink(fr *frame, args []value) value { 235 path := args[0].(string) 236 link := args[1].(string) 237 return wrapError(syscall.Symlink(path, link)) 238} 239 240func ext۰syscall۰Unlink(fr *frame, args []value) value { 241 return wrapError(syscall.Unlink(args[0].(string))) 242} 243 244func ext۰syscall۰UtimesNano(fr *frame, args []value) value { 245 path := args[0].(string) 246 var ts [2]syscall.Timespec 247 err := syscall.UtimesNano(path, ts[:]) 248 // TODO(adonovan): copy the Timespecs into args[1] 249 return wrapError(err) 250} 251 252func ext۰syscall۰Write(fr *frame, args []value) value { 253 // func Write(fd int, p []byte) (n int, err error) 254 n, err := write(args[0].(int), valueToBytes(args[1])) 255 return tuple{n, wrapError(err)} 256} 257