Opened 4 years ago

Closed 3 years ago

#4248 closed bug (fixed)

Poor error message when openFile fails to open named pipe

Reported by: Khudyakov Owned by:
Priority: normal Milestone: 7.2.1
Component: libraries/base Version: 6.12.3
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty:
Test Case: Blocked By:
Blocking: Related Tickets:

Description

openFile cannot open named pipe if no one reads on the other end and fails with particularly unhelpful error message. Quick googling shows that it opens file in non-blocking mode so failure to open is not bug per se, but this fact is not mentioned in documentation.

Example:

  1. Create named pipe
    $ mkfifo /tmp/fifo
    
  1. Now in GHCi:
    Prelude> openFile "/tmp/fifo" WriteMode
    *** Exception: /tmp/fifo: openFile: does not exist (No such device or address)
    

Change History (6)

comment:1 Changed 4 years ago by igloo

  • Milestone set to 6.14.2

Thanks for the report.

comment:2 follow-up: Changed 3 years ago by simonmar

Would you like us to try opening the file in blocking mode if non-blocking mode fails? We could certainly do that, but I can't remember all the details of the interaction between non-blocking mode and FIFOs, so I can't be sure that it wouldn't have any strange consequences.

comment:3 in reply to: ↑ 2 Changed 3 years ago by duncan

Replying to simonmar:

Would you like us to try opening the file in blocking mode if non-blocking mode fails?

I don't think we would want to do that in general for all files, it's hard to predict what that does for security or atomicity properties.

The linux man page makes the behaviour clear:

A process can open a FIFO in nonblocking mode.  In this  case,  opening
for  read only will succeed even if no-one has opened on the write side
yet, opening for write only will fail with ENXIO  (no  such  device  or
address) unless the other end has already been opened.

Under  Linux,  opening  a  FIFO for read and write will succeed both in
blocking and nonblocking mode.  POSIX leaves this  behavior  undefined.
This  can be used to open a FIFO for writing while there are no readers
available.  A process that uses both ends of the connection in order to
communicate with itself should be very careful to avoid deadlocks.

So, the "does not exist" error is a direct consequence of the ENXIO error code "no such device or address".

comment:4 Changed 3 years ago by simonmar

Yes, I read the man page too. What I was wondering was whether GHC's behaviour of always opening files in non-blocking mode might not be what you want when opening a FIFO, and if that's the case, should we

  • provide a way to open the file in blocking mode instead, or
  • try to do it automatically

In any case, we should at least document the behaviour (but describing this obscure corner-case in such a prominent place as the documentation for openFile might look a bit strange, I'm not sure what to do about that.)

I don't have any strong feelings about this. Somebody tell me what to do :-)

comment:5 Changed 3 years ago by igloo

  • Milestone changed from 7.0.2 to 7.2.1

comment:6 Changed 3 years ago by simonmar

  • Resolution set to fixed
  • Status changed from new to closed

I added an API that you can use to open a file in blocking mode if you want:

Tue Mar 29 14:09:28 BST 2011  Simon Marlow <marlowsd@gmail.com>
  * Add GHC.IO.Handle.FD.openFileBlocking (#4248)
  like openFile, but opens the file without O_NONBLOCK

It's in a GHC-specific module, because this is a GHC-specific issue. You could also use System.Posix.openFD and then System.Posix.fdToHandle, which is more portable.

Note: See TracTickets for help on using tickets.