2

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.

1

2 Answers 2

9

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)
Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.