21

I create a FIFO, and periodically open it in read-only and non-blockingly mode from a.py:

os.mkfifo(cs_cmd_fifo_file, 0777)
io = os.open(fifo, os.O_RDONLY | os.O_NONBLOCK)
buffer = os.read(io, BUFFER_SIZE)

From b.py, open the fifo for writing:

out = open(fifo, 'w')
out.write('sth')

Then a.py will raise an error:

buffer = os.read(io, BUFFER_SIZE)

OSError: [Errno 11] Resource temporarily unavailable

Anyone know what's wrong?

tshepang
  • 12,111
  • 21
  • 91
  • 136
chaonin
  • 227
  • 1
  • 2
  • 6
  • 1
    possible duplicate of [What conditions result in an opened, nonblocking named pipe (fifo) being "unavailable" for reads?](http://stackoverflow.com/questions/10021759/what-conditions-result-in-an-opened-nonblocking-named-pipe-fifo-being-unavai) However, this question is definitely still useful, since it's unique phrasing meant it was the first one I found on Google. – Seanny123 Nov 26 '13 at 02:29
  • `NameError: name 'fifo' is not defined` could you please fix the example? – n611x007 Apr 17 '15 at 13:22

2 Answers2

17

According to the manpage of read(2):

   EAGAIN or EWOULDBLOCK
          The  file  descriptor  fd refers to a socket and has been marked
          nonblocking   (O_NONBLOCK),   and   the   read   would    block.
          POSIX.1-2001  allows  either error to be returned for this case,
          and does not require these constants to have the same value,  so
          a portable application should check for both possibilities.

So what you're getting is that there is no data available for reading. It is safe to handle the error like this:

try:
    buffer = os.read(io, BUFFER_SIZE)
except OSError as err:
    if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK:
        buffer = None
    else:
        raise  # something else has happened -- better reraise

if buffer is None: 
    # nothing was received -- do something else
else:
    # buffer contains some received data -- do something with it

Make sure you have the errno module imported: import errno.

Jonas Schäfer
  • 20,140
  • 5
  • 55
  • 69
  • after try it out, a.py raise: UnboundLocalError: local variable 'buffer' referenced before assignment – chaonin Jan 15 '13 at 20:12
  • @chaonin I tried to guess what the reason is (I did not use buffer before), and updated my example. Hopefully it is more clear now. – Jonas Schäfer Jan 15 '13 at 20:25
  • 2
    io = os.open(fifo, os.O_RDONLY | os.O_NONBLOCK) try: buffer = os.read(io, BUFFER_SIZE) except OSError as err: if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK: pass else: raise err jobs_infile = shlex.split(buffer) os.close(io) – chaonin Jan 15 '13 at 20:28
  • For interest: EAGAIN and EWOULDBLOCK both indicate effectively the same thing. In fact on some systems they are the same value. Checking both is a good idea though. – lxs Nov 06 '13 at 15:44
  • 1
    @lxs In fact, you have to if you want to be portable, as the read(2) manpage suggests. It's inconvenient and in python3.3, we would catch [``BlockingIOError``](http://docs.python.org/3/library/exceptions.html#BlockingIOError) instead (which also tells us how many characters were written). – Jonas Schäfer Nov 08 '13 at 10:46
-2
out = open(fifo, 'w')

Who will close it for you? Replace your open+write by this:

with open(fifo, 'w') as fp:
    fp.write('sth')

UPD: Ok, than just make this:

out = os.open(fifo, os.O_NONBLOCK | os.O_WRONLY)
os.write(out, 'tetet')
der_fenix
  • 241
  • 1
  • 10