syscall_unix.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. //go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
  5. package syscall
  6. import (
  7. "internal/race"
  8. "internal/unsafeheader"
  9. "runtime"
  10. "sync"
  11. "unsafe"
  12. )
  13. var (
  14. Stdin = 0
  15. Stdout = 1
  16. Stderr = 2
  17. )
  18. const (
  19. darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
  20. netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
  21. )
  22. // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
  23. func clen(n []byte) int {
  24. for i := 0; i < len(n); i++ {
  25. if n[i] == 0 {
  26. return i
  27. }
  28. }
  29. return len(n)
  30. }
  31. // Mmap manager, for use by operating system-specific implementations.
  32. // Gccgo only has one implementation but we do this to correspond to gc.
  33. type mmapper struct {
  34. sync.Mutex
  35. active map[*byte][]byte // active mappings; key is last byte in mapping
  36. mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
  37. munmap func(addr uintptr, length uintptr) error
  38. }
  39. func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  40. if length <= 0 {
  41. return nil, EINVAL
  42. }
  43. // Map the requested memory.
  44. addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
  45. if errno != nil {
  46. return nil, errno
  47. }
  48. // Use unsafe to turn addr into a []byte.
  49. var b []byte
  50. hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
  51. hdr.Data = unsafe.Pointer(addr)
  52. hdr.Cap = length
  53. hdr.Len = length
  54. // Register mapping in m and return it.
  55. p := &b[cap(b)-1]
  56. m.Lock()
  57. defer m.Unlock()
  58. m.active[p] = b
  59. return b, nil
  60. }
  61. func (m *mmapper) Munmap(data []byte) (err error) {
  62. if len(data) == 0 || len(data) != cap(data) {
  63. return EINVAL
  64. }
  65. // Find the base of the mapping.
  66. p := &data[cap(data)-1]
  67. m.Lock()
  68. defer m.Unlock()
  69. b := m.active[p]
  70. if b == nil || &b[0] != &data[0] {
  71. return EINVAL
  72. }
  73. // Unmap the memory and update m.
  74. if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
  75. return errno
  76. }
  77. delete(m.active, p)
  78. return nil
  79. }
  80. var mapper = &mmapper{
  81. active: make(map[*byte][]byte),
  82. mmap: mmap,
  83. munmap: munmap,
  84. }
  85. func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
  86. return mapper.Mmap(fd, offset, length, prot, flags)
  87. }
  88. func Munmap(b []byte) (err error) {
  89. return mapper.Munmap(b)
  90. }
  91. // Do the interface allocations only once for common
  92. // Errno values.
  93. var (
  94. errEAGAIN error = EAGAIN
  95. errEINVAL error = EINVAL
  96. errENOENT error = ENOENT
  97. )
  98. // errnoErr returns common boxed Errno values, to prevent
  99. // allocations at runtime.
  100. func errnoErr(e Errno) error {
  101. switch e {
  102. case 0:
  103. return nil
  104. case EAGAIN:
  105. return errEAGAIN
  106. case EINVAL:
  107. return errEINVAL
  108. case ENOENT:
  109. return errENOENT
  110. }
  111. return e
  112. }
  113. // A Signal is a number describing a process signal.
  114. // It implements the os.Signal interface.
  115. type Signal int
  116. func (s Signal) Signal() {}
  117. func Signame(s Signal) string
  118. func (s Signal) String() string {
  119. return Signame(s)
  120. }
  121. func Read(fd int, p []byte) (n int, err error) {
  122. n, err = read(fd, p)
  123. if race.Enabled {
  124. if n > 0 {
  125. race.WriteRange(unsafe.Pointer(&p[0]), n)
  126. }
  127. if err == nil {
  128. race.Acquire(unsafe.Pointer(&ioSync))
  129. }
  130. }
  131. if msanenabled && n > 0 {
  132. msanWrite(unsafe.Pointer(&p[0]), n)
  133. }
  134. if asanenabled && n > 0 {
  135. asanWrite(unsafe.Pointer(&p[0]), n)
  136. }
  137. return
  138. }
  139. func Write(fd int, p []byte) (n int, err error) {
  140. if race.Enabled {
  141. race.ReleaseMerge(unsafe.Pointer(&ioSync))
  142. }
  143. if faketime && (fd == 1 || fd == 2) {
  144. n = faketimeWrite(fd, p)
  145. if n < 0 {
  146. n, err = 0, errnoErr(Errno(-n))
  147. }
  148. } else {
  149. n, err = write(fd, p)
  150. }
  151. if race.Enabled && n > 0 {
  152. race.ReadRange(unsafe.Pointer(&p[0]), n)
  153. }
  154. if msanenabled && n > 0 {
  155. msanRead(unsafe.Pointer(&p[0]), n)
  156. }
  157. if asanenabled && n > 0 {
  158. asanRead(unsafe.Pointer(&p[0]), n)
  159. }
  160. return
  161. }
  162. var ioSync int64