Source file
src/syscall/syscall_unix.go
Documentation: syscall
1
2
3
4
5
6
7 package syscall
8
9 import (
10 "internal/race"
11 "runtime"
12 "sync"
13 "unsafe"
14 )
15
16 var (
17 Stdin = 0
18 Stdout = 1
19 Stderr = 2
20 )
21
22 const (
23 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8
24 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
25 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
26 solaris64Bit = runtime.GOOS == "solaris" && sizeofPtr == 8
27 )
28
29 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
30 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
31 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
32 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
33
34
35
36 type mmapper struct {
37 sync.Mutex
38 active map[*byte][]byte
39 mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
40 munmap func(addr uintptr, length uintptr) error
41 }
42
43 func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
44 if length <= 0 {
45 return nil, EINVAL
46 }
47
48
49 addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
50 if errno != nil {
51 return nil, errno
52 }
53
54
55 var sl = struct {
56 addr uintptr
57 len int
58 cap int
59 }{addr, length, length}
60
61
62 b := *(*[]byte)(unsafe.Pointer(&sl))
63
64
65 p := &b[cap(b)-1]
66 m.Lock()
67 defer m.Unlock()
68 m.active[p] = b
69 return b, nil
70 }
71
72 func (m *mmapper) Munmap(data []byte) (err error) {
73 if len(data) == 0 || len(data) != cap(data) {
74 return EINVAL
75 }
76
77
78 p := &data[cap(data)-1]
79 m.Lock()
80 defer m.Unlock()
81 b := m.active[p]
82 if b == nil || &b[0] != &data[0] {
83 return EINVAL
84 }
85
86
87 if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
88 return errno
89 }
90 delete(m.active, p)
91 return nil
92 }
93
94
95
96
97
98
99
100
101 type Errno uintptr
102
103 func (e Errno) Error() string {
104 if 0 <= int(e) && int(e) < len(errors) {
105 s := errors[e]
106 if s != "" {
107 return s
108 }
109 }
110 return "errno " + itoa(int(e))
111 }
112
113 func (e Errno) Temporary() bool {
114 return e == EINTR || e == EMFILE || e == ECONNRESET || e == ECONNABORTED || e.Timeout()
115 }
116
117 func (e Errno) Timeout() bool {
118 return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
119 }
120
121
122
123 var (
124 errEAGAIN error = EAGAIN
125 errEINVAL error = EINVAL
126 errENOENT error = ENOENT
127 )
128
129
130
131 func errnoErr(e Errno) error {
132 switch e {
133 case 0:
134 return nil
135 case EAGAIN:
136 return errEAGAIN
137 case EINVAL:
138 return errEINVAL
139 case ENOENT:
140 return errENOENT
141 }
142 return e
143 }
144
145
146
147 type Signal int
148
149 func (s Signal) Signal() {}
150
151 func (s Signal) String() string {
152 if 0 <= s && int(s) < len(signals) {
153 str := signals[s]
154 if str != "" {
155 return str
156 }
157 }
158 return "signal " + itoa(int(s))
159 }
160
161 func Read(fd int, p []byte) (n int, err error) {
162 n, err = read(fd, p)
163 if race.Enabled {
164 if n > 0 {
165 race.WriteRange(unsafe.Pointer(&p[0]), n)
166 }
167 if err == nil {
168 race.Acquire(unsafe.Pointer(&ioSync))
169 }
170 }
171 if msanenabled && n > 0 {
172 msanWrite(unsafe.Pointer(&p[0]), n)
173 }
174 return
175 }
176
177 func Write(fd int, p []byte) (n int, err error) {
178 if race.Enabled {
179 race.ReleaseMerge(unsafe.Pointer(&ioSync))
180 }
181 n, err = write(fd, p)
182 if race.Enabled && n > 0 {
183 race.ReadRange(unsafe.Pointer(&p[0]), n)
184 }
185 if msanenabled && n > 0 {
186 msanRead(unsafe.Pointer(&p[0]), n)
187 }
188 return
189 }
190
191
192
193 var SocketDisableIPv6 bool
194
195 type Sockaddr interface {
196 sockaddr() (ptr unsafe.Pointer, len _Socklen, err error)
197 }
198
199 type SockaddrInet4 struct {
200 Port int
201 Addr [4]byte
202 raw RawSockaddrInet4
203 }
204
205 type SockaddrInet6 struct {
206 Port int
207 ZoneId uint32
208 Addr [16]byte
209 raw RawSockaddrInet6
210 }
211
212 type SockaddrUnix struct {
213 Name string
214 raw RawSockaddrUnix
215 }
216
217 func Bind(fd int, sa Sockaddr) (err error) {
218 ptr, n, err := sa.sockaddr()
219 if err != nil {
220 return err
221 }
222 return bind(fd, ptr, n)
223 }
224
225 func Connect(fd int, sa Sockaddr) (err error) {
226 ptr, n, err := sa.sockaddr()
227 if err != nil {
228 return err
229 }
230 return connect(fd, ptr, n)
231 }
232
233 func Getpeername(fd int) (sa Sockaddr, err error) {
234 var rsa RawSockaddrAny
235 var len _Socklen = SizeofSockaddrAny
236 if err = getpeername(fd, &rsa, &len); err != nil {
237 return
238 }
239 return anyToSockaddr(&rsa)
240 }
241
242 func GetsockoptInt(fd, level, opt int) (value int, err error) {
243 var n int32
244 vallen := _Socklen(4)
245 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
246 return int(n), err
247 }
248
249 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
250 var rsa RawSockaddrAny
251 var len _Socklen = SizeofSockaddrAny
252 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
253 return
254 }
255 if rsa.Addr.Family != AF_UNSPEC {
256 from, err = anyToSockaddr(&rsa)
257 }
258 return
259 }
260
261 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
262 ptr, n, err := to.sockaddr()
263 if err != nil {
264 return err
265 }
266 return sendto(fd, p, flags, ptr, n)
267 }
268
269 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
270 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
271 }
272
273 func SetsockoptInt(fd, level, opt int, value int) (err error) {
274 var n = int32(value)
275 return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
276 }
277
278 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
279 return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
280 }
281
282 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
283 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
284 }
285
286 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
287 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
288 }
289
290 func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
291 return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
292 }
293
294 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
295 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
296 }
297
298 func SetsockoptString(fd, level, opt int, s string) (err error) {
299 return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s)))
300 }
301
302 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
303 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
304 }
305
306 func Socket(domain, typ, proto int) (fd int, err error) {
307 if domain == AF_INET6 && SocketDisableIPv6 {
308 return -1, EAFNOSUPPORT
309 }
310 fd, err = socket(domain, typ, proto)
311 return
312 }
313
314 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
315 var fdx [2]int32
316 err = socketpair(domain, typ, proto, &fdx)
317 if err == nil {
318 fd[0] = int(fdx[0])
319 fd[1] = int(fdx[1])
320 }
321 return
322 }
323
324 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
325 if race.Enabled {
326 race.ReleaseMerge(unsafe.Pointer(&ioSync))
327 }
328 return sendfile(outfd, infd, offset, count)
329 }
330
331 var ioSync int64
332
View as plain text