github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/syscall/syscall_unix.go (about) 1 // Copyright 2009 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 dragonfly freebsd linux netbsd openbsd solaris 6 7 package syscall 8 9 import ( 10 "runtime" 11 "sync" 12 "unsafe" 13 ) 14 15 var ( 16 Stdin = 0 17 Stdout = 1 18 Stderr = 2 19 ) 20 21 const ( 22 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 23 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 24 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 25 ) 26 27 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 28 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 29 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 30 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 31 32 // Mmap manager, for use by operating system-specific implementations. 33 34 type mmapper struct { 35 sync.Mutex 36 active map[*byte][]byte // active mappings; key is last byte in mapping 37 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error) 38 munmap func(addr uintptr, length uintptr) error 39 } 40 41 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 42 if length <= 0 { 43 return nil, EINVAL 44 } 45 46 // Map the requested memory. 47 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset) 48 if errno != nil { 49 return nil, errno 50 } 51 52 // Slice memory layout 53 var sl = struct { 54 addr uintptr 55 len int 56 cap int 57 }{addr, length, length} 58 59 // Use unsafe to turn sl into a []byte. 60 b := *(*[]byte)(unsafe.Pointer(&sl)) 61 62 // Register mapping in m and return it. 63 p := &b[cap(b)-1] 64 m.Lock() 65 defer m.Unlock() 66 m.active[p] = b 67 return b, nil 68 } 69 70 func (m *mmapper) Munmap(data []byte) (err error) { 71 if len(data) == 0 || len(data) != cap(data) { 72 return EINVAL 73 } 74 75 // Find the base of the mapping. 76 p := &data[cap(data)-1] 77 m.Lock() 78 defer m.Unlock() 79 b := m.active[p] 80 if b == nil || &b[0] != &data[0] { 81 return EINVAL 82 } 83 84 // Unmap the memory and update m. 85 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil { 86 return errno 87 } 88 delete(m.active, p) 89 return nil 90 } 91 92 // An Errno is an unsigned number describing an error condition. 93 // It implements the error interface. The zero Errno is by convention 94 // a non-error, so code to convert from Errno to error should use: 95 // err = nil 96 // if errno != 0 { 97 // err = errno 98 // } 99 type Errno uintptr 100 101 func (e Errno) Error() string { 102 if 0 <= int(e) && int(e) < len(errors) { 103 s := errors[e] 104 if s != "" { 105 return s 106 } 107 } 108 return "errno " + itoa(int(e)) 109 } 110 111 func (e Errno) Temporary() bool { 112 return e == EINTR || e == EMFILE || e == ECONNRESET || e == ECONNABORTED || e.Timeout() 113 } 114 115 func (e Errno) Timeout() bool { 116 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT 117 } 118 119 // A Signal is a number describing a process signal. 120 // It implements the os.Signal interface. 121 type Signal int 122 123 func (s Signal) Signal() {} 124 125 func (s Signal) String() string { 126 if 0 <= s && int(s) < len(signals) { 127 str := signals[s] 128 if str != "" { 129 return str 130 } 131 } 132 return "signal " + itoa(int(s)) 133 } 134 135 func Read(fd int, p []byte) (n int, err error) { 136 n, err = read(fd, p) 137 if raceenabled { 138 if n > 0 { 139 raceWriteRange(unsafe.Pointer(&p[0]), n) 140 } 141 if err == nil { 142 raceAcquire(unsafe.Pointer(&ioSync)) 143 } 144 } 145 return 146 } 147 148 func Write(fd int, p []byte) (n int, err error) { 149 if raceenabled { 150 raceReleaseMerge(unsafe.Pointer(&ioSync)) 151 } 152 n, err = write(fd, p) 153 if raceenabled && n > 0 { 154 raceReadRange(unsafe.Pointer(&p[0]), n) 155 } 156 return 157 } 158 159 // For testing: clients can set this flag to force 160 // creation of IPv6 sockets to return EAFNOSUPPORT. 161 var SocketDisableIPv6 bool 162 163 type Sockaddr interface { 164 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs 165 } 166 167 type SockaddrInet4 struct { 168 Port int 169 Addr [4]byte 170 raw RawSockaddrInet4 171 } 172 173 type SockaddrInet6 struct { 174 Port int 175 ZoneId uint32 176 Addr [16]byte 177 raw RawSockaddrInet6 178 } 179 180 type SockaddrUnix struct { 181 Name string 182 raw RawSockaddrUnix 183 } 184 185 func Bind(fd int, sa Sockaddr) (err error) { 186 ptr, n, err := sa.sockaddr() 187 if err != nil { 188 return err 189 } 190 return bind(fd, ptr, n) 191 } 192 193 func Connect(fd int, sa Sockaddr) (err error) { 194 ptr, n, err := sa.sockaddr() 195 if err != nil { 196 return err 197 } 198 return connect(fd, ptr, n) 199 } 200 201 func Getpeername(fd int) (sa Sockaddr, err error) { 202 var rsa RawSockaddrAny 203 var len _Socklen = SizeofSockaddrAny 204 if err = getpeername(fd, &rsa, &len); err != nil { 205 return 206 } 207 return anyToSockaddr(&rsa) 208 } 209 210 func GetsockoptInt(fd, level, opt int) (value int, err error) { 211 var n int32 212 vallen := _Socklen(4) 213 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) 214 return int(n), err 215 } 216 217 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { 218 var rsa RawSockaddrAny 219 var len _Socklen = SizeofSockaddrAny 220 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { 221 return 222 } 223 if rsa.Addr.Family != AF_UNSPEC { 224 from, err = anyToSockaddr(&rsa) 225 } 226 return 227 } 228 229 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { 230 ptr, n, err := to.sockaddr() 231 if err != nil { 232 return err 233 } 234 return sendto(fd, p, flags, ptr, n) 235 } 236 237 func SetsockoptByte(fd, level, opt int, value byte) (err error) { 238 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) 239 } 240 241 func SetsockoptInt(fd, level, opt int, value int) (err error) { 242 var n = int32(value) 243 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4) 244 } 245 246 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) { 247 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4) 248 } 249 250 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) { 251 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq) 252 } 253 254 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) { 255 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq) 256 } 257 258 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { 259 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter) 260 } 261 262 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { 263 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) 264 } 265 266 func SetsockoptString(fd, level, opt int, s string) (err error) { 267 return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s))) 268 } 269 270 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { 271 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) 272 } 273 274 func Socket(domain, typ, proto int) (fd int, err error) { 275 if domain == AF_INET6 && SocketDisableIPv6 { 276 return -1, EAFNOSUPPORT 277 } 278 fd, err = socket(domain, typ, proto) 279 return 280 } 281 282 func Socketpair(domain, typ, proto int) (fd [2]int, err error) { 283 var fdx [2]int32 284 err = socketpair(domain, typ, proto, &fdx) 285 if err == nil { 286 fd[0] = int(fdx[0]) 287 fd[1] = int(fdx[1]) 288 } 289 return 290 } 291 292 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 293 if raceenabled { 294 raceReleaseMerge(unsafe.Pointer(&ioSync)) 295 } 296 return sendfile(outfd, infd, offset, count) 297 } 298 299 var ioSync int64