go version)?$ go version go version go1.12.7 linux/amd64
Yes
go env)?go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/westleyk/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/westleyk/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build074655655=/tmp/go-build -gno-record-gcc-switches"
Here is a test code, that will use os.OpenFile() to open a test file with 0777:
package main
import (
"log"
"os"
)
func main() {
f, err := os.OpenFile("foo.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
if err != nil {
log.Fatalf("failed opening file: %s", err)
}
f.Close()
}
When I run the code with go run test.go, and foo.txt does not exist, I get the expected results:
$ ls -l foo.txt
ls: cannot access 'foo.txt': No such file or directory
$ go run test.go
$ ls -l foo.txt
-rwxr-xr-x 1 westleyk westleyk 0 Aug 12 12:16 foo.txt
But, when foo.txt already exist (with the "default" permission), the specified 777 file permission is ignored and not applied to foo.txt...
$ touch foo.txt
$ ls -l foo.txt
-rw-r--r-- 1 westleyk westleyk 0 Aug 12 12:17 foo.txt
$ go run test.go
$ ls -l foo.txt
-rw-r--r-- 1 westleyk westleyk 0 Aug 12 12:17 foo.txt
I expected when truncating the already-existing file, os.OpenFile will truncated it, and apply the specified file permission.
os.OpenFile() ignored the 0777 permission, and continued without an error.
Thanks for reporting.
Do you know (or can you check) what was the behavior in Go 1.11 or older versions? In other words, is this a recent regression, or has it always behaved like that?
@dmitshur, I got the same behavior as above with go1.11, all the way down to go1.2.2. So _all_ the go versions are like this.
I believe you'll see the same behavior from a C program; i.e. that's POSIX.
Thank you for confirming this is not a recent regression, that's very helpful.
This issue is under the Go1.14 milestone, so we can investigate it during the upcoming development cycle.
Yeah, a similar c program does this same behavior, which seems a little weird... I guess this is not a issue with Go. Thanks for the help! Close when ready :+1:
Closing as per https://github.com/golang/go/issues/33605#issuecomment-520672726 and thanks @WestleyK for the report, @dmitshur for the triage and @networkimprov for catching that an equivalent C program produces the same result.
For the record here is the equivalent C program
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/errno.h>
#include <stdio.h>
int main() {
int fd = open("foo.txt", O_CREAT|O_TRUNC|O_WRONLY, 0777);
if (fd < 0) {
fprintf(stderr, "opening file: %s\n", strerror(errno));
return -1;
}
close(fd);
return 0;
}
and when run, here are the results:
$ gcc main.c -o main
$ ls -lrth
total 32
-rw-r--r-- 1 emmanuelodeke staff 315B 13 Aug 00:18 main.c
-rwxr-xr-x 1 emmanuelodeke staff 8.5K 13 Aug 00:19 main
$ ./main
$ ls -lrth
total 32
-rw-r--r-- 1 emmanuelodeke staff 315B 13 Aug 00:18 main.c
-rwxr-xr-x 1 emmanuelodeke staff 8.5K 13 Aug 00:19 main
-rwxr-xr-x 1 emmanuelodeke staff 0B 13 Aug 00:19 foo.txt
$ ./main
$ ls -lrth
total 32
-rw-r--r-- 1 emmanuelodeke staff 315B 13 Aug 00:18 main.c
-rwxr-xr-x 1 emmanuelodeke staff 8.5K 13 Aug 00:19 main
-rwxr-xr-x 1 emmanuelodeke staff 0B 13 Aug 00:20 foo.txt
$ chmod 0777 foo.txt # Now trying with chmod and this should change the permissions
$ ls -lrth
total 32
-rw-r--r-- 1 emmanuelodeke staff 315B 13 Aug 00:18 main.c
-rwxr-xr-x 1 emmanuelodeke staff 8.5K 13 Aug 00:19 main
-rwxrwxrwx 1 emmanuelodeke staff 0B 13 Aug 00:20 foo.txt
Most helpful comment
Closing as per https://github.com/golang/go/issues/33605#issuecomment-520672726 and thanks @WestleyK for the report, @dmitshur for the triage and @networkimprov for catching that an equivalent C program produces the same result.
For the record here is the equivalent C program
and when run, here are the results: