hyde
hyde

Reputation: 62869

Error with os.open in Python

I'm trying to create and write a file if it does not exist yet, so that it is co-operatively safe from race conditions, and I'm having (probably stupid) problem. First, here's code:

import os

def safewrite(text, filename):
    print "Going to open", filename
    fd = os.open(filename, os.O_CREAT | os.O_EXCL, 0666) ##### problem line?
    print "Going to write after opening fd", fd
    os.write(fd, text)
    print "Going to close after writing", text
    os.close(fd)
    print "Going to return after closing"

#test code to verify file writing works otherwise
f = open("foo2.txt", "w")
f.write("foo\n");
f.close()
f = open("foo2.txt", "r")
print "First write contents:", f.read()
f.close()
os.remove("foo2.txt")

#call the problem method
safewrite ("test\n", "foo2.txt")

Then the problem, I get exception:

First write contents: foo

Going to open foo2.txt
Going to write after opening fd 5

Traceback (most recent call last):
  File "/home/user/test.py", line 21, in <module>
    safewrite ("test\n", "foo2.txt")
  File "/home/user/test.py", line 7, in safewrite
    os.write(fd, text)
OSError: [Errno 9] Bad file descriptor

Probable problem line is marked in the code above (I mean, what else could it be?), but I can't figure out how to fix it. What is the problem?

Note: above was tested in a Linux VM, with Python 2.7.3. If you try the code and it works for you, please write a comment with your environment.

Alternative code to do the same thing at least as safely is also very welcome.

Upvotes: 2

Views: 5212

Answers (2)

Brian Cain
Brian Cain

Reputation: 14619

You must open the file with a flag such that you can write to it (os.O_WRONLY).

From open(2):

DESCRIPTION
       The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR.   These  request  opening  the  file  read-only,
       write-only, or read/write, respectively.

From write(2):

NAME
       write - write to a file descriptor

...    
ERRORS
       EAGAIN The file descriptor fd has been marked non-blocking (O_NONBLOCK) and the write would block.

       EBADF  fd is not a valid file descriptor or is not open for writing.

Upvotes: 2

st0ne
st0ne

Reputation: 4265

Change the line:

fd = os.open(filename, os.O_CREAT | os.O_EXCL, 0666)

to be instead:

fd=os.open(filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0666)

Upvotes: 9

Related Questions