Skip to content

Commit 731ebf4

Browse files
randall77andybons
authored andcommitted
[release-branch.go1.12] syscall: avoid _getdirentries64 on darwin
Getdirentries is implemented with the __getdirentries64 function in libSystem.dylib. That function works, but it's on Apple's can't-be-used-in-an-app-store-application list. Implement Getdirentries using the underlying fdopendir/readdir_r/closedir. The simulation isn't faithful, and could be slow, but it should handle common cases. Don't use Getdirentries in the stdlib, use fdopendir/readdir_r/closedir instead (via (*os.File).readdirnames). (Incorporates CL 170837 and CL 170698, which were small fixes to the original tip CL.) Fixes #31244 Update #28984 RELNOTE=yes Change-Id: Ia6b5d003e5bfe43ba54b1e1d9cfa792cc6511717 Reviewed-on: https://go-review.googlesource.com/c/go/+/168479 Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> (cherry picked from commit 9da6530) Reviewed-on: https://go-review.googlesource.com/c/go/+/170640 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
1 parent 8b086a2 commit 731ebf4

23 files changed

+300
-159
lines changed

src/internal/poll/fd_opendir_ios.go renamed to src/internal/poll/fd_opendir_darwin.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build darwin
6-
// +build arm arm64
7-
85
package poll
96

