aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2019-01-05 14:12:00 +0100
committerJakob Unterwurzacher2019-01-05 14:17:51 +0100
commitad15ad99856f90f3a72be4bd22ce44338645c963 (patch)
treeadf4958eaad373c27d790a36c1bcb8d758eebe43
parent5055f39bd534b1f13257f95ffdc28575b9b2e3ed (diff)
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.
-rw-r--r--internal/exitcodes/exitcodes.go2
-rw-r--r--main.go25
2 files changed, 27 insertions, 0 deletions
diff --git a/internal/exitcodes/exitcodes.go b/internal/exitcodes/exitcodes.go
index c4e18df..cd36988 100644
--- a/internal/exitcodes/exitcodes.go
+++ b/internal/exitcodes/exitcodes.go
@@ -70,6 +70,8 @@ const (
TrezorError = 28
// ExcludeError - an error occurred while processing "-exclude"
ExcludeError = 29
+ // DevNull means that /dev/null could not be opened
+ DevNull = 30
)
// Err wraps an error with an associated numeric exit code
diff --git a/main.go b/main.go
index a376356..619b1ce 100644
--- a/main.go
+++ b/main.go
@@ -8,6 +8,7 @@ import (
"runtime"
"strconv"
"strings"
+ "syscall"
"github.com/hanwen/go-fuse/fuse"
@@ -149,6 +150,7 @@ func printVersion() {
}
func main() {
+ ensureStdFds()
mxp := runtime.GOMAXPROCS(0)
if mxp < 4 {
// On a 2-core machine, setting maxprocs to 4 gives 10% better performance
@@ -328,3 +330,26 @@ func main() {
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)
+}