all repos

rss-tools @ master

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/sys/unix/syscall_bsd.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
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)