Source file
src/syscall/syscall_solaris.go
1
2
3
4
5
6
7
8
9
10
11
12
13 package syscall
14
15 import "unsafe"
16
17 const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
18
19
20 func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
21 func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
22
23 type SockaddrDatalink struct {
24 Family uint16
25 Index uint16
26 Type uint8
27 Nlen uint8
28 Alen uint8
29 Slen uint8
30 Data [244]int8
31 raw RawSockaddrDatalink
32 }
33
34 func direntIno(buf []byte) (uint64, bool) {
35 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
36 }
37
38 func direntReclen(buf []byte) (uint64, bool) {
39 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
40 }
41
42 func direntNamlen(buf []byte) (uint64, bool) {
43 reclen, ok := direntReclen(buf)
44 if !ok {
45 return 0, false
46 }
47 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
48 }
49
50 func pipe() (r uintptr, w uintptr, err uintptr)
51
52 func Pipe(p []int) (err error) {
53 if len(p) != 2 {
54 return EINVAL
55 }
56 r0, w0, e1 := pipe()
57 if e1 != 0 {
58 err = Errno(e1)
59 }
60 if err == nil {
61 p[0], p[1] = int(r0), int(w0)
62 }
63 return
64 }
65
66 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
67 if sa.Port < 0 || sa.Port > 0xFFFF {
68 return nil, 0, EINVAL
69 }
70 sa.raw.Family = AF_INET
71 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
72 p[0] = byte(sa.Port >> 8)
73 p[1] = byte(sa.Port)
74 sa.raw.Addr = sa.Addr
75 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
76 }
77
78 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
79 if sa.Port < 0 || sa.Port > 0xFFFF {
80 return nil, 0, EINVAL
81 }
82 sa.raw.Family = AF_INET6
83 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
84 p[0] = byte(sa.Port >> 8)
85 p[1] = byte(sa.Port)
86 sa.raw.Scope_id = sa.ZoneId
87 sa.raw.Addr = sa.Addr
88 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
89 }
90
91 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
92 name := sa.Name
93 n := len(name)
94 if n >= len(sa.raw.Path) {
95 return nil, 0, EINVAL
96 }
97 sa.raw.Family = AF_UNIX
98 for i := 0; i < n; i++ {
99 sa.raw.Path[i] = int8(name[i])
100 }
101
102 sl := _Socklen(2)
103 if n > 0 {
104 sl += _Socklen(n) + 1
105 }
106 if sa.raw.Path[0] == '@' {
107 sa.raw.Path[0] = 0
108
109 sl--
110 }
111
112 return unsafe.Pointer(&sa.raw), sl, nil
113 }
114
115 func Getsockname(fd int) (sa Sockaddr, err error) {
116 var rsa RawSockaddrAny
117 var len _Socklen = SizeofSockaddrAny
118 if err = getsockname(fd, &rsa, &len); err != nil {
119 return
120 }
121 return anyToSockaddr(&rsa)
122 }
123
124 const ImplementsGetwd = true
125
126
127
128 func Getwd() (wd string, err error) {
129 var buf [PathMax]byte
130
131 _, err = Getcwd(buf[0:])
132 if err != nil {
133 return "", err
134 }
135 n := clen(buf[:])
136 if n < 1 {
137 return "", EINVAL
138 }
139 return string(buf[:n]), nil
140 }
141
142
145
146
147
148
149 func Getgroups() (gids []int, err error) {
150 n, err := getgroups(0, nil)
151 if err != nil {
152 return nil, err
153 }
154 if n == 0 {
155 return nil, nil
156 }
157
158
159 if n < 0 || n > 1000 {
160 return nil, EINVAL
161 }
162
163 a := make([]_Gid_t, n)
164 n, err = getgroups(n, &a[0])
165 if err != nil {
166 return nil, err
167 }
168 gids = make([]int, n)
169 for i, v := range a[0:n] {
170 gids[i] = int(v)
171 }
172 return
173 }
174
175 func Setgroups(gids []int) (err error) {
176 if len(gids) == 0 {
177 return setgroups(0, nil)
178 }
179
180 a := make([]_Gid_t, len(gids))
181 for i, v := range gids {
182 a[i] = _Gid_t(v)
183 }
184 return setgroups(len(a), &a[0])
185 }
186
187 func ReadDirent(fd int, buf []byte) (n int, err error) {
188
189
190 return Getdents(fd, buf, new(uintptr))
191 }
192
193
194
195
196
197
198
199 type WaitStatus uint32
200
201 const (
202 mask = 0x7F
203 core = 0x80
204 shift = 8
205
206 exited = 0
207 stopped = 0x7F
208 )
209
210 func (w WaitStatus) Exited() bool { return w&mask == exited }
211
212 func (w WaitStatus) ExitStatus() int {
213 if w&mask != exited {
214 return -1
215 }
216 return int(w >> shift)
217 }
218
219 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
220
221 func (w WaitStatus) Signal() Signal {
222 sig := Signal(w & mask)
223 if sig == stopped || sig == 0 {
224 return -1
225 }
226 return sig
227 }
228
229 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
230
231 func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
232
233 func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
234
235 func (w WaitStatus) StopSignal() Signal {
236 if !w.Stopped() {
237 return -1
238 }
239 return Signal(w>>shift) & 0xFF
240 }
241
242 func (w WaitStatus) TrapCause() int { return -1 }
243
244 func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid uintptr, err uintptr)
245
246 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
247 r0, e1 := wait4(uintptr(pid), wstatus, uintptr(options), rusage)
248 if e1 != 0 {
249 err = Errno(e1)
250 }
251 return int(r0), err
252 }
253
254 func gethostname() (name string, err uintptr)
255
256 func Gethostname() (name string, err error) {
257 name, e1 := gethostname()
258 if e1 != 0 {
259 err = Errno(e1)
260 }
261 return name, err
262 }
263
264 func UtimesNano(path string, ts []Timespec) error {
265 if len(ts) != 2 {
266 return EINVAL
267 }
268 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
269 }
270
271
272
273
274 func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
275 _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_fcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0)
276 if e1 != 0 {
277 return e1
278 }
279 return nil
280 }
281
282 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
283 switch rsa.Addr.Family {
284 case AF_UNIX:
285 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
286 sa := new(SockaddrUnix)
287
288
289
290
291
292 n := 0
293 for n < len(pp.Path) && pp.Path[n] != 0 {
294 n++
295 }
296 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
297 sa.Name = string(bytes)
298 return sa, nil
299
300 case AF_INET:
301 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
302 sa := new(SockaddrInet4)
303 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
304 sa.Port = int(p[0])<<8 + int(p[1])
305 sa.Addr = pp.Addr
306 return sa, nil
307
308 case AF_INET6:
309 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
310 sa := new(SockaddrInet6)
311 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
312 sa.Port = int(p[0])<<8 + int(p[1])
313 sa.ZoneId = pp.Scope_id
314 sa.Addr = pp.Addr
315 return sa, nil
316 }
317 return nil, EAFNOSUPPORT
318 }
319
320
321
322 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
323 var rsa RawSockaddrAny
324 var len _Socklen = SizeofSockaddrAny
325 nfd, err = accept(fd, &rsa, &len)
326 if err != nil {
327 return
328 }
329 sa, err = anyToSockaddr(&rsa)
330 if err != nil {
331 Close(nfd)
332 nfd = 0
333 }
334 return
335 }
336
337 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
338 var msg Msghdr
339 msg.Name = (*byte)(unsafe.Pointer(rsa))
340 msg.Namelen = uint32(SizeofSockaddrAny)
341 var iov Iovec
342 if len(p) > 0 {
343 iov.Base = (*int8)(unsafe.Pointer(&p[0]))
344 iov.SetLen(len(p))
345 }
346 var dummy int8
347 if len(oob) > 0 {
348
349 if len(p) == 0 {
350 iov.Base = &dummy
351 iov.SetLen(1)
352 }
353 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
354 msg.Accrightslen = int32(len(oob))
355 }
356 msg.Iov = &iov
357 msg.Iovlen = 1
358 if n, err = recvmsg(fd, &msg, flags); err != nil {
359 return
360 }
361 oobn = int(msg.Accrightslen)
362 return
363 }
364
365
366
367 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
368 var msg Msghdr
369 msg.Name = (*byte)(unsafe.Pointer(ptr))
370 msg.Namelen = uint32(salen)
371 var iov Iovec
372 if len(p) > 0 {
373 iov.Base = (*int8)(unsafe.Pointer(&p[0]))
374 iov.SetLen(len(p))
375 }
376 var dummy int8
377 if len(oob) > 0 {
378
379 if len(p) == 0 {
380 iov.Base = &dummy
381 iov.SetLen(1)
382 }
383 msg.Accrights = (*int8)(unsafe.Pointer(&oob[0]))
384 msg.Accrightslen = int32(len(oob))
385 }
386 msg.Iov = &iov
387 msg.Iovlen = 1
388 if n, err = sendmsg(fd, &msg, flags); err != nil {
389 return 0, err
390 }
391 if len(oob) > 0 && len(p) == 0 {
392 n = 0
393 }
394 return n, nil
395 }
396
397
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 func Getexecname() (path string, err error) {
479 ptr, err := getexecname()
480 if err != nil {
481 return "", err
482 }
483 bytes := (*[1 << 29]byte)(ptr)[:]
484 for i, b := range bytes {
485 if b == 0 {
486 return string(bytes[:i]), nil
487 }
488 }
489 panic("unreachable")
490 }
491
492 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
493 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_read)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
494 n = int(r0)
495 if e1 != 0 {
496 err = e1
497 }
498 return
499 }
500
501 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
502 r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_write)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0)
503 n = int(r0)
504 if e1 != 0 {
505 err = e1
506 }
507 return
508 }
509
510 func Utimes(path string, tv []Timeval) error {
511 if len(tv) != 2 {
512 return EINVAL
513 }
514 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
515 }
516
View as plain text