Closed
Description
What version of Go are you using (go version
)?
go version go1.10.3 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
Linux, amd64
What did you do?
Make a long file path (> 4096 chars). os.RemoveAll(path)
.
package main
import (
"io/ioutil"
"os"
"path/filepath"
"syscall"
"fmt"
)
func main() {
tmpDir, err := ioutil.TempDir("", "")
if err != nil {
panic(err)
}
err = createVeryLongFilePath(tmpDir)
if err != nil {
panic(err)
}
fmt.Println(tmpDir)
err = os.RemoveAll(tmpDir)
if err != nil {
panic(err)
}
}
func createVeryLongFilePath(startPath string) error {
currentPath := startPath
for i := 0; i < 41; i++ {
name := ""
for j := 0; j < 100; j++ {
name = name + "a"
}
if err := mkdirAt(currentPath, name); err != nil {
return err
}
currentPath = filepath.Join(currentPath, name)
}
return nil
}
func mkdirAt(atPath, path string) error {
fd, err := syscall.Open(atPath, syscall.O_RDONLY, 0)
if err != nil {
return err
}
defer syscall.Close(fd)
return syscall.Mkdirat(fd, path, 755)
}
What did you expect to see?
Success.
What did you see instead?
it fails with file name too long
.
Suggested solutions
We have worked around this using unix.Openat
and unix.Unlinkat
in our code base, but this solution would only work on unix.
The problem really is with os.Remove, whose unix syscalls don't accept long file paths. An alternate solution would be to alter os.Remove to split long path names on unix systems.
We'd be happy to submit pull requests for either approach.
cc @Callisto13