Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have a server script that runs all the time in a dialog with a remote device (IE via RS232). The remote device must get regular input from the perl script otherwise it alarms.

I want to connect to this process from a CGI script to ask it to get info from the device, to this end I have opened two pipes one for writing requests to the server application and one for the server to write back the requested data.

After working around the blocking behaviour of pipes (blocking interferes with the regular servicing of the device) I have encountered a problem I am having trouble solving. The CGI script is only intermittently connecting to the pipes, so most of the time there is no reader/writer on the named pipe endpoints from the servers point of view. If something goes wrong, and the server writes on the output pipe when there is no reader, then it gets a SIGPIPE (Ignored) and subsequent writes fail even if a reader subsequently connects and is present when writing.

Other that catching SIGPIPE, and reopening the pipe after each SIGPIPE, is there any other way to work around this problem. For example can I test if there is a reader on the pipe before writing to it ?

What better ways are there for a many-to-one connection than pipes that support non-blocking I/O.

Replies are listed 'Best First'.
Re: many-to-one pipes
by cdarke (Prior) on Mar 14, 2011 at 09:08 UTC
    can I test if there is a reader on the pipe before writing to it ?

    Assuming you are opening the pipe for write-only, you need to specify O_NONBLOCK on the file handle when you open it, see sysopen and Fcntl. The run-time errno should be set to ENXIO if no process has the pipe open for reading. This is accessable through $! and Errno might also be useful.

    Alternatively use non-blocking sockets or message queues.
Re: many-to-one pipes
by happy.barney (Friar) on Mar 14, 2011 at 06:03 UTC