github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/syscall/syscall_darwin.go (about) 1 // Copyright 2009,2010 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 // Darwin system calls. 6 // This file is compiled as ordinary Go code, 7 // but it is also input to mksyscall, 8 // which parses the //sys lines and generates system call stubs. 9 // Note that sometimes we use a lowercase //sys name and wrap 10 // it in our own nicer implementation, either here or in 11 // syscall_bsd.go or syscall_unix.go. 12 13 package syscall 14 15 import ( 16 errorspkg "errors" 17 "unsafe" 18 ) 19 20 const ImplementsGetwd = true 21 22 func Getwd() (string, error) { 23 buf := make([]byte, 2048) 24 attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0) 25 if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 { 26 wd := string(attrs[0]) 27 // Sanity check that it's an absolute path and ends 28 // in a null byte, which we then strip. 29 if wd[0] == '/' && wd[len(wd)-1] == 0 { 30 return wd[:len(wd)-1], nil 31 } 32 } 33 // If pkg/os/getwd.go gets ENOTSUP, it will fall back to the 34 // slow algorithm. 35 return "", ENOTSUP 36 } 37 38 type SockaddrDatalink struct { 39 Len uint8 40 Family uint8 41 Index uint16 42 Type uint8 43 Nlen uint8 44 Alen uint8 45 Slen uint8 46 Data [12]int8 47 raw RawSockaddrDatalink 48 } 49 50 // Translate "kern.hostname" to []_C_int{0,1,2,3}. 51 func nametomib(name string) (mib []_C_int, err error) { 52 const siz = unsafe.Sizeof(mib[0]) 53 54 // NOTE(rsc): It seems strange to set the buffer to have 55 // size CTL_MAXNAME+2 but use only CTL_MAXNAME 56 // as the size. I don't know why the +2 is here, but the 57 // kernel uses +2 for its own implementation of this function. 58 // I am scared that if we don't include the +2 here, the kernel 59 // will silently write 2 words farther than we specify 60 // and we'll get memory corruption. 61 var buf [CTL_MAXNAME + 2]_C_int 62 n := uintptr(CTL_MAXNAME) * siz 63 64 p := (*byte)(unsafe.Pointer(&buf[0])) 65 bytes, err := ByteSliceFromString(name) 66 if err != nil { 67 return nil, err 68 } 69 70 // Magic sysctl: "setting" 0.3 to a string name 71 // lets you read back the array of integers form. 72 if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil { 73 return nil, err 74 } 75 return buf[0 : n/siz], nil 76 } 77 78 func direntIno(buf []byte) (uint64, bool) { 79 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 80 } 81 82 func direntReclen(buf []byte) (uint64, bool) { 83 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 84 } 85 86 func direntNamlen(buf []byte) (uint64, bool) { 87 return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) 88 } 89 90 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 91 func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } 92 func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } 93 94 const ( 95 attrBitMapCount = 5 96 attrCmnModtime = 0x00000400 97 attrCmnAcctime = 0x00001000 98 attrCmnFullpath = 0x08000000 99 ) 100 101 type attrList struct { 102 bitmapCount uint16 103 _ uint16 104 CommonAttr uint32 105 VolAttr uint32 106 DirAttr uint32 107 FileAttr uint32 108 Forkattr uint32 109 } 110 111 func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) { 112 if len(attrBuf) < 4 { 113 return nil, errorspkg.New("attrBuf too small") 114 } 115 attrList.bitmapCount = attrBitMapCount 116 117 var _p0 *byte 118 _p0, err = BytePtrFromString(path) 119 if err != nil { 120 return nil, err 121 } 122 123 _, _, e1 := syscall6( 124 funcPC(libc_getattrlist_trampoline), 125 uintptr(unsafe.Pointer(_p0)), 126 uintptr(unsafe.Pointer(&attrList)), 127 uintptr(unsafe.Pointer(&attrBuf[0])), 128 uintptr(len(attrBuf)), 129 uintptr(options), 130 0, 131 ) 132 if e1 != 0 { 133 return nil, e1 134 } 135 size := *(*uint32)(unsafe.Pointer(&attrBuf[0])) 136 137 // dat is the section of attrBuf that contains valid data, 138 // without the 4 byte length header. All attribute offsets 139 // are relative to dat. 140 dat := attrBuf 141 if int(size) < len(attrBuf) { 142 dat = dat[:size] 143 } 144 dat = dat[4:] // remove length prefix 145 146 for i := uint32(0); int(i) < len(dat); { 147 header := dat[i:] 148 if len(header) < 8 { 149 return attrs, errorspkg.New("truncated attribute header") 150 } 151 datOff := *(*int32)(unsafe.Pointer(&header[0])) 152 attrLen := *(*uint32)(unsafe.Pointer(&header[4])) 153 if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) { 154 return attrs, errorspkg.New("truncated results; attrBuf too small") 155 } 156 end := uint32(datOff) + attrLen 157 attrs = append(attrs, dat[datOff:end]) 158 i = end 159 if r := i % 4; r != 0 { 160 i += (4 - r) 161 } 162 } 163 return 164 } 165 166 func libc_getattrlist_trampoline() 167 168 //go:linkname libc_getattrlist libc_getattrlist 169 //go:cgo_import_dynamic libc_getattrlist getattrlist "/usr/lib/libSystem.B.dylib" 170 171 //sysnb pipe(p *[2]int32) (err error) 172 173 func Pipe(p []int) (err error) { 174 if len(p) != 2 { 175 return EINVAL 176 } 177 var q [2]int32 178 err = pipe(&q) 179 p[0] = int(q[0]) 180 p[1] = int(q[1]) 181 return 182 } 183 184 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { 185 var _p0 unsafe.Pointer 186 var bufsize uintptr 187 if len(buf) > 0 { 188 _p0 = unsafe.Pointer(&buf[0]) 189 bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) 190 } 191 r0, _, e1 := syscall(funcPC(libc_getfsstat64_trampoline), uintptr(_p0), bufsize, uintptr(flags)) 192 n = int(r0) 193 if e1 != 0 { 194 err = e1 195 } 196 return 197 } 198 199 func libc_getfsstat64_trampoline() 200 201 //go:linkname libc_getfsstat64 libc_getfsstat64 202 //go:cgo_import_dynamic libc_getfsstat64 getfsstat64 "/usr/lib/libSystem.B.dylib" 203 204 func setattrlistTimes(path string, times []Timespec) error { 205 _p0, err := BytePtrFromString(path) 206 if err != nil { 207 return err 208 } 209 210 var attrList attrList 211 attrList.bitmapCount = attrBitMapCount 212 attrList.CommonAttr = attrCmnModtime | attrCmnAcctime 213 214 // order is mtime, atime: the opposite of Chtimes 215 attributes := [2]Timespec{times[1], times[0]} 216 const options = 0 217 _, _, e1 := syscall6( 218 funcPC(libc_setattrlist_trampoline), 219 uintptr(unsafe.Pointer(_p0)), 220 uintptr(unsafe.Pointer(&attrList)), 221 uintptr(unsafe.Pointer(&attributes)), 222 uintptr(unsafe.Sizeof(attributes)), 223 uintptr(options), 224 0, 225 ) 226 if e1 != 0 { 227 return e1 228 } 229 return nil 230 } 231 232 func libc_setattrlist_trampoline() 233 234 //go:linkname libc_setattrlist libc_setattrlist 235 //go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" 236 237 func utimensat(dirfd int, path string, times *[2]Timespec, flag int) error { 238 // Darwin doesn't support SYS_UTIMENSAT 239 return ENOSYS 240 } 241 242 /* 243 * Wrapped 244 */ 245 246 //sys kill(pid int, signum int, posix int) (err error) 247 248 func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1) } 249 250 /* 251 * Exposed directly 252 */ 253 //sys Access(path string, mode uint32) (err error) 254 //sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) 255 //sys Chdir(path string) (err error) 256 //sys Chflags(path string, flags int) (err error) 257 //sys Chmod(path string, mode uint32) (err error) 258 //sys Chown(path string, uid int, gid int) (err error) 259 //sys Chroot(path string) (err error) 260 //sys Close(fd int) (err error) 261 //sys Dup(fd int) (nfd int, err error) 262 //sys Dup2(from int, to int) (err error) 263 //sys Exchangedata(path1 string, path2 string, options int) (err error) 264 //sys Fchdir(fd int) (err error) 265 //sys Fchflags(fd int, flags int) (err error) 266 //sys Fchmod(fd int, mode uint32) (err error) 267 //sys Fchown(fd int, uid int, gid int) (err error) 268 //sys Flock(fd int, how int) (err error) 269 //sys Fpathconf(fd int, name int) (val int, err error) 270 //sys Fsync(fd int) (err error) 271 // Fsync is not called for os.File.Sync(). Please see internal/poll/fd_fsync_darwin.go 272 //sys Ftruncate(fd int, length int64) (err error) 273 //sys Getdtablesize() (size int) 274 //sysnb Getegid() (egid int) 275 //sysnb Geteuid() (uid int) 276 //sysnb Getgid() (gid int) 277 //sysnb Getpgid(pid int) (pgid int, err error) 278 //sysnb Getpgrp() (pgrp int) 279 //sysnb Getpid() (pid int) 280 //sysnb Getppid() (ppid int) 281 //sys Getpriority(which int, who int) (prio int, err error) 282 //sysnb Getrlimit(which int, lim *Rlimit) (err error) 283 //sysnb Getrusage(who int, rusage *Rusage) (err error) 284 //sysnb Getsid(pid int) (sid int, err error) 285 //sysnb Getuid() (uid int) 286 //sysnb Issetugid() (tainted bool) 287 //sys Kqueue() (fd int, err error) 288 //sys Lchown(path string, uid int, gid int) (err error) 289 //sys Link(path string, link string) (err error) 290 //sys Listen(s int, backlog int) (err error) 291 //sys Mkdir(path string, mode uint32) (err error) 292 //sys Mkfifo(path string, mode uint32) (err error) 293 //sys Mknod(path string, mode uint32, dev int) (err error) 294 //sys Mlock(b []byte) (err error) 295 //sys Mlockall(flags int) (err error) 296 //sys Mprotect(b []byte, prot int) (err error) 297 //sys Munlock(b []byte) (err error) 298 //sys Munlockall() (err error) 299 //sys Open(path string, mode int, perm uint32) (fd int, err error) 300 //sys Pathconf(path string, name int) (val int, err error) 301 //sys Pread(fd int, p []byte, offset int64) (n int, err error) 302 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) 303 //sys read(fd int, p []byte) (n int, err error) 304 //sys Readlink(path string, buf []byte) (n int, err error) 305 //sys Rename(from string, to string) (err error) 306 //sys Revoke(path string) (err error) 307 //sys Rmdir(path string) (err error) 308 //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_lseek 309 //sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) 310 //sys Setegid(egid int) (err error) 311 //sysnb Seteuid(euid int) (err error) 312 //sysnb Setgid(gid int) (err error) 313 //sys Setlogin(name string) (err error) 314 //sysnb Setpgid(pid int, pgid int) (err error) 315 //sys Setpriority(which int, who int, prio int) (err error) 316 //sys Setprivexec(flag int) (err error) 317 //sysnb Setregid(rgid int, egid int) (err error) 318 //sysnb Setreuid(ruid int, euid int) (err error) 319 //sysnb Setrlimit(which int, lim *Rlimit) (err error) 320 //sysnb Setsid() (pid int, err error) 321 //sysnb Settimeofday(tp *Timeval) (err error) 322 //sysnb Setuid(uid int) (err error) 323 //sys Symlink(path string, link string) (err error) 324 //sys Sync() (err error) 325 //sys Truncate(path string, length int64) (err error) 326 //sys Umask(newmask int) (oldmask int) 327 //sys Undelete(path string) (err error) 328 //sys Unlink(path string) (err error) 329 //sys Unmount(path string, flags int) (err error) 330 //sys write(fd int, p []byte) (n int, err error) 331 //sys writev(fd int, iovecs []Iovec) (cnt uintptr, err error) 332 //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) 333 //sys munmap(addr uintptr, length uintptr) (err error) 334 //sysnb fork() (pid int, err error) 335 //sysnb ioctl(fd int, req int, arg int) (err error) 336 //sysnb ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_ioctl 337 //sysnb execve(path *byte, argv **byte, envp **byte) (err error) 338 //sysnb exit(res int) (err error) 339 //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) 340 //sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_fcntl 341 //sys unlinkat(fd int, path string, flags int) (err error) 342 //sys openat(fd int, path string, flags int, perm uint32) (fdret int, err error) 343 344 func init() { 345 execveDarwin = execve 346 } 347 348 func readlen(fd int, buf *byte, nbuf int) (n int, err error) { 349 r0, _, e1 := syscall(funcPC(libc_read_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) 350 n = int(r0) 351 if e1 != 0 { 352 err = errnoErr(e1) 353 } 354 return 355 } 356 357 func writelen(fd int, buf *byte, nbuf int) (n int, err error) { 358 r0, _, e1 := syscall(funcPC(libc_write_trampoline), uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) 359 n = int(r0) 360 if e1 != 0 { 361 err = errnoErr(e1) 362 } 363 return 364 } 365 366 // Implemented in the runtime package (runtime/sys_darwin.go) 367 func syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 368 func syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 369 func syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 370 func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) 371 func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) 372 373 // Find the entry point for f. See comments in runtime/proc.go for the 374 // function of the same name. 375 //go:nosplit 376 func funcPC(f func()) uintptr { 377 return **(**uintptr)(unsafe.Pointer(&f)) 378 }