# 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)