5

As an extension to a previous post that unfortunately seems to have died a death: select.select issue for sockets and pipes. Since this post I have been trying various things to no avail and I wanted to see if anyone has any idea where I am going wrong. I'm using the select() module to identify when data is present on either a pipe or a socket. The socket seems to be working fine but the pipe is proving problematic.

I have set up the pipe as follows:

pipe_name = 'testpipe'
if not os.path.exists(pipe_name):
    os.mkfifo(pipe_name)

and the pipe read is:

pipein = open(pipe_name, 'r')
line = pipein.readline()[:-1]
pipein.close()

It works perfectly as a stand alone piece of code but when I try and link it to the select.select function it fails:

inputdata,outputdata,exceptions = select.select([tcpCliSock,xxxx],[],[])

I have tried entering 'pipe_name', 'testpipe' and 'pipein' in the inputdata argument but I always get a 'not defined' error. Looking at various other posts I thought it might be because the pipe does not have an object identifier so I tried:

pipein = os.open(pipe_name, 'r')
fo = pipein.fileno()

and put 'fo' in the select.select arguments but got a TypeError: an integer is required. I have also had a Error 9: Bad file descriptor when using this configuration of 'fo'. Any ideas what I have done wrong would be appreciated.

EDITED CODE: I have managed to find a way to resolve it although not sure it is particularly neat - I would be interested in any comments- Revised pipe setup:

pipe_name = 'testpipe'
pipein = os.open(pipe_name, os.O_RDONLY)
if not os.path.exists(pipe_name):
    os.mkfifo(pipe_name)

Pipe Read:

def readPipe()
    line = os.read(pipein, 1094)
    if not line:
        return
    else:
        print line

Main loop to monitor events:

inputdata, outputdata,exceptions = select.select([tcpCliSock,pipein],[],[])
if tcpCliSock in inputdata:
    readTCP()   #function and declarations not shown
if pipein in inputdata:
    readPipe()

It all works well, my only problem now is getting the code to read from the socket before any event monitoring from select gets underway. As soon as connection is made to the TCP server a command is sent via the socket and I seem to have to wait until the pipe has been read for the first time before this command comes through.

Community
  • 1
  • 1
AimSkyward
  • 145
  • 3
  • 12
  • You on a windows box? Select only works with sockets there. – Spencer Rathbun Sep 13 '13 at 12:34
  • In your original question you wrote "The pipe currently holds incoming data from an html form, the socket makes up a connection to a server that sends TCP/IP commands at various intervals. The form and server are on the same LAN but different computers." Named pipes (fifos) are local to a single machine and are not accessible from another. You've shown the fifo being read, but not a fifo writer. Something is missing from your question. – msw Sep 13 '13 at 12:42
  • Hey Spencer, no not Windows, have managed to get it working. – AimSkyward Sep 14 '13 at 12:59
  • Hey msw, Yeah i think my description wasn't great. The form is on the same machine as the server that creates the fifo (The form is accessed through it's IP address on the LAN). The data from the form is put onto the pipe and read from it by the python code via the select function. The TCP commands are incoming from another machine which is itself a server so my machine is acting as a client. I have changed my os.open command to include the write although I don't make use of it. pipein = os.open(pipe_name, os.O_WRONLY). Now the select command picks up data incoming from both socket and pipe. – AimSkyward Sep 14 '13 at 13:07

1 Answers1

2

According to the docs, select needs a file descriptor from os.open or similar. So, you should use select.select([pipein], [], []) as your command.

Alternatively, you can use epoll if you are on a linux system.

poller = epoll.fromfd(pipein)
events = poller.poll()
for fileno, event in events:
  if event is select.EPOLLIN:
    print "We can read from", fileno
Spencer Rathbun
  • 14,510
  • 6
  • 54
  • 73
  • Hi Spencer, Thanks for the comment, before I got to see it I managed to find a way to do it although it is slightly different from what you recommended. I have had a good look at using epoll and it may be the way I end up going as it seems quite neat. If you are interested I have added an edit to my original post describing what I did, I would be interested in your comments. Thanks again – AimSkyward Sep 13 '13 at 15:09