Welcome
Example Code
C and C++
Argument Parsing
Create Subprocess
Create Thread
Is Subprocess Done
Non-Blocking File (Unix)
Mutex (Lock)
TCP Server
Wait For File (Unix)
Python
Non-Blocking Read

Monju System Architects



Code - Python - Non-Blocking Read
Download: nonBlockingRead.py (the linked-to file is properly tabbed)
#  Copyright (c) 2007, Monju System Architects
#
#  Released under the Monju-Public copyright license:
#
#  Permission is hereby granted, free of charge, to any person or entity
#  obtaining a copy of this software and associated documentation files
#  (the "Software"), to deal in the Software without restriction,
#  including without limitation the rights to use, copy, modify, merge,
#  publish, distribute, sublicense, and/or sell copies and modifications
#  of the Software, and to permit persons to whom the Software is
#  furnished to do so, subject to the following conditions:
#
#  The above copyright notice and this permission notice shall be
#  included in all copies or substantial portions of published, sold, or
#  ownership-transferred versions of the Software. The notices are not
#  required for binary-only releases or binary-only derivatives of the
#  Software, or documentation provided with binary-only releases and
#  binary-only derivatives.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
#  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
#  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
#  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.




import sys
import errno



_IS_WINDOWS = sys.platform.lower().startswith("win")



if _IS_WINDOWS:
    import msvcrt
    import win32pipe
    import win32file

else:
    import fcntl
    import os
    import select




#  readNonBlocking()
#
#  This function is useful for reading the pipes returned by starting a process,
#  so as to not block waiting on child processes to output data.
def readNonBlocking(pipe, maximumAmount=4000):
    """ Returns None when the pipe is closed.  Otherwise, returns the data read."""

    #  HANDLE WINDOWS...
    if _IS_WINDOWS:

        try:
            osfHandle = msvcrt.get_osfhandle(pipe.fileno())
            (ignore, amountAvailable, ignore) = win32pipe.PeekNamedPipe(osfHandle, 0)
            if amountAvailable == 0:
                if pipe.closed:
                    return None
                return ""
            if maximumAmount > amountAvailable:
                maximumAmount = amountAvailable
            errrCode, data = win32file.ReadFile(osfHandle, maximumAmount, None)
            return data
        except ValueError:
            pipe.close()
            return None
        except Exception, exception:
            if exception[0] in (109, errno.ESHUTDOWN):
                pipe.close()
                return None
            raise

    #  HANDLE NON-WINDOWS.
    else:

        #  MAKE SURE WE ARE NON BLOCKING.
        try:
            flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
        except ValueError, exception:
            if "closed" in str(exception):
                return None
        try:
            if not pipe.closed:
                fcntl.fcntl(pipe, fcntl.F_SETFL, flags | os.O_NONBLOCK)

            #  IF NOTHING IS READY, RETURN EMPTY STRING.
            if len(select.select([pipe], [], [], 0)[0]) == 0:
                return ""

            #  DO THE READ.
            data = pipe.read(maximumAmount)
            if len(data) == 0:
                return pipe.close()
            return data

        #  RETURN THE PIPE TO THE PREVIOUS FLAG STATE.
        finally:
            if not pipe.closed:
                fcntl.fcntl(pipe, fcntl.F_SETFL, flags)