I am trying to write a program that reads a file while allowing other applications to access it. I’ve learned that in Windows you need to pass syscall.FILESHARE_READ/WRITE flags to prevent file locking. However, introducing these flags restricts me from reading the file in the first place, with the error — read ‘file’: Access is denied. This is my code:
os.OpenFile(path, syscall.O_RDONLY | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_READ, 0444)
Am I using the correct flags? Is this functionality allowed on Windows?
Here's an example Go program Building with this command - GOOS=windows GOARCH=amd64 go build -v -o testRead.exe
package main
import (
"fmt"
"os"
"time"
"bufio"
"syscall"
)
func main() {
if len(os.Args) != 2 {
fmt.Println("Specify file!")
return
}
path := os.Args[1]
f, err := os.OpenFile(path, syscall.O_RDONLY|syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_READ, 0444)
//f, err := os.Open(path)
if err != nil {
fmt.Println("Can't open file")
fmt.Println(err)
return
}
defer f.Close()
reader := bufio.NewReader(f)
line, _, err := reader.ReadLine()
if (err != nil) {
fmt.Println(err)
}
fmt.Println(line)
// Keeps the program alive
t1 := time.Now().Local().Add(time.Second * time.Duration(3))
for {
if time.Now().After(t1) {
fmt.Println("Still Alive!")
t1 = time.Now().Local().Add(time.Second * time.Duration(3))
}
}
}
I've observed that reading works fine with os.Open and os.OpenFile(path, syscall.O_RDONLY, 0444).
The XY problem is asking about your attempted solution rather than your actual problem: The XY Problem.
If we open the file with
f, err := os.OpenFile(path, syscall.O_RDONLY, 0444)
your program runs with no errors.
On Windows, the program uses CreateFile with
DesiredAccess = GENERIC_READ
ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE
For some unknown reason, you are using arbitrary os.OpenFile
flag
bit smashing on Windows.
f, err := os.OpenFile(path, syscall.O_RDONLY|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_READ, 0444)
where
const (
O_RDONLY = 0x00000
O_WRONLY = 0x00001
O_RDWR = 0x00002
FILE_SHARE_READ = 0x00000001
FILE_SHARE_WRITE = 0x00000002
)
Smashing the os.OpenFile
flag
mode bits with unrelated file share bits, you have
flag = syscall.O_RDONLY|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_READ
or
flag = O_RDONLY|O_WRONLY|O_RDWR
The results are undefined.
On Windows, an error is reported: read test.file: Access is denied.
.
On Linux, an error is detected: read test.file: bad file descriptor
.