6 |
6 |
7 package unix |
7 package unix |
8 |
8 |
9 import ( |
9 import ( |
10 "bytes" |
10 "bytes" |
11 "runtime" |
|
12 "sort" |
11 "sort" |
13 "sync" |
12 "sync" |
14 "syscall" |
13 "syscall" |
15 "unsafe" |
14 "unsafe" |
16 ) |
15 ) |
17 |
16 |
18 var ( |
17 var ( |
19 Stdin = 0 |
18 Stdin = 0 |
20 Stdout = 1 |
19 Stdout = 1 |
21 Stderr = 2 |
20 Stderr = 2 |
22 ) |
|
23 |
|
24 const ( |
|
25 darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8 |
|
26 dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8 |
|
27 netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4 |
|
28 solaris64Bit = runtime.GOOS == "solaris" && sizeofPtr == 8 |
|
29 ) |
21 ) |
30 |
22 |
31 // Do the interface allocations only once for common |
23 // Do the interface allocations only once for common |
32 // Errno values. |
24 // Errno values. |
33 var ( |
25 var ( |
34 errEAGAIN error = syscall.EAGAIN |
26 errEAGAIN error = syscall.EAGAIN |
35 errEINVAL error = syscall.EINVAL |
27 errEINVAL error = syscall.EINVAL |
36 errENOENT error = syscall.ENOENT |
28 errENOENT error = syscall.ENOENT |
|
29 ) |
|
30 |
|
31 var ( |
|
32 signalNameMapOnce sync.Once |
|
33 signalNameMap map[string]syscall.Signal |
37 ) |
34 ) |
38 |
35 |
39 // errnoErr returns common boxed Errno values, to prevent |
36 // errnoErr returns common boxed Errno values, to prevent |
40 // allocations at runtime. |
37 // allocations at runtime. |
41 func errnoErr(e syscall.Errno) error { |
38 func errnoErr(e syscall.Errno) error { |
72 return signalList[i].name |
69 return signalList[i].name |
73 } |
70 } |
74 return "" |
71 return "" |
75 } |
72 } |
76 |
73 |
|
74 // SignalNum returns the syscall.Signal for signal named s, |
|
75 // or 0 if a signal with such name is not found. |
|
76 // The signal name should start with "SIG". |
|
77 func SignalNum(s string) syscall.Signal { |
|
78 signalNameMapOnce.Do(func() { |
|
79 signalNameMap = make(map[string]syscall.Signal) |
|
80 for _, signal := range signalList { |
|
81 signalNameMap[signal.name] = signal.num |
|
82 } |
|
83 }) |
|
84 return signalNameMap[s] |
|
85 } |
|
86 |
77 // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. |
87 // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. |
78 func clen(n []byte) int { |
88 func clen(n []byte) int { |
79 i := bytes.IndexByte(n, 0) |
89 i := bytes.IndexByte(n, 0) |
80 if i == -1 { |
90 if i == -1 { |
81 i = len(n) |
91 i = len(n) |
282 vallen := _Socklen(unsafe.Sizeof(tv)) |
292 vallen := _Socklen(unsafe.Sizeof(tv)) |
283 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen) |
293 err := getsockopt(fd, level, opt, unsafe.Pointer(&tv), &vallen) |
284 return &tv, err |
294 return &tv, err |
285 } |
295 } |
286 |
296 |
|
297 func GetsockoptUint64(fd, level, opt int) (value uint64, err error) { |
|
298 var n uint64 |
|
299 vallen := _Socklen(8) |
|
300 err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen) |
|
301 return n, err |
|
302 } |
|
303 |
287 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { |
304 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) { |
288 var rsa RawSockaddrAny |
305 var rsa RawSockaddrAny |
289 var len _Socklen = SizeofSockaddrAny |
306 var len _Socklen = SizeofSockaddrAny |
290 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { |
307 if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil { |
291 return |
308 return |
332 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { |
349 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) { |
333 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) |
350 return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger) |
334 } |
351 } |
335 |
352 |
336 func SetsockoptString(fd, level, opt int, s string) (err error) { |
353 func SetsockoptString(fd, level, opt int, s string) (err error) { |
337 return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s))) |
354 var p unsafe.Pointer |
|
355 if len(s) > 0 { |
|
356 p = unsafe.Pointer(&[]byte(s)[0]) |
|
357 } |
|
358 return setsockopt(fd, level, opt, p, uintptr(len(s))) |
338 } |
359 } |
339 |
360 |
340 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { |
361 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) { |
341 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) |
362 return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv)) |
|
363 } |
|
364 |
|
365 func SetsockoptUint64(fd, level, opt int, value uint64) (err error) { |
|
366 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 8) |
342 } |
367 } |
343 |
368 |
344 func Socket(domain, typ, proto int) (fd int, err error) { |
369 func Socket(domain, typ, proto int) (fd int, err error) { |
345 if domain == AF_INET6 && SocketDisableIPv6 { |
370 if domain == AF_INET6 && SocketDisableIPv6 { |
346 return -1, EAFNOSUPPORT |
371 return -1, EAFNOSUPPORT |
355 if err == nil { |
380 if err == nil { |
356 fd[0] = int(fdx[0]) |
381 fd[0] = int(fdx[0]) |
357 fd[1] = int(fdx[1]) |
382 fd[1] = int(fdx[1]) |
358 } |
383 } |
359 return |
384 return |
360 } |
|
361 |
|
362 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { |
|
363 if raceenabled { |
|
364 raceReleaseMerge(unsafe.Pointer(&ioSync)) |
|
365 } |
|
366 return sendfile(outfd, infd, offset, count) |
|
367 } |
385 } |
368 |
386 |
369 var ioSync int64 |
387 var ioSync int64 |
370 |
388 |
371 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) } |
389 func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) } |
390 // envv are the environment variables that should be passed to the new |
408 // envv are the environment variables that should be passed to the new |
391 // process (["USER=go", "PWD=/tmp"]). |
409 // process (["USER=go", "PWD=/tmp"]). |
392 func Exec(argv0 string, argv []string, envv []string) error { |
410 func Exec(argv0 string, argv []string, envv []string) error { |
393 return syscall.Exec(argv0, argv, envv) |
411 return syscall.Exec(argv0, argv, envv) |
394 } |
412 } |
|
413 |
|
414 // Lutimes sets the access and modification times tv on path. If path refers to |
|
415 // a symlink, it is not dereferenced and the timestamps are set on the symlink. |
|
416 // If tv is nil, the access and modification times are set to the current time. |
|
417 // Otherwise tv must contain exactly 2 elements, with access time as the first |
|
418 // element and modification time as the second element. |
|
419 func Lutimes(path string, tv []Timeval) error { |
|
420 if tv == nil { |
|
421 return UtimesNanoAt(AT_FDCWD, path, nil, AT_SYMLINK_NOFOLLOW) |
|
422 } |
|
423 if len(tv) != 2 { |
|
424 return EINVAL |
|
425 } |
|
426 ts := []Timespec{ |
|
427 NsecToTimespec(TimevalToNsec(tv[0])), |
|
428 NsecToTimespec(TimevalToNsec(tv[1])), |
|
429 } |
|
430 return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW) |
|
431 } |