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