1
2
3
4
5
6
7
8
9
10
11
12
13
14 package unix
15
16 import "unsafe"
17
18
21
22 func Access(path string, mode uint32) (err error) {
23 return Faccessat(AT_FDCWD, path, mode, 0)
24 }
25
26 func Chmod(path string, mode uint32) (err error) {
27 return Fchmodat(AT_FDCWD, path, mode, 0)
28 }
29
30 func Chown(path string, uid int, gid int) (err error) {
31 return Fchownat(AT_FDCWD, path, uid, gid, 0)
32 }
33
34 func Creat(path string, mode uint32) (fd int, err error) {
35 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
36 }
37
38
39
40 func Utimes(path string, tv []Timeval) error {
41 if len(tv) != 2 {
42 return EINVAL
43 }
44 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
45 }
46
47
48
49 func UtimesNano(path string, ts []Timespec) error {
50 if len(ts) != 2 {
51 return EINVAL
52 }
53 return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
54 }
55
56 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
57 if ts == nil {
58 return utimensat(dirfd, path, nil, flags)
59 }
60 if len(ts) != 2 {
61 return EINVAL
62 }
63 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
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 if n == len(sa.raw.Path) && name[0] != '@' {
98 return nil, 0, EINVAL
99 }
100 sa.raw.Family = AF_UNIX
101 for i := 0; i < n; i++ {
102 sa.raw.Path[i] = uint8(name[i])
103 }
104
105 sl := _Socklen(2)
106 if n > 0 {
107 sl += _Socklen(n) + 1
108 }
109 if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) {
110
111 sa.raw.Path[0] = 0
112
113 sl--
114 }
115
116 return unsafe.Pointer(&sa.raw), sl, nil
117 }
118
119 func Getsockname(fd int) (sa Sockaddr, err error) {
120 var rsa RawSockaddrAny
121 var len _Socklen = SizeofSockaddrAny
122 if err = getsockname(fd, &rsa, &len); err != nil {
123 return
124 }
125 return anyToSockaddr(fd, &rsa)
126 }
127
128
129
130 const ImplementsGetwd = true
131
132 func Getwd() (ret string, err error) {
133 for len := uint64(4096); ; len *= 2 {
134 b := make([]byte, len)
135 err := getcwd(b)
136 if err == nil {
137 i := 0
138 for b[i] != 0 {
139 i++
140 }
141 return string(b[0:i]), nil
142 }
143 if err != ERANGE {
144 return "", err
145 }
146 }
147 }
148
149 func Getcwd(buf []byte) (n int, err error) {
150 err = getcwd(buf)
151 if err == nil {
152 i := 0
153 for buf[i] != 0 {
154 i++
155 }
156 n = i + 1
157 }
158 return
159 }
160
161 func Getgroups() (gids []int, err error) {
162 n, err := getgroups(0, nil)
163 if err != nil {
164 return nil, err
165 }
166 if n == 0 {
167 return nil, nil
168 }
169
170
171 if n < 0 || n > 1000 {
172 return nil, EINVAL
173 }
174
175 a := make([]_Gid_t, n)
176 n, err = getgroups(n, &a[0])
177 if err != nil {
178 return nil, err
179 }
180 gids = make([]int, n)
181 for i, v := range a[0:n] {
182 gids[i] = int(v)
183 }
184 return
185 }
186
187 func Setgroups(gids []int) (err error) {
188 if len(gids) == 0 {
189 return setgroups(0, nil)
190 }
191
192 a := make([]_Gid_t, len(gids))
193 for i, v := range gids {
194 a[i] = _Gid_t(v)
195 }
196 return setgroups(len(a), &a[0])
197 }
198
199
202
203
204
205 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
206 var rsa RawSockaddrAny
207 var len _Socklen = SizeofSockaddrAny
208 nfd, err = accept(fd, &rsa, &len)
209 if nfd == -1 {
210 return
211 }
212 sa, err = anyToSockaddr(fd, &rsa)
213 if err != nil {
214 Close(nfd)
215 nfd = 0
216 }
217 return
218 }
219
220 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
221 var msg Msghdr
222 msg.Name = (*byte)(unsafe.Pointer(rsa))
223 msg.Namelen = uint32(SizeofSockaddrAny)
224 var dummy byte
225 if len(oob) > 0 {
226
227 if emptyIovecs(iov) {
228 var iova [1]Iovec
229 iova[0].Base = &dummy
230 iova[0].SetLen(1)
231 iov = iova[:]
232 }
233 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
234 msg.SetControllen(len(oob))
235 }
236 if len(iov) > 0 {
237 msg.Iov = &iov[0]
238 msg.SetIovlen(len(iov))
239 }
240 if n, err = recvmsg(fd, &msg, flags); n == -1 {
241 return
242 }
243 oobn = int(msg.Controllen)
244 recvflags = int(msg.Flags)
245 return
246 }
247
248 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
249 var msg Msghdr
250 msg.Name = (*byte)(unsafe.Pointer(ptr))
251 msg.Namelen = uint32(salen)
252 var dummy byte
253 var empty bool
254 if len(oob) > 0 {
255
256 empty = emptyIovecs(iov)
257 if empty {
258 var iova [1]Iovec
259 iova[0].Base = &dummy
260 iova[0].SetLen(1)
261 iov = iova[:]
262 }
263 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
264 msg.SetControllen(len(oob))
265 }
266 if len(iov) > 0 {
267 msg.Iov = &iov[0]
268 msg.SetIovlen(len(iov))
269 }
270 if n, err = sendmsg(fd, &msg, flags); err != nil {
271 return 0, err
272 }
273 if len(oob) > 0 && empty {
274 n = 0
275 }
276 return n, nil
277 }
278
279 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
280 switch rsa.Addr.Family {
281
282 case AF_UNIX:
283 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
284 sa := new(SockaddrUnix)
285
286
287
288 n := SizeofSockaddrUnix - 3
289 for i := 0; i < n; i++ {
290 if pp.Path[i] == 0 {
291 n = i
292 break
293 }
294 }
295 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
296 return sa, nil
297
298 case AF_INET:
299 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
300 sa := new(SockaddrInet4)
301 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
302 sa.Port = int(p[0])<<8 + int(p[1])
303 sa.Addr = pp.Addr
304 return sa, nil
305
306 case AF_INET6:
307 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
308 sa := new(SockaddrInet6)
309 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
310 sa.Port = int(p[0])<<8 + int(p[1])
311 sa.ZoneId = pp.Scope_id
312 sa.Addr = pp.Addr
313 return sa, nil
314 }
315 return nil, EAFNOSUPPORT
316 }
317
318 func Gettimeofday(tv *Timeval) (err error) {
319 err = gettimeofday(tv, nil)
320 return
321 }
322
323 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
324 if raceenabled {
325 raceReleaseMerge(unsafe.Pointer(&ioSync))
326 }
327 return sendfile(outfd, infd, offset, count)
328 }
329
330
331 func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
332 return -1, ENOSYS
333 }
334
335 func direntIno(buf []byte) (uint64, bool) {
336 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
337 }
338
339 func direntReclen(buf []byte) (uint64, bool) {
340 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
341 }
342
343 func direntNamlen(buf []byte) (uint64, bool) {
344 reclen, ok := direntReclen(buf)
345 if !ok {
346 return 0, false
347 }
348 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
349 }
350
351
352
353 func Getdents(fd int, buf []byte) (n int, err error) {
354 return getdirent(fd, buf)
355 }
356
357
358
359 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
360 var status _C_int
361 var r Pid_t
362 err = ERESTART
363
364
365 for err == ERESTART {
366 r, err = wait4(Pid_t(pid), &status, options, rusage)
367 }
368 wpid = int(r)
369 if wstatus != nil {
370 *wstatus = WaitStatus(status)
371 }
372 return
373 }
374
375
378
379 type WaitStatus uint32
380
381 func (w WaitStatus) Stopped() bool { return w&0x40 != 0 }
382 func (w WaitStatus) StopSignal() Signal {
383 if !w.Stopped() {
384 return -1
385 }
386 return Signal(w>>8) & 0xFF
387 }
388
389 func (w WaitStatus) Exited() bool { return w&0xFF == 0 }
390 func (w WaitStatus) ExitStatus() int {
391 if !w.Exited() {
392 return -1
393 }
394 return int((w >> 8) & 0xFF)
395 }
396
397 func (w WaitStatus) Signaled() bool { return w&0x40 == 0 && w&0xFF != 0 }
398 func (w WaitStatus) Signal() Signal {
399 if !w.Signaled() {
400 return -1
401 }
402 return Signal(w>>16) & 0xFF
403 }
404
405 func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }
406
407 func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 }
408
409 func (w WaitStatus) TrapCause() int { return -1 }
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428 func Fsync(fd int) error {
429 return fsyncRange(fd, O_SYNC, 0, 0)
430 }
431
432
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
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546 func Pipe(p []int) (err error) {
547 if len(p) != 2 {
548 return EINVAL
549 }
550 var pp [2]_C_int
551 err = pipe(&pp)
552 if err == nil {
553 p[0] = int(pp[0])
554 p[1] = int(pp[1])
555 }
556 return
557 }
558
559
560
561 func Poll(fds []PollFd, timeout int) (n int, err error) {
562 if len(fds) == 0 {
563 return poll(nil, 0, timeout)
564 }
565 return poll(&fds[0], len(fds), timeout)
566 }
567
568
569
570
571
572
573
574
575
576 func Unmount(target string, flags int) (err error) {
577 if flags != 0 {
578
579 return ENOSYS
580 }
581 return umount(target)
582 }
583
View as plain text