def __init__(self, proto): """ Start talking to standard IO with the given protocol. Also, put it stdin/stdout/stderr into binary mode. """ from twisted.internet import reactor for stdfd in range(0, 1, 2): msvcrt.setmode(stdfd, os.O_BINARY) _pollingfile._PollingTimer.__init__(self, reactor) self.proto = proto hstdin = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE) hstdout = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE) self.stdin = _pollingfile._PollableReadPipe( hstdin, self.dataReceived, self.readConnectionLost) self.stdout = _pollingfile._PollableWritePipe( hstdout, self.writeConnectionLost) self._addPollableResource(self.stdin) self._addPollableResource(self.stdout) self.proto.makeConnection(self)
def test_writeUnicode(self): """ L{_pollingfile._PollableWritePipe.write} raises a C{TypeError} if an attempt is made to append unicode data to the output buffer. """ p = _pollingfile._PollableWritePipe(1, lambda: None) self.assertRaises(TypeError, p.write, u"test")
def __init__(self, proto, reactor=None): """ Start talking to standard IO with the given protocol. Also, put it stdin/stdout/stderr into binary mode. """ if reactor is None: from twisted.internet import reactor for stdfd in range(0, 1, 2): msvcrt.setmode(stdfd, os.O_BINARY) _pollingfile._PollingTimer.__init__(self, reactor) self.proto = proto hstdin = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE) hstdout = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE) self.stdin = _pollingfile._PollableReadPipe( hstdin, self.dataReceived, self.readConnectionLost ) self.stdout = _pollingfile._PollableWritePipe(hstdout, self.writeConnectionLost) self._addPollableResource(self.stdin) self._addPollableResource(self.stdout) self.proto.makeConnection(self)
def test_writeSequenceUnicode(self): """ L{_pollingfile._PollableWritePipe.writeSequence} raises a C{TypeError} if unicode data is part of the data sequence to be appended to the output buffer. """ p = _pollingfile._PollableWritePipe(1, lambda: None) self.assertRaises(TypeError, p.writeSequence, [u"test"]) self.assertRaises(TypeError, p.writeSequence, (u"test", ))
def test_checkWorkUnicode(self): """ When one tries to pass unicode to L{_pollingfile._PollableWritePipe}, a C{TypeError} is raised instead of passing the data to C{WriteFile} call which is going to mangle it. """ p = _pollingfile._PollableWritePipe(1, lambda: None) p.write("test") p.checkWork() p.write(u"test") self.assertRaises(TypeError, p.checkWork)
def __init__(self, proto): from twisted.internet import reactor _pollingfile._PollingTimer.__init__(self, reactor) self.proto = proto hstdin = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE) hstdout = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE) self.stdin = _pollingfile._PollableReadPipe( hstdin, self.dataReceived, self.readConnectionLost) self.stdout = _pollingfile._PollableWritePipe( hstdout, self.writeConnectionLost) self._addPollableResource(self.stdin) self._addPollableResource(self.stdout) self.proto.makeConnection(self)
def __init__(self, proto): from twisted.internet import reactor _pollingfile._PollingTimer.__init__(self, reactor) self.proto = proto hstdin = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE) hstdout = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE) self.stdin = _pollingfile._PollableReadPipe(hstdin, self.dataReceived, self.readConnectionLost) self.stdout = _pollingfile._PollableWritePipe(hstdout, self.writeConnectionLost) self._addPollableResource(self.stdin) self._addPollableResource(self.stdout) self.proto.makeConnection(self)
def __init__(self, reactor, protocol, command, args, environment, path): """ Create a new child process. """ _pollingfile._PollingTimer.__init__(self, reactor) BaseProcess.__init__(self, protocol) # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false currentPid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) env = { os.fsdecode(key): os.fsdecode(value) for key, value in env.items() } # Make sure all the arguments are Unicode. args = [os.fsdecode(x) for x in args] cmdline = quoteArguments(args) # The command, too, needs to be Unicode, if it is a value. command = os.fsdecode(command) if command else command path = os.fsdecode(path) if path else path # TODO: error detection here. See #2787 and #4184. def doCreate(): flags = win32con.CREATE_NO_WINDOW self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess( command, cmdline, None, None, 1, flags, env, path, StartupInfo) try: doCreate() except pywintypes.error as pwte: if not _invalidWin32App(pwte): # This behavior isn't _really_ documented, but let's make it # consistent with the behavior that is documented. raise OSError(pwte) else: # look for a shebang line. Insert the original 'command' # (actually a script) into the new arguments list. sheb = _findShebang(command) if sheb is None: raise OSError("%r is neither a Windows executable, " "nor a script with a shebang line" % command) else: args = list(args) args.insert(0, command) cmdline = quoteArguments(args) origcmd = command command = sheb try: # Let's try again. doCreate() except pywintypes.error as pwte2: # d'oh, failed again! if _invalidWin32App(pwte2): raise OSError("%r has an invalid shebang line: " "%r is not a valid executable" % (origcmd, sheb)) raise OSError(pwte2) # close handles which only the child will use win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.proto.childDataReceived(1, data), self.outConnectionLost, ) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.proto.childDataReceived(2, data), self.errConnectionLost, ) self.stdin = _pollingfile._PollableWritePipe(self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.proto.makeConnection(self) self._addPollableResource(_Reaper(self))
win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.proto.childDataReceived(1, data), self.outConnectionLost) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.proto.childDataReceived(2, data), self.errConnectionLost) self.stdin = _pollingfile._PollableWritePipe( self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.proto.makeConnection(self) self._addPollableResource(_Reaper(self)) def signalProcess(self, signalID): if self.pid is None: raise error.ProcessExitedAlready() if signalID in ("INT", "TERM", "KILL"):
def __init__(self, reactor, protocol, command, args, environment, path): """ Create a new child process. """ _pollingfile._PollingTimer.__init__(self, reactor) BaseProcess.__init__(self, protocol) # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false currentPid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(currentPid, self.hStdoutR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStderrR, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(currentPid, self.hStdinW, currentPid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) newenv = {} for key, value in items(env): key = _fsdecode(key) value = _fsdecode(value) newenv[key] = value env = newenv # Make sure all the arguments are Unicode. args = [_fsdecode(x) for x in args] cmdline = quoteArguments(args) # The command, too, needs to be Unicode, if it is a value. command = _fsdecode(command) if command else command path = _fsdecode(path) if path else path # TODO: error detection here. See #2787 and #4184. def doCreate(): flags = win32con.CREATE_NO_WINDOW self.hProcess, self.hThread, self.pid, dwTid = win32process.CreateProcess( command, cmdline, None, None, 1, flags, env, path, StartupInfo) try: doCreate() except pywintypes.error as pwte: if not _invalidWin32App(pwte): # This behavior isn't _really_ documented, but let's make it # consistent with the behavior that is documented. raise OSError(pwte) else: # look for a shebang line. Insert the original 'command' # (actually a script) into the new arguments list. sheb = _findShebang(command) if sheb is None: raise OSError( "%r is neither a Windows executable, " "nor a script with a shebang line" % command) else: args = list(args) args.insert(0, command) cmdline = quoteArguments(args) origcmd = command command = sheb try: # Let's try again. doCreate() except pywintypes.error as pwte2: # d'oh, failed again! if _invalidWin32App(pwte2): raise OSError( "%r has an invalid shebang line: " "%r is not a valid executable" % ( origcmd, sheb)) raise OSError(pwte2) # close handles which only the child will use win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.proto.childDataReceived(1, data), self.outConnectionLost) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.proto.childDataReceived(2, data), self.errConnectionLost) self.stdin = _pollingfile._PollableWritePipe( self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.proto.makeConnection(self) self._addPollableResource(_Reaper(self))
self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.proto.childDataReceived(1, data), self.outConnectionLost) #Josh: added this so that stderr data isnt unexpected (causes a useless exception otherwise that we have no good way of handling) def got_data(data): self.proto.childDataReceived(2, data) self.proto.errReceived = self.proto.errReceivedIsGood self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, got_data, self.errConnectionLost) self.stdin = _pollingfile._PollableWritePipe( self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.proto.makeConnection(self) # (maybe?) a good idea in win32er, otherwise not # self.reactor.addEvent(self.hProcess, self, 'inConnectionLost') self._addPollableResource(twisted.internet._dumbwin32proc._Reaper(self)) #and finally, apply the monkeypatch: twisted.internet._dumbwin32proc.Process.__init__ = __new_init__
def __init__(self, reactor, protocol, command, args, environment, path): _pollingfile._PollingTimer.__init__(self, reactor) self.protocol = protocol # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false pid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(pid, self.hStdoutR, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(pid, self.hStderrR, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(pid, self.hStdinW, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) # create the process cmdline = ' '.join([cmdLineQuote(a) for a in args]) # TODO: error detection here. self.hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(command, cmdline, None, None, 1, 0, env, path, StartupInfo) win32file.CloseHandle(hThread) # close handles which only the child will use win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) self.closed = 0 self.closedNotifies = 0 # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.protocol.childDataReceived(1, data), self.outConnectionLost) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.protocol.childDataReceived(2, data), self.errConnectionLost) self.stdin = _pollingfile._PollableWritePipe( self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.protocol.makeConnection(self)
def __init__(self, reactor, protocol, command, args, environment, path): _pollingfile._PollingTimer.__init__(self, reactor) self.protocol = protocol # security attributes for pipes sAttrs = win32security.SECURITY_ATTRIBUTES() sAttrs.bInheritHandle = 1 # create the pipes which will connect to the secondary process self.hStdoutR, hStdoutW = win32pipe.CreatePipe(sAttrs, 0) self.hStderrR, hStderrW = win32pipe.CreatePipe(sAttrs, 0) hStdinR, self.hStdinW = win32pipe.CreatePipe(sAttrs, 0) win32pipe.SetNamedPipeHandleState(self.hStdinW, win32pipe.PIPE_NOWAIT, None, None) # set the info structure for the new process. StartupInfo = win32process.STARTUPINFO() StartupInfo.hStdOutput = hStdoutW StartupInfo.hStdError = hStderrW StartupInfo.hStdInput = hStdinR StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES # Create new handles whose inheritance property is false pid = win32api.GetCurrentProcess() tmp = win32api.DuplicateHandle(pid, self.hStdoutR, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdoutR) self.hStdoutR = tmp tmp = win32api.DuplicateHandle(pid, self.hStderrR, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStderrR) self.hStderrR = tmp tmp = win32api.DuplicateHandle(pid, self.hStdinW, pid, 0, 0, win32con.DUPLICATE_SAME_ACCESS) win32file.CloseHandle(self.hStdinW) self.hStdinW = tmp # Add the specified environment to the current environment - this is # necessary because certain operations are only supported on Windows # if certain environment variables are present. env = os.environ.copy() env.update(environment or {}) # create the process cmdline = ' '.join([cmdLineQuote(a) for a in args]) # TODO: error detection here. self.hProcess, hThread, dwPid, dwTid = win32process.CreateProcess( command, cmdline, None, None, 1, 0, env, path, StartupInfo) win32file.CloseHandle(hThread) # close handles which only the child will use win32file.CloseHandle(hStderrW) win32file.CloseHandle(hStdoutW) win32file.CloseHandle(hStdinR) self.closed = 0 self.closedNotifies = 0 # set up everything self.stdout = _pollingfile._PollableReadPipe( self.hStdoutR, lambda data: self.protocol.childDataReceived(1, data), self.outConnectionLost) self.stderr = _pollingfile._PollableReadPipe( self.hStderrR, lambda data: self.protocol.childDataReceived(2, data), self.errConnectionLost) self.stdin = _pollingfile._PollableWritePipe(self.hStdinW, self.inConnectionLost) for pipewatcher in self.stdout, self.stderr, self.stdin: self._addPollableResource(pipewatcher) # notify protocol self.protocol.makeConnection(self)