Permission problem when creating a file in a Go program

14,847 views
Skip to first unread message

vendion

unread,
Apr 9, 2010, 1:57:11 PM4/9/10
to golang-nuts
I'm trying to create a file in go with permissions of 755, the way I
am doing it is like this

Config, err := os.Open(Home + "/.backup-lightrc", os.O_CREATE, 755)

After running the program I see that it does create the file in
question but running 'ls -l' I this is what it returns:

'--wxr----t 1 vendion users 0 2010-04-09 13:45 /home/vendion/.backup-
lightrc'

It looks like the owner of the file has read and write permissions but
any attempts to access the file, ether by a program written in Go and
vim, gets a permission denied error.

Daniel Smith

unread,
Apr 9, 2010, 2:02:14 PM4/9/10
to vendion, golang-nuts
You probably want 0755, which will make it an octal number. (755 decimal = 01363 octal, which is not the permissions you meant to set)



--
To unsubscribe, reply using "remove me" as the subject.



--
Daniel Smith
http://www.schaumburggoclub.org/

abiosoft

unread,
Apr 10, 2010, 4:34:24 AM4/10/10
to golang-nuts
I've been creating all files with permission 0666.

But i'm having similar issues when creating a folder so I make use of
mkdir with Forkexec.

vendion

unread,
Apr 10, 2010, 10:33:58 PM4/10/10
to golang-nuts
Well that seemed to have solved one part of the problem, but now when
the programs tries to write to the file it complains about a bad file
descriptor (see below):

Error: Write has failed: write /home/vendion/.backup-lightrc: bad file
descriptor

The only thing I can think of is in my os.Open line I need to use both
os.O_CREATE and os.O_RDWR but not sure how, to give a better idea of
what I am doing here is a code snipplet:

func CreateConfig() {
var Success int
Home := os.Getenv("HOME")
Config, err := os.Open(Home + "/.backup-lightrc", os.O_CREATE, 0755)
if err != nil {
fmt.Printf("Error: Can't create config file, %s\n", err.String())
os.Exit(1)
}
//Get information for config file and write it
fmt.Println("\nSpecify backup directory [/tmp]: ")
input := bufio.NewReader(os.Stdin)
result, _ := input.ReadString('\n')
backupDir := strings.TrimSpace(result)
if backupDir == "" {
backupDir = "/tmp"
}
Success, err = Config.WriteString(backupDir)
if Success == 0 {
fmt.Printf("Error: Write has failed: %s\n", err.String()) <- Fails
at this point
os.Exit(1)
}
if err != nil { <- For some reason didn't catch the problem with bad
file descriptor, even the the above if proves that err is definitely
not nil
fmt.Printf("Error: Can't write to config file: %s\n", err.String())
os.Exit(1)
}
//Add more config options here
fmt.Println("Configuration file created, please rerun backup-light now
\n")
Config.Close()
os.Exit(0)
}

On Apr 9, 7:02 pm, Daniel Smith <lukenin...@gmail.com> wrote:

Daniel Smith

unread,
Apr 10, 2010, 11:07:12 PM4/10/10
to vendion, golang-nuts
You can bit-or those flags together: os.O_CREATE | os.O_RDWR

"Success" is misnamed, that function returns the number of bytes written, so


Success, err = Config.WriteString(backupDir)
if Success == 0 {

should be

Count, err := Config.WriteString(backupDir)
if Count != len(backupDir) { //see http://golang.org/pkg/os/#File.Write

Or something like that. Actually it really should be

if err != nil { //I'm not sure why this wouldn't work for you

Adam Jimerson

unread,
Apr 10, 2010, 11:42:40 PM4/10/10
to Daniel Smith, golang-nuts
Yea I know Success is bad wording for it, but I was just trying to throw
something together to see if it was truly generating a error or what was
going on. Anyways I'll see if using a bit-or will solve my problem, as
for the problem with "err != nil" it is kind of weird as to why that is
not catching anything, would be nice to know why.

Russ Cox

unread,
Apr 11, 2010, 3:46:28 PM4/11/10
to Adam Jimerson, Daniel Smith, golang-nuts
> going on.  Anyways I'll see if using a bit-or will solve my problem,

It will.

> as for the problem with "err != nil" it is kind of weird as to why that is not
> catching anything, would be nice to know why.

Because there wasn't an error.
The code created a file and opened it for reading
(on Unix, O_RDONLY=0, so O_CREATE == O_CREATE|O_RDONLY).
The only error, from the operating system's vantage point,
is that the program tried to write to a file open only for reading.

Russ

Daniel Smith

unread,
Apr 11, 2010, 4:55:37 PM4/11/10
to r...@golang.org, Adam Jimerson, golang-nuts

On Sun, Apr 11, 2010 at 2:46 PM, Russ Cox <r...@golang.org> wrote:
Because there wasn't an error.
The code created a file and opened it for reading
(on Unix, O_RDONLY=0, so O_CREATE == O_CREATE|O_RDONLY).
The only error, from the operating system's vantage point,
is that the program tried to write to a file open only for reading.

...but Write() should still return a non-nil err. I thought Adam was saying that Write incorrectly returned 0 and nil (the documentation says, "Write returns a non-nil Error when n != len(b)" [1]), so I just tested it. The documentation is correct. I cannot reproduce Adam's reported non-nil err [2]. And, looking at his code, the fmt.Printf(... err.String()) ought to panic if err really were nil. It seems likely that his code has evolved since he got that result--perhaps at some point it was writing a string of length 0?

[1] http://golang.org/pkg/os/#File.Write
[2]
package main

import (
    "os"
    "fmt"
)

func main() {
    f, err := os.Open("testfile", os.O_CREATE, 0755)

    if err != nil {
        fmt.Printf("Error: Can't create config file, %s\n", err.String())
        return
    }
    defer f.Close()
   
    str := "some string"
   
    n, err := f.WriteString(str)
    if n != len(str) {
        if err == nil {
            panic("err ought to be something")
        }
        fmt.Printf("Error: Write has failed: %s\n", err.String()) //this is the output, not the panic
        return

Adam Jimerson

unread,
Apr 11, 2010, 6:03:05 PM4/11/10
to Daniel Smith, golang-nuts, r...@golang.org

The only change I made to my code was the addition of "| os.O_RDWR".  I will admit I may have had a typo or something that I fixed without thinking about it, the way I know this because I committed out the line compairing to 0, leaving the err != nil line and it worked.

Sorry for bugging everyone so much, also sorry for any typos I wrote this on my Nexus One.

On Apr 11, 2010 4:55 PM, "Daniel Smith" <luken...@gmail.com> wrote:


On Sun, Apr 11, 2010 at 2:46 PM, Russ Cox <r...@golang.org> wrote:
>

> Because there wasn't an error...

Reply all
Reply to author
Forward
0 new messages