main: ensure fds 0,1,2 are always open

The Go stdlib, as well as the gocryptfs code, relies on the fact
that fds 0,1,2 are always open.

See https://github.com/rfjakob/gocryptfs/issues/320 for details.
This commit is contained in:
Jakob Unterwurzacher 2019-01-05 14:12:00 +01:00
parent 5055f39bd5
commit ad15ad9985
2 changed files with 27 additions and 0 deletions

View File

@ -70,6 +70,8 @@ const (
TrezorError = 28 TrezorError = 28
// ExcludeError - an error occurred while processing "-exclude" // ExcludeError - an error occurred while processing "-exclude"
ExcludeError = 29 ExcludeError = 29
// DevNull means that /dev/null could not be opened
DevNull = 30
) )
// Err wraps an error with an associated numeric exit code // Err wraps an error with an associated numeric exit code

25
main.go
View File

@ -8,6 +8,7 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"syscall"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
@ -149,6 +150,7 @@ func printVersion() {
} }
func main() { func main() {
ensureStdFds()
mxp := runtime.GOMAXPROCS(0) mxp := runtime.GOMAXPROCS(0)
if mxp < 4 { if mxp < 4 {
// On a 2-core machine, setting maxprocs to 4 gives 10% better performance // On a 2-core machine, setting maxprocs to 4 gives 10% better performance
@ -328,3 +330,26 @@ func main() {
os.Exit(0) os.Exit(0)
} }
} }
// ensureStdFds ensures that file descriptors 0,1,2 are open. The Go stdlib,
// as well as the gocryptfs code, relies on the fact that fds 0,1,2 are always
// open.
// See https://github.com/rfjakob/gocryptfs/issues/320 for details.
//
// This function should be called as the first thing from main().
func ensureStdFds() {
fd, err := syscall.Open("/dev/null", syscall.O_RDWR, 0)
if err != nil {
tlog.Fatal.Printf("ensureStdFds: open /dev/null failed: %v", err)
os.Exit(exitcodes.DevNull)
}
for fd <= 2 {
fd, err = syscall.Dup(fd)
if err != nil {
tlog.Fatal.Printf("ensureStdFds: dup failed: %v", err)
os.Exit(exitcodes.DevNull)
}
}
// Close excess fd (usually fd 3)
syscall.Close(fd)
}