Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1423)

Unified Diff: src/pkg/syscall/syscall_darwin.go

Issue 12349044: code review 12349044: os, syscall: implement Getwd on darwin using getattrlist (Closed)
Patch Set: diff -r 8aeade4c393e https://go.googlecode.com/hg/ Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pkg/syscall/syscall_bsd.go ('k') | src/pkg/syscall/syscall_no_getwd.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pkg/syscall/syscall_darwin.go
===================================================================
--- a/src/pkg/syscall/syscall_darwin.go
+++ b/src/pkg/syscall/syscall_darwin.go
@@ -12,7 +12,28 @@
package syscall
-import "unsafe"
+import (
+ errorspkg "errors"
+ "unsafe"
+)
+
+const ImplementsGetwd = true
+
+func Getwd() (string, error) {
+ buf := make([]byte, 2048)
+ attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
+ if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
+ wd := string(attrs[0])
+ // Sanity check that it's an absolute path and ends
+ // in a null byte, which we then strip.
+ if wd[0] == '/' && wd[len(wd)-1] == 0 {
+ return wd[:len(wd)-1], nil
+ }
+ }
+ // If pkg/os/getwd.go gets ENOTSUP, it will fall back to the
+ // slow algorithm.
+ return "", ENOTSUP
+}
type SockaddrDatalink struct {
Len uint8
@@ -86,6 +107,76 @@
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
+const (
+ attrBitMapCount = 5
+ attrCmnFullpath = 0x08000000
+)
+
+type attrList struct {
+ bitmapCount uint16
+ _ uint16
+ CommonAttr uint32
+ VolAttr uint32
+ DirAttr uint32
+ FileAttr uint32
+ Forkattr uint32
+}
+
+func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
+ if len(attrBuf) < 4 {
+ return nil, errorspkg.New("attrBuf too small")
+ }
+ attrList.bitmapCount = attrBitMapCount
+
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return nil, err
+ }
+
+ _, _, e1 := Syscall6(
+ SYS_GETATTRLIST,
+ uintptr(unsafe.Pointer(_p0)),
+ uintptr(unsafe.Pointer(&attrList)),
+ uintptr(unsafe.Pointer(&attrBuf[0])),
+ uintptr(len(attrBuf)),
+ uintptr(options),
+ 0,
+ )
+ if e1 != 0 {
+ return nil, e1
+ }
+ size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
+
+ // dat is the section of attrBuf that contains valid data,
+ // without the 4 byte length header. All attribute offsets
+ // are relative to dat.
+ dat := attrBuf
+ if int(size) < len(attrBuf) {
+ dat = dat[:size]
+ }
+ dat = dat[4:] // remove length prefix
+
+ for i := uint32(0); int(i) < len(dat); {
+ header := dat[i:]
+ if len(header) < 8 {
+ return attrs, errorspkg.New("truncated attribute header")
+ }
+ datOff := *(*int32)(unsafe.Pointer(&header[0]))
+ attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
+ if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
+ return attrs, errorspkg.New("truncated results; attrBuf too small")
+ }
+ end := uint32(datOff) + attrLen
+ attrs = append(attrs, dat[datOff:end])
+ i = end
+ if r := i % 4; r != 0 {
+ i += (4 - r)
+ }
+ }
+ return
+}
+
//sysnb pipe() (r int, w int, err error)
func Pipe(p []int) (err error) {
« no previous file with comments | « src/pkg/syscall/syscall_bsd.go ('k') | src/pkg/syscall/syscall_no_getwd.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b