Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os: os.OpenFile() ignores FileMode when truncating a existing file #33605

Closed
WestleyK opened this issue Aug 12, 2019 · 6 comments
Closed

os: os.OpenFile() ignores FileMode when truncating a existing file #33605

WestleyK opened this issue Aug 12, 2019 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@WestleyK
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.12.7 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (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"

What did you do?

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()
}

What did you expect to see?

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.


What did you see instead?

os.OpenFile() ignored the 0777 permission, and continued without an error.

@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Aug 13, 2019
@dmitshur dmitshur added this to the Go1.14 milestone Aug 13, 2019
@dmitshur
Copy link
Contributor

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?

@WestleyK
Copy link
Author

WestleyK commented Aug 13, 2019

@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.

@networkimprov
Copy link

I believe you'll see the same behavior from a C program; i.e. that's POSIX.

@dmitshur
Copy link
Contributor

dmitshur commented Aug 13, 2019

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.

@WestleyK
Copy link
Author

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 👍

@odeke-em
Copy link
Member

Closing as per #33605 (comment) 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

@golang golang locked and limited conversation to collaborators Aug 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants