diff options
Diffstat (limited to 'vendor/golang.org/x/sys/unix/syscall_bsd.go')
-rw-r--r-- | vendor/golang.org/x/sys/unix/syscall_bsd.go | 609 |
1 files changed, 609 insertions, 0 deletions
diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go new file mode 100644 index 0000000..a00c3e5 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go | |||
@@ -0,0 +1,609 @@ | |||
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 | //go:build darwin || dragonfly || freebsd || netbsd || openbsd | ||
6 | |||
7 | // BSD system call wrappers shared by *BSD based systems | ||
8 | // including OS X (Darwin) and FreeBSD. Like the other | ||
9 | // syscall_*.go files it is compiled as Go code but also | ||
10 | // used as input to mksyscall which parses the //sys | ||
11 | // lines and generates system call stubs. | ||
12 | |||
13 | package unix | ||
14 | |||
15 | import ( | ||
16 | "runtime" | ||
17 | "syscall" | ||
18 | "unsafe" | ||
19 | ) | ||
20 | |||
21 | const ImplementsGetwd = true | ||
22 | |||
23 | func Getwd() (string, error) { | ||
24 | var buf [PathMax]byte | ||
25 | _, err := Getcwd(buf[0:]) | ||
26 | if err != nil { | ||
27 | return "", err | ||
28 | } | ||
29 | n := clen(buf[:]) | ||
30 | if n < 1 { | ||
31 | return "", EINVAL | ||
32 | } | ||
33 | return string(buf[:n]), nil | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * Wrapped | ||
38 | */ | ||
39 | |||
40 | //sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error) | ||
41 | //sysnb setgroups(ngid int, gid *_Gid_t) (err error) | ||
42 | |||
43 | func Getgroups() (gids []int, err error) { | ||
44 | n, err := getgroups(0, nil) | ||
45 | if err != nil { | ||
46 | return nil, err | ||
47 | } | ||
48 | if n == 0 { | ||
49 | return nil, nil | ||
50 | } | ||
51 | |||
52 | // Sanity check group count. Max is 16 on BSD. | ||
53 | if n < 0 || n > 1000 { | ||
54 | return nil, EINVAL | ||
55 | } | ||
56 | |||
57 | a := make([]_Gid_t, n) | ||
58 | n, err = getgroups(n, &a[0]) | ||
59 | if err != nil { | ||
60 | return nil, err | ||
61 | } | ||
62 | gids = make([]int, n) | ||
63 | for i, v := range a[0:n] { | ||
64 | gids[i] = int(v) | ||
65 | } | ||
66 | return | ||
67 | } | ||
68 | |||
69 | func Setgroups(gids []int) (err error) { | ||
70 | if len(gids) == 0 { | ||
71 | return setgroups(0, nil) | ||
72 | } | ||
73 | |||
74 | a := make([]_Gid_t, len(gids)) | ||
75 | for i, v := range gids { | ||
76 | a[i] = _Gid_t(v) | ||
77 | } | ||
78 | return setgroups(len(a), &a[0]) | ||
79 | } | ||
80 | |||
81 | // Wait status is 7 bits at bottom, either 0 (exited), | ||
82 | // 0x7F (stopped), or a signal number that caused an exit. | ||
83 | // The 0x80 bit is whether there was a core dump. | ||
84 | // An extra number (exit code, signal causing a stop) | ||
85 | // is in the high bits. | ||
86 | |||
87 | type WaitStatus uint32 | ||
88 | |||
89 | const ( | ||
90 | mask = 0x7F | ||
91 | core = 0x80 | ||
92 | shift = 8 | ||
93 | |||
94 | exited = 0 | ||
95 | killed = 9 | ||
96 | stopped = 0x7F | ||
97 | ) | ||
98 | |||
99 | func (w WaitStatus) Exited() bool { return w&mask == exited } | ||
100 | |||
101 | func (w WaitStatus) ExitStatus() int { | ||
102 | if w&mask != exited { | ||
103 | return -1 | ||
104 | } | ||
105 | return int(w >> shift) | ||
106 | } | ||
107 | |||
108 | func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 } | ||
109 | |||
110 | func (w WaitStatus) Signal() syscall.Signal { | ||
111 | sig := syscall.Signal(w & mask) | ||
112 | if sig == stopped || sig == 0 { | ||
113 | return -1 | ||
114 | } | ||
115 | return sig | ||
116 | } | ||
117 | |||
118 | func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } | ||
119 | |||
120 | func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP } | ||
121 | |||
122 | func (w WaitStatus) Killed() bool { return w&mask == killed && syscall.Signal(w>>shift) != SIGKILL } | ||
123 | |||
124 | func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP } | ||
125 | |||
126 | func (w WaitStatus) StopSignal() syscall.Signal { | ||
127 | if !w.Stopped() { | ||
128 | return -1 | ||
129 | } | ||
130 | return syscall.Signal(w>>shift) & 0xFF | ||
131 | } | ||
132 | |||
133 | func (w WaitStatus) TrapCause() int { return -1 } | ||
134 | |||
135 | //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) | ||
136 | |||
137 | func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { | ||
138 | var status _C_int | ||
139 | wpid, err = wait4(pid, &status, options, rusage) | ||
140 | if wstatus != nil { | ||
141 | *wstatus = WaitStatus(status) | ||
142 | } | ||
143 | return | ||
144 | } | ||
145 | |||
146 | //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) | ||
147 | //sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) | ||
148 | //sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) | ||
149 | //sysnb socket(domain int, typ int, proto int) (fd int, err error) | ||
150 | //sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) | ||
151 | //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) | ||
152 | //sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) | ||
153 | //sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) | ||
154 | //sys Shutdown(s int, how int) (err error) | ||
155 | |||
156 | func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { | ||
157 | if sa.Port < 0 || sa.Port > 0xFFFF { | ||
158 | return nil, 0, EINVAL | ||
159 | } | ||
160 | sa.raw.Len = SizeofSockaddrInet4 | ||
161 | sa.raw.Family = AF_INET | ||
162 | p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) | ||
163 | p[0] = byte(sa.Port >> 8) | ||
164 | p[1] = byte(sa.Port) | ||
165 | sa.raw.Addr = sa.Addr | ||
166 | return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil | ||
167 | } | ||
168 | |||
169 | func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { | ||
170 | if sa.Port < 0 || sa.Port > 0xFFFF { | ||
171 | return nil, 0, EINVAL | ||
172 | } | ||
173 | sa.raw.Len = SizeofSockaddrInet6 | ||
174 | sa.raw.Family = AF_INET6 | ||
175 | p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) | ||
176 | p[0] = byte(sa.Port >> 8) | ||
177 | p[1] = byte(sa.Port) | ||
178 | sa.raw.Scope_id = sa.ZoneId | ||
179 | sa.raw.Addr = sa.Addr | ||
180 | return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil | ||
181 | } | ||
182 | |||
183 | func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { | ||
184 | name := sa.Name | ||
185 | n := len(name) | ||
186 | if n >= len(sa.raw.Path) || n == 0 { | ||
187 | return nil, 0, EINVAL | ||
188 | } | ||
189 | sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL | ||
190 | sa.raw.Family = AF_UNIX | ||
191 | for i := 0; i < n; i++ { | ||
192 | sa.raw.Path[i] = int8(name[i]) | ||
193 | } | ||
194 | return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil | ||
195 | } | ||
196 | |||
197 | func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) { | ||
198 | if sa.Index == 0 { | ||
199 | return nil, 0, EINVAL | ||
200 | } | ||
201 | sa.raw.Len = sa.Len | ||
202 | sa.raw.Family = AF_LINK | ||
203 | sa.raw.Index = sa.Index | ||
204 | sa.raw.Type = sa.Type | ||
205 | sa.raw.Nlen = sa.Nlen | ||
206 | sa.raw.Alen = sa.Alen | ||
207 | sa.raw.Slen = sa.Slen | ||
208 | sa.raw.Data = sa.Data | ||
209 | return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil | ||
210 | } | ||
211 | |||
212 | func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { | ||
213 | switch rsa.Addr.Family { | ||
214 | case AF_LINK: | ||
215 | pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa)) | ||
216 | sa := new(SockaddrDatalink) | ||
217 | sa.Len = pp.Len | ||
218 | sa.Family = pp.Family | ||
219 | sa.Index = pp.Index | ||
220 | sa.Type = pp.Type | ||
221 | sa.Nlen = pp.Nlen | ||
222 | sa.Alen = pp.Alen | ||
223 | sa.Slen = pp.Slen | ||
224 | sa.Data = pp.Data | ||
225 | return sa, nil | ||
226 | |||
227 | case AF_UNIX: | ||
228 | pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) | ||
229 | if pp.Len < 2 || pp.Len > SizeofSockaddrUnix { | ||
230 | return nil, EINVAL | ||
231 | } | ||
232 | sa := new(SockaddrUnix) | ||
233 | |||
234 | // Some BSDs include the trailing NUL in the length, whereas | ||
235 | // others do not. Work around this by subtracting the leading | ||
236 | // family and len. The path is then scanned to see if a NUL | ||
237 | // terminator still exists within the length. | ||
238 | n := int(pp.Len) - 2 // subtract leading Family, Len | ||
239 | for i := 0; i < n; i++ { | ||
240 | if pp.Path[i] == 0 { | ||
241 | // found early NUL; assume Len included the NUL | ||
242 | // or was overestimating. | ||
243 | n = i | ||
244 | break | ||
245 | } | ||
246 | } | ||
247 | sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) | ||
248 | return sa, nil | ||
249 | |||
250 | case AF_INET: | ||
251 | pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) | ||
252 | sa := new(SockaddrInet4) | ||
253 | p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | ||
254 | sa.Port = int(p[0])<<8 + int(p[1]) | ||
255 | sa.Addr = pp.Addr | ||
256 | return sa, nil | ||
257 | |||
258 | case AF_INET6: | ||
259 | pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) | ||
260 | sa := new(SockaddrInet6) | ||
261 | p := (*[2]byte)(unsafe.Pointer(&pp.Port)) | ||
262 | sa.Port = int(p[0])<<8 + int(p[1]) | ||
263 | sa.ZoneId = pp.Scope_id | ||
264 | sa.Addr = pp.Addr | ||
265 | return sa, nil | ||
266 | } | ||
267 | return anyToSockaddrGOOS(fd, rsa) | ||
268 | } | ||
269 | |||
270 | func Accept(fd int) (nfd int, sa Sockaddr, err error) { | ||
271 | var rsa RawSockaddrAny | ||
272 | var len _Socklen = SizeofSockaddrAny | ||
273 | nfd, err = accept(fd, &rsa, &len) | ||
274 | if err != nil { | ||
275 | return | ||
276 | } | ||
277 | if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 { | ||
278 | // Accepted socket has no address. | ||
279 | // This is likely due to a bug in xnu kernels, | ||
280 | // where instead of ECONNABORTED error socket | ||
281 | // is accepted, but has no address. | ||
282 | Close(nfd) | ||
283 | return 0, nil, ECONNABORTED | ||
284 | } | ||
285 | sa, err = anyToSockaddr(fd, &rsa) | ||
286 | if err != nil { | ||
287 | Close(nfd) | ||
288 | nfd = 0 | ||
289 | } | ||
290 | return | ||
291 | } | ||
292 | |||
293 | func Getsockname(fd int) (sa Sockaddr, err error) { | ||
294 | var rsa RawSockaddrAny | ||
295 | var len _Socklen = SizeofSockaddrAny | ||
296 | if err = getsockname(fd, &rsa, &len); err != nil { | ||
297 | return | ||
298 | } | ||
299 | // TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be | ||
300 | // reported upstream. | ||
301 | if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 { | ||
302 | rsa.Addr.Family = AF_UNIX | ||
303 | rsa.Addr.Len = SizeofSockaddrUnix | ||
304 | } | ||
305 | return anyToSockaddr(fd, &rsa) | ||
306 | } | ||
307 | |||
308 | //sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) | ||
309 | |||
310 | // GetsockoptString returns the string value of the socket option opt for the | ||
311 | // socket associated with fd at the given socket level. | ||
312 | func GetsockoptString(fd, level, opt int) (string, error) { | ||
313 | buf := make([]byte, 256) | ||
314 | vallen := _Socklen(len(buf)) | ||
315 | err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) | ||
316 | if err != nil { | ||
317 | return "", err | ||
318 | } | ||
319 | return ByteSliceToString(buf[:vallen]), nil | ||
320 | } | ||
321 | |||
322 | //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) | ||
323 | //sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) | ||
324 | //sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) | ||
325 | |||
326 | func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { | ||
327 | var msg Msghdr | ||
328 | msg.Name = (*byte)(unsafe.Pointer(rsa)) | ||
329 | msg.Namelen = uint32(SizeofSockaddrAny) | ||
330 | var dummy byte | ||
331 | if len(oob) > 0 { | ||
332 | // receive at least one normal byte | ||
333 | if emptyIovecs(iov) { | ||
334 | var iova [1]Iovec | ||
335 | iova[0].Base = &dummy | ||
336 | iova[0].SetLen(1) | ||
337 | iov = iova[:] | ||
338 | } | ||
339 | msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | ||
340 | msg.SetControllen(len(oob)) | ||
341 | } | ||
342 | if len(iov) > 0 { | ||
343 | msg.Iov = &iov[0] | ||
344 | msg.SetIovlen(len(iov)) | ||
345 | } | ||
346 | if n, err = recvmsg(fd, &msg, flags); err != nil { | ||
347 | return | ||
348 | } | ||
349 | oobn = int(msg.Controllen) | ||
350 | recvflags = int(msg.Flags) | ||
351 | return | ||
352 | } | ||
353 | |||
354 | //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) | ||
355 | |||
356 | func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { | ||
357 | var msg Msghdr | ||
358 | msg.Name = (*byte)(unsafe.Pointer(ptr)) | ||
359 | msg.Namelen = uint32(salen) | ||
360 | var dummy byte | ||
361 | var empty bool | ||
362 | if len(oob) > 0 { | ||
363 | // send at least one normal byte | ||
364 | empty = emptyIovecs(iov) | ||
365 | if empty { | ||
366 | var iova [1]Iovec | ||
367 | iova[0].Base = &dummy | ||
368 | iova[0].SetLen(1) | ||
369 | iov = iova[:] | ||
370 | } | ||
371 | msg.Control = (*byte)(unsafe.Pointer(&oob[0])) | ||
372 | msg.SetControllen(len(oob)) | ||
373 | } | ||
374 | if len(iov) > 0 { | ||
375 | msg.Iov = &iov[0] | ||
376 | msg.SetIovlen(len(iov)) | ||
377 | } | ||
378 | if n, err = sendmsg(fd, &msg, flags); err != nil { | ||
379 | return 0, err | ||
380 | } | ||
381 | if len(oob) > 0 && empty { | ||
382 | n = 0 | ||
383 | } | ||
384 | return n, nil | ||
385 | } | ||
386 | |||
387 | //sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) | ||
388 | |||
389 | func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) { | ||
390 | var change, event unsafe.Pointer | ||
391 | if len(changes) > 0 { | ||
392 | change = unsafe.Pointer(&changes[0]) | ||
393 | } | ||
394 | if len(events) > 0 { | ||
395 | event = unsafe.Pointer(&events[0]) | ||
396 | } | ||
397 | return kevent(kq, change, len(changes), event, len(events), timeout) | ||
398 | } | ||
399 | |||
400 | // sysctlmib translates name to mib number and appends any additional args. | ||
401 | func sysctlmib(name string, args ...int) ([]_C_int, error) { | ||
402 | // Translate name to mib number. | ||
403 | mib, err := nametomib(name) | ||
404 | if err != nil { | ||
405 | return nil, err | ||
406 | } | ||
407 | |||
408 | for _, a := range args { | ||
409 | mib = append(mib, _C_int(a)) | ||
410 | } | ||
411 | |||
412 | return mib, nil | ||
413 | } | ||
414 | |||
415 | func Sysctl(name string) (string, error) { | ||
416 | return SysctlArgs(name) | ||
417 | } | ||
418 | |||
419 | func SysctlArgs(name string, args ...int) (string, error) { | ||
420 | buf, err := SysctlRaw(name, args...) | ||
421 | if err != nil { | ||
422 | return "", err | ||
423 | } | ||
424 | n := len(buf) | ||
425 | |||
426 | // Throw away terminating NUL. | ||
427 | if n > 0 && buf[n-1] == '\x00' { | ||
428 | n-- | ||
429 | } | ||
430 | return string(buf[0:n]), nil | ||
431 | } | ||
432 | |||
433 | func SysctlUint32(name string) (uint32, error) { | ||
434 | return SysctlUint32Args(name) | ||
435 | } | ||
436 | |||
437 | func SysctlUint32Args(name string, args ...int) (uint32, error) { | ||
438 | mib, err := sysctlmib(name, args...) | ||
439 | if err != nil { | ||
440 | return 0, err | ||
441 | } | ||
442 | |||
443 | n := uintptr(4) | ||
444 | buf := make([]byte, 4) | ||
445 | if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { | ||
446 | return 0, err | ||
447 | } | ||
448 | if n != 4 { | ||
449 | return 0, EIO | ||
450 | } | ||
451 | return *(*uint32)(unsafe.Pointer(&buf[0])), nil | ||
452 | } | ||
453 | |||
454 | func SysctlUint64(name string, args ...int) (uint64, error) { | ||
455 | mib, err := sysctlmib(name, args...) | ||
456 | if err != nil { | ||
457 | return 0, err | ||
458 | } | ||
459 | |||
460 | n := uintptr(8) | ||
461 | buf := make([]byte, 8) | ||
462 | if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { | ||
463 | return 0, err | ||
464 | } | ||
465 | if n != 8 { | ||
466 | return 0, EIO | ||
467 | } | ||
468 | return *(*uint64)(unsafe.Pointer(&buf[0])), nil | ||
469 | } | ||
470 | |||
471 | func SysctlRaw(name string, args ...int) ([]byte, error) { | ||
472 | mib, err := sysctlmib(name, args...) | ||
473 | if err != nil { | ||
474 | return nil, err | ||
475 | } | ||
476 | |||
477 | // Find size. | ||
478 | n := uintptr(0) | ||
479 | if err := sysctl(mib, nil, &n, nil, 0); err != nil { | ||
480 | return nil, err | ||
481 | } | ||
482 | if n == 0 { | ||
483 | return nil, nil | ||
484 | } | ||
485 | |||
486 | // Read into buffer of that size. | ||
487 | buf := make([]byte, n) | ||
488 | if err := sysctl(mib, &buf[0], &n, nil, 0); err != nil { | ||
489 | return nil, err | ||
490 | } | ||
491 | |||
492 | // The actual call may return less than the original reported required | ||
493 | // size so ensure we deal with that. | ||
494 | return buf[:n], nil | ||
495 | } | ||
496 | |||
497 | func SysctlClockinfo(name string) (*Clockinfo, error) { | ||
498 | mib, err := sysctlmib(name) | ||
499 | if err != nil { | ||
500 | return nil, err | ||
501 | } | ||
502 | |||
503 | n := uintptr(SizeofClockinfo) | ||
504 | var ci Clockinfo | ||
505 | if err := sysctl(mib, (*byte)(unsafe.Pointer(&ci)), &n, nil, 0); err != nil { | ||
506 | return nil, err | ||
507 | } | ||
508 | if n != SizeofClockinfo { | ||
509 | return nil, EIO | ||
510 | } | ||
511 | return &ci, nil | ||
512 | } | ||
513 | |||
514 | func SysctlTimeval(name string) (*Timeval, error) { | ||
515 | mib, err := sysctlmib(name) | ||
516 | if err != nil { | ||
517 | return nil, err | ||
518 | } | ||
519 | |||
520 | var tv Timeval | ||
521 | n := uintptr(unsafe.Sizeof(tv)) | ||
522 | if err := sysctl(mib, (*byte)(unsafe.Pointer(&tv)), &n, nil, 0); err != nil { | ||
523 | return nil, err | ||
524 | } | ||
525 | if n != unsafe.Sizeof(tv) { | ||
526 | return nil, EIO | ||
527 | } | ||
528 | return &tv, nil | ||
529 | } | ||
530 | |||
531 | //sys utimes(path string, timeval *[2]Timeval) (err error) | ||
532 | |||
533 | func Utimes(path string, tv []Timeval) error { | ||
534 | if tv == nil { | ||
535 | return utimes(path, nil) | ||
536 | } | ||
537 | if len(tv) != 2 { | ||
538 | return EINVAL | ||
539 | } | ||
540 | return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) | ||
541 | } | ||
542 | |||
543 | func UtimesNano(path string, ts []Timespec) error { | ||
544 | if ts == nil { | ||
545 | err := utimensat(AT_FDCWD, path, nil, 0) | ||
546 | if err != ENOSYS { | ||
547 | return err | ||
548 | } | ||
549 | return utimes(path, nil) | ||
550 | } | ||
551 | if len(ts) != 2 { | ||
552 | return EINVAL | ||
553 | } | ||
554 | err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) | ||
555 | if err != ENOSYS { | ||
556 | return err | ||
557 | } | ||
558 | // Not as efficient as it could be because Timespec and | ||
559 | // Timeval have different types in the different OSes | ||
560 | tv := [2]Timeval{ | ||
561 | NsecToTimeval(TimespecToNsec(ts[0])), | ||
562 | NsecToTimeval(TimespecToNsec(ts[1])), | ||
563 | } | ||
564 | return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) | ||
565 | } | ||
566 | |||
567 | func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { | ||
568 | if ts == nil { | ||
569 | return utimensat(dirfd, path, nil, flags) | ||
570 | } | ||
571 | if len(ts) != 2 { | ||
572 | return EINVAL | ||
573 | } | ||
574 | return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) | ||
575 | } | ||
576 | |||
577 | //sys futimes(fd int, timeval *[2]Timeval) (err error) | ||
578 | |||
579 | func Futimes(fd int, tv []Timeval) error { | ||
580 | if tv == nil { | ||
581 | return futimes(fd, nil) | ||
582 | } | ||
583 | if len(tv) != 2 { | ||
584 | return EINVAL | ||
585 | } | ||
586 | return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) | ||
587 | } | ||
588 | |||
589 | //sys poll(fds *PollFd, nfds int, timeout int) (n int, err error) | ||
590 | |||
591 | func Poll(fds []PollFd, timeout int) (n int, err error) { | ||
592 | if len(fds) == 0 { | ||
593 | return poll(nil, 0, timeout) | ||
594 | } | ||
595 | return poll(&fds[0], len(fds), timeout) | ||
596 | } | ||
597 | |||
598 | // TODO: wrap | ||
599 | // Acct(name nil-string) (err error) | ||
600 | // Gethostuuid(uuid *byte, timeout *Timespec) (err error) | ||
601 | // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) | ||
602 | |||
603 | //sys Madvise(b []byte, behav int) (err error) | ||
604 | //sys Mlock(b []byte) (err error) | ||
605 | //sys Mlockall(flags int) (err error) | ||
606 | //sys Mprotect(b []byte, prot int) (err error) | ||
607 | //sys Msync(b []byte, flags int) (err error) | ||
608 | //sys Munlock(b []byte) (err error) | ||
609 | //sys Munlockall() (err error) | ||