107
import (

src/os/dir_ios.go renamed to src/os/dir_darwin.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build darwin
6-
// +build arm arm64
7-
85
package os
96

107
import (
@@ -47,12 +44,12 @@ func (f *File) readdirnames(n int) (names []string, err error) {
4744

4845
names = make([]string, 0, size)
4946
var dirent syscall.Dirent
50-
var entptr uintptr
51-
for len(names) < size {
52-
if res := readdir_r(d.dir, uintptr(unsafe.Pointer(&dirent)), uintptr(unsafe.Pointer(&entptr))); res != 0 {
47+
var entptr *syscall.Dirent
48+
for len(names) < size || n == -1 {
49+
if res := readdir_r(d.dir, &dirent, &entptr); res != 0 {
5350
return names, wrapSyscallError("readdir", syscall.Errno(res))
5451
}
55-
if entptr == 0 { // EOF
52+
if entptr == nil { // EOF
5653
break
5754
}
5855
if dirent.Ino == 0 {
@@ -84,4 +81,4 @@ func (f *File) readdirnames(n int) (names []string, err error) {
8481
func closedir(dir uintptr) (err error)
8582

8683
//go:linkname readdir_r syscall.readdir_r
87-
func readdir_r(dir, entry, result uintptr) (res int)
84+
func readdir_r(dir uintptr, entry *syscall.Dirent, result **syscall.Dirent) (res int)

src/os/dir_unix.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build aix darwin,!arm,!arm64 dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris
5+
// +build aix dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris
66

77
package os
88

src/runtime/sys_darwin.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
8989
}
9090
func syscall6X()
9191

92+
//go:linkname syscall_syscallPtr syscall.syscallPtr
93+
//go:nosplit
94+
//go:cgo_unsafe_args
95+
func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
96+
entersyscallblock()
97+
libcCall(unsafe.Pointer(funcPC(syscallPtr)), unsafe.Pointer(&fn))
98+
exitsyscall()
99+
return
100+
}
101+
func syscallPtr()
102+
92103
//go:linkname syscall_rawSyscall syscall.rawSyscall
93104
//go:nosplit
94105
//go:cgo_unsafe_args

src/runtime/sys_darwin_32.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,3 @@ func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, e
1919
return
2020
}
2121
func syscall9()
22-
23-
//go:linkname syscall_syscallPtr syscall.syscallPtr
24-
//go:nosplit
25-
//go:cgo_unsafe_args
26-
func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
27-
entersyscallblock()
28-
libcCall(unsafe.Pointer(funcPC(syscallPtr)), unsafe.Pointer(&fn))
29-
exitsyscall()
30-
return
31-
}
32-
func syscallPtr()

src/runtime/sys_darwin_386.s

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,9 +675,42 @@ ok:
675675
POPL BP
676676
RET
677677

678-
// Not used on 386.
678+
// syscallPtr is like syscall except the libc function reports an
679+
// error by returning NULL and setting errno.
679680
TEXT runtime·syscallPtr(SB),NOSPLIT,$0
680-
MOVL $0xf1, 0xf1 // crash
681+
PUSHL BP
682+
MOVL SP, BP
683+
SUBL $24, SP
684+
MOVL 32(SP), CX
685+
MOVL (0*4)(CX), AX // fn
686+
MOVL (1*4)(CX), DX // a1
687+
MOVL DX, 0(SP)
688+
MOVL (2*4)(CX), DX // a2
689+
MOVL DX, 4(SP)
690+
MOVL (3*4)(CX), DX // a3
691+
MOVL DX, 8(SP)
692+
693+
CALL AX
694+
695+
MOVL 32(SP), CX
696+
MOVL AX, (4*4)(CX) // r1
697+
MOVL DX, (5*4)(CX) // r2
698+
699+
// syscallPtr libc functions return NULL on error
700+
// and set errno.
701+
TESTL AX, AX
702+
JNE ok
703+
704+
// Get error code from libc.
705+
CALL libc_error(SB)
706+
MOVL (AX), AX
707+
MOVL 32(SP), CX
708+
MOVL AX, (6*4)(CX) // err
709+
710+
ok:
711+
XORL AX, AX // no error (it's ignored anyway)
712+
MOVL BP, SP
713+
POPL BP
681714
RET
682715

683716
// syscall6 calls a function in libc on behalf of the syscall package.

src/runtime/sys_darwin_64.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,3 @@ func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
1919
return
2020
}
2121
func syscallX()
22-
23-
//go:linkname syscall_syscallXPtr syscall.syscallXPtr
24-
//go:nosplit
25-
//go:cgo_unsafe_args
26-
func syscall_syscallXPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
27-
entersyscallblock()
28-
libcCall(unsafe.Pointer(funcPC(syscallXPtr)), unsafe.Pointer(&fn))
29-
exitsyscall()
30-
return
31-
}
32-
func syscallXPtr()

src/runtime/sys_darwin_amd64.s

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,40 @@ ok:
637637
POPQ BP
638638
RET
639639

640-
// Not used on amd64.
641-
TEXT runtime·syscallXPtr(SB),NOSPLIT,$0
642-
MOVL $0xf1, 0xf1 // crash
640+
// syscallPtr is like syscallX except that the libc function reports an
641+
// error by returning NULL and setting errno.
642+
TEXT runtime·syscallPtr(SB),NOSPLIT,$0
643+
PUSHQ BP
644+
MOVQ SP, BP
645+
SUBQ $16, SP
646+
MOVQ (0*8)(DI), CX // fn
647+
MOVQ (2*8)(DI), SI // a2
648+
MOVQ (3*8)(DI), DX // a3
649+
MOVQ DI, (SP)
650+
MOVQ (1*8)(DI), DI // a1
651+
XORL AX, AX // vararg: say "no float args"
652+
653+
CALL CX
654+
655+
MOVQ (SP), DI
656+
MOVQ AX, (4*8)(DI) // r1
657+
MOVQ DX, (5*8)(DI) // r2
658+
659+
// syscallPtr libc functions return NULL on error
660+
// and set errno.
661+
TESTQ AX, AX
662+
JNE ok
663+
664+
// Get error code from libc.
665+
CALL libc_error(SB)
666+
MOVLQSX (AX), AX
667+
MOVQ (SP), DI
668+
MOVQ AX, (6*8)(DI) // err
669+
670+
ok:
671+
XORL AX, AX // no error (it's ignored anyway)
672+
MOVQ BP, SP
673+
POPQ BP
643674
RET
644675

645676
// syscall6 calls a function in libc on behalf of the syscall package.

src/runtime/sys_darwin_arm.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ ok:
418418
RET
419419

420420
// syscallPtr is like syscall except the libc function reports an
421-
// error by returning NULL.
421+
// error by returning NULL and setting errno.
422422
TEXT runtime·syscallPtr(SB),NOSPLIT,$0
423423
MOVW.W R0, -4(R13) // push structure pointer
424424
MOVW 0(R0), R12 // fn

src/runtime/sys_darwin_arm64.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,9 @@ TEXT runtime·syscallX(SB),NOSPLIT,$0
465465
ok:
466466
RET
467467

468-
// syscallXPtr is like syscallX except that the libc function reports an
469-
// error by returning NULL.
470-
TEXT runtime·syscallXPtr(SB),NOSPLIT,$0
468+
// syscallPtr is like syscallX except that the libc function reports an
469+
// error by returning NULL and setting errno.
470+
TEXT runtime·syscallPtr(SB),NOSPLIT,$0
471471
SUB $16, RSP // push structure pointer
472472
MOVD R0, (RSP)
473473

0 commit comments

Comments
 (0)