mirror of
https://github.com/golang/go
synced 2024-11-19 07:04:43 -07:00
syscall: ensure Mkdir(path) on Plan 9 fails if path exists
On Plan 9, the underlying create() syscall with DMDIR flag, which is used to implement Mkdir, will fail silently if the path exists and is not a directory. Work around this by checking for existence first and rejecting Mkdir with error EEXIST if the path is found. Fixes #23918 Change-Id: I439115662307923c9f498d3e7b1f32c6d205e1ad Reviewed-on: https://go-review.googlesource.com/94777 Reviewed-by: David du Colombier <0intro@gmail.com>
This commit is contained in:
parent
9b7f221a3a
commit
a156fc08b7
@ -9,7 +9,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const _BIT16SZ = 2
|
||||
const bitSize16 = 2
|
||||
|
||||
func fileInfoFromStat(d *syscall.Dir) FileInfo {
|
||||
fs := &fileStat{
|
||||
@ -46,7 +46,7 @@ func dirstat(arg interface{}) (*syscall.Dir, error) {
|
||||
size := syscall.STATFIXLEN + 16*4
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
buf := make([]byte, _BIT16SZ+size)
|
||||
buf := make([]byte, bitSize16+size)
|
||||
|
||||
var n int
|
||||
switch a := arg.(type) {
|
||||
@ -60,7 +60,7 @@ func dirstat(arg interface{}) (*syscall.Dir, error) {
|
||||
panic("phase error in dirstat")
|
||||
}
|
||||
|
||||
if n < _BIT16SZ {
|
||||
if n < bitSize16 {
|
||||
return nil, &PathError{"stat", name, err}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ package syscall
|
||||
import "unsafe"
|
||||
|
||||
const ImplementsGetwd = true
|
||||
const bitSize16 = 2
|
||||
|
||||
// ErrorString implements Error's String method by returning itself.
|
||||
type ErrorString string
|
||||
@ -164,6 +165,20 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
|
||||
}
|
||||
|
||||
func Mkdir(path string, mode uint32) (err error) {
|
||||
// If path exists and is not a directory, Create will fail silently.
|
||||
// Work around this by rejecting Mkdir if path exists.
|
||||
statbuf := make([]byte, bitSize16)
|
||||
// Remove any trailing slashes from path, otherwise the Stat will
|
||||
// fail with ENOTDIR.
|
||||
n := len(path)
|
||||
for n > 1 && path[n-1] == '/' {
|
||||
n--
|
||||
}
|
||||
_, err = Stat(path[0:n], statbuf)
|
||||
if err == nil {
|
||||
return EEXIST
|
||||
}
|
||||
|
||||
fd, err := Create(path, O_RDONLY, DMDIR|mode)
|
||||
|
||||
if fd != -1 {
|
||||
|
Loading…
Reference in New Issue
Block a user