I'd like func FolderExists(path string) bool
that will tell whether a folder exists and is writable. I've gotten here:
func FolderExists(path string) bool {
info, err := os.Stat(path)
return os.IsExist(err) && info.Mode().IsDir() && info.Mode().???
}
How to tell if this folder is writable? I cannot simply check for filemode permissions (e.g. 0200 for user write permission) because then I'd have to check the owner of the file. Is there a straightforward way to do this in Go?
For those with UNIX backgrounds, looking for the equivalent of the very simple:
if [ -d "$n" && -w "$n" ] ; then ... fi
There's no platform independent way to achieve this because checking whether the user created a directory is not possible on Windows. So, we will implement it differently for Windows and non-Windows system and then use Golang's build constraints to conditionally compile the files depending upon the OS.
Create 3 .go files under directory file-perm as shown -
file-perm /
file-perm.go
is-writable.go
is-writable_windows.go
File : file-perm.go
package main
import (
"fmt"
)
func main() {
path := "/tmp/xyz"
fmt.Println(IsWritable(path))
}
File : is-writable.go
This builds on all platforms except Windows because syscall.Stat_t is not available on Windows. Please note that there needs to be a blank line after the build constraint // +build !windows
// +build !windows
package main
import (
"fmt"
"os"
"syscall"
)
func IsWritable(path string) (isWritable bool, err error) {
isWritable = false
info, err := os.Stat(path)
if err != nil {
fmt.Println("Path doesn't exist")
return
}
err = nil
if !info.IsDir() {
fmt.Println("Path isn't a directory")
return
}
// Check if the user bit is enabled in file permission
if info.Mode().Perm() & (1 << (uint(7))) == 0 {
fmt.Println("Write permission bit is not set on this file for user")
return
}
var stat syscall.Stat_t
if err = syscall.Stat(path, &stat); err != nil {
fmt.Println("Unable to get stat")
return
}
err = nil
if uint32(os.Geteuid()) != stat.Uid {
isWritable = false
fmt.Println("User doesn't have permission to write to this directory")
return
}
isWritable = true
return
}
File : is-writable_windows.go
This file will build only on Windows because of the _windows.go suffix in the filename. For more info please refer to https://golang.org/pkg/go/build/
package main
import (
"fmt"
"os"
)
func IsWritable(path string) (isWritable bool, err error) {
isWritable = false
info, err := os.Stat(path)
if err != nil {
fmt.Println("Path doesn't exist")
return
}
err = nil
if !info.IsDir() {
fmt.Println("Path isn't a directory")
return
}
// Check if the user bit is enabled in file permission
if info.Mode().Perm()&(1<<(uint(7))) == 0 {
fmt.Println("Write permission bit is not set on this file for user")
return
}
isWritable = true
return
}
Now, you must use go build in file-perm directory and then run the executable. Please note that it won't work with go run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With