def buildReactor(self): """ Create and return a reactor using C{self.reactorFactory}. """ try: reactor = self.reactorFactory() except: # Unfortunately, not all errors which result in a reactor # being unusable are detectable without actually # instantiating the reactor. So we catch some more here # and skip the test if necessary. We also log it to aid # with debugging, but flush the logged error so the test # doesn't fail. log.err(None, "Failed to install reactor") self.flushLoggedErrors() raise SkipTest(Failure().getErrorMessage()) else: if self.requiredInterface is not None: if not self.requiredInterface.providedBy(reactor): self.unbuildReactor(reactor) raise SkipTest( "%r does not provide %r" % ( reactor, self.requiredInterface)) self.addCleanup(self.unbuildReactor, reactor) return reactor
def _doReadOrWrite(self, selectable, fd, event): """ fd is available for read or write, make the work and raise errors if necessary. """ why = None inRead = False if event & _POLL_DISCONNECTED and not (event & _epoll.IN): if fd in self._reads: inRead = True why = CONNECTION_DONE else: why = CONNECTION_LOST else: try: if event & _epoll.IN: why = selectable.doRead() inRead = True if not why and event & _epoll.OUT: why = selectable.doWrite() inRead = False if selectable.fileno() != fd: why = error.ConnectionFdescWentAway( 'Filedescriptor went away') inRead = False except: log.err() why = sys.exc_info()[1] if why: self._disconnectSelectable(selectable, why, inRead)
def registerMany(results): for success, result in results: if success: chatui.registerAccountClient(result) self._cb_logOn(result) else: log.err(result)
def cmd_ERROR(self): """ An non-existent command has been sent. """ log.err("Non-existent command sent.") cmd = self._current.popleft() cmd.fail(NoSuchCommand())
def callback(self, *args, **kwargs): """ Call all registered callbacks. The passed arguments are event specific and augment and override the callback specific arguments as described above. @note: Exceptions raised by callbacks are trapped and logged. They will not propagate up to make sure other callbacks will still be called, and the event dispatching allways succeeds. @param args: Positional arguments to the callable. @type args: C{list} @param kwargs: Keyword arguments to the callable. @type kwargs: C{dict} """ for key, (methodwrapper, onetime) in self.callbacks.items(): try: methodwrapper(*args, **kwargs) except: log.err() if onetime: del self.callbacks[key]
def cmd_CLIENT_ERROR(self, errText): """ An invalid input as been sent. """ log.err("Invalid input: %s" % (errText, )) cmd = self._current.popleft() cmd.fail(ClientError(errText))
def cmd_SERVER_ERROR(self, errText): """ An error has happened server-side. """ log.err("Server error: %s" % (errText,)) cmd = self._current.popleft() cmd.fail(ServerError(errText))
def reapProcess(self): """ Try to reap a process (without blocking) via waitpid. This is called when sigchild is caught or a Process object loses its "connection" (stdout is closed) This ought to result in reaping all zombie processes, since it will be called twice as often as it needs to be. (Unfortunately, this is a slightly experimental approach, since UNIX has no way to be really sure that your process is going to go away w/o blocking. I don't want to block.) """ try: try: pid, status = os.waitpid(self.pid, os.WNOHANG) except OSError, e: if e.errno == errno.ECHILD: # no child process pid = None else: raise except: log.msg('Failed to reap %d:' % self.pid) log.err() pid = None if pid: self.processEnded(status) unregisterReapProcessHandler(pid, self)
def cmd_SERVER_ERROR(self, errText): """ An error has happened server-side. """ log.err("Server error: %s" % (errText, )) cmd = self._current.popleft() cmd.fail(ServerError(errText))
def cmd_CLIENT_ERROR(self, errText): """ An invalid input as been sent. """ log.err("Invalid input: %s" % (errText,)) cmd = self._current.popleft() cmd.fail(ClientError(errText))
def _ebLookup(self, failure, sport, cport): if failure.check(IdentError): self.sendLine('%d, %d : ERROR : %s' % (sport, cport, failure.value)) else: log.err(failure) self.sendLine('%d, %d : ERROR : %s' % (sport, cport, IdentError(failure.value)))
def connectionLost(self, reason): """ Release the inotify file descriptor and do the necessary cleanup """ FileDescriptor.connectionLost(self, reason) if self._fd >= 0: try: os.close(self._fd) except OSError, e: log.err(e, "Couldn't close INotify file descriptor.")
def readConnectionLost(self, reason): p = interfaces.IHalfCloseableProtocol(self.protocol, None) if p: try: p.readConnectionLost() except: log.err() self.connectionLost(failure.Failure()) else: self.connectionLost(reason)
def childConnectionLost(self, childFD, reason): # this is called when one of the helpers (ProcessReader or # ProcessWriter) notices their pipe has been closed os.close(self.pipes[childFD].fileno()) del self.pipes[childFD] try: self.proto.childConnectionLost(childFD) except: log.err() self.maybeCallProcessEnded()
def maybeCallProcessEnded(self): """ Call processEnded on protocol after final cleanup. """ if self.proto is not None: reason = self._getReason(self.status) proto = self.proto self.proto = None try: proto.processEnded(Failure(reason)) except: err(None, "unexpected error in processEnded")
def run(self, installSignalHandlers=True): """ Start the reactor. """ self._postQueue = Queue.Queue() if not hasattr(self, "wxapp"): log.msg("registerWxApp() was not called on reactor, " "registering my own wxApp instance.") self.registerWxApp(wxPySimpleApp()) # start select() thread: self.interleave(self._runInMainThread, installSignalHandlers=installSignalHandlers) if installSignalHandlers: self.callLater(0, self._installSignalHandlersAgain) # add cleanup events: self.addSystemEventTrigger("after", "shutdown", self._stopWx) self.addSystemEventTrigger("after", "shutdown", lambda: self._postQueue.put(None)) # On Mac OS X, work around wx bug by starting timer to ensure # wxCallAfter calls are always processed. We don't wake up as # often as we could since that uses too much CPU. if runtime.platform.isMacOSX(): t = ProcessEventsTimer(self.wxapp) t.Start(2) # wake up every 2ms self.wxapp.MainLoop() wxapp = self.wxapp del self.wxapp if not self._stopping: # wx event loop exited without reactor.stop() being # called. At this point events from select() thread will # be added to _postQueue, but some may still be waiting # unprocessed in wx, thus the ProcessPendingEvents() # below. self.stop() wxapp.ProcessPendingEvents() # deal with any queued wxCallAfters while 1: try: f = self._postQueue.get(timeout=0.01) except Queue.Empty: continue else: if f is None: break try: f() except: log.err()
def _continueFiring(self, ignored): """ Call the during and after phase triggers for this event. """ self.state = 'BASE' self.finishedBefore = [] for phase in self.during, self.after: while phase: callable, args, kwargs = phase.pop(0) try: callable(*args, **kwargs) except: log.err()
def _writeConnectionLost(self, reason): self._writer=None if self.disconnecting: self.connectionLost(reason) return p = interfaces.IHalfCloseableProtocol(self.protocol, None) if p: try: p.writeConnectionLost() except: log.err() self.connectionLost(failure.Failure())
def __del__(self): """ Print tracebacks and die. If the *last* (and I do mean *last*) callback leaves me in an error state, print a traceback (if said errback is a L{Failure}). """ if self.failResult is not None: log.msg("Unhandled error in Deferred:", isError=True) debugInfo = self._getDebugTracebacks() if debugInfo != '': log.msg("(debug: " + debugInfo + ")", isError=True) log.err(self.failResult)
def _closeWriteConnection(self): try: getattr(self.socket, self._socketShutdownMethod)(1) except socket.error: pass p = interfaces.IHalfCloseableProtocol(self.protocol, None) if p: try: p.writeConnectionLost() except: f = failure.Failure() log.err() self.connectionLost(f)
def _doReadOrWrite(self, selectable, method, dict): try: why = getattr(selectable, method)() handfn = getattr(selectable, 'fileno', None) if not handfn: why = _NO_FILENO elif handfn() == -1: why = _NO_FILEDESC except: why = sys.exc_info()[1] log.err() if why: self._disconnectSelectable(selectable, why, method=="doRead")
def _writeConnectionLost(self, reason): self._writer = None if self.disconnecting: self.connectionLost(reason) return p = interfaces.IHalfCloseableProtocol(self.protocol, None) if p: try: p.writeConnectionLost() except: log.err() self.connectionLost(failure.Failure())
def _finishReadOrWrite(self, fn, faildict=_faildict): try: why = fn() except: why = sys.exc_info()[1] log.err() if why: try: f = faildict.get(why.__class__) or failure.Failure(why) self.objConnectionLost(f) except: log.err() if self.reactor.running: self.reactor.simulate()
def handleRead(self, rc, bytes, evt): if rc in (errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE): if self._connectedAddr: self.protocol.connectionRefused() elif rc: log.msg("error in recvfrom -- %s (%s)" % (errno.errorcode.get(rc, 'unknown error'), rc)) else: try: self.protocol.datagramReceived(str(evt.buff[:bytes]), _iocp.makesockaddr(evt.addr_buff)) except: log.err()
def handleRead(self, rc, bytes, evt): if rc in (errno.WSAECONNREFUSED, errno.WSAECONNRESET, ERROR_CONNECTION_REFUSED, ERROR_PORT_UNREACHABLE): if self._connectedAddr: self.protocol.connectionRefused() elif rc: log.msg("error in recvfrom -- %s (%s)" % (errno.errorcode.get(rc, 'unknown error'), rc)) else: try: self.protocol.datagramReceived( str(evt.buff[:bytes]), _iocp.makesockaddr(evt.addr_buff)) except: log.err()
def mainLoop(self): while self._started: try: while self._started: # Advance simulation time in delayed event # processors. self.runUntilCurrent() t2 = self.timeout() t = self.running and t2 self.doIteration(t) except: log.msg("Unexpected error in main loop.") log.err() else: log.msg('Main loop terminated.')
def __init__(self, reactor, executable, args, environment, path, proto, uid=None, gid=None, usePTY=None): """ Spawn an operating-system process. This is where the hard work of disconnecting all currently open files / forking / executing the new process happens. (This is executed automatically when a Process is instantiated.) This will also run the subprocess as a given user ID and group ID, if specified. (Implementation Note: this doesn't support all the arcane nuances of setXXuid on UNIX: it will assume that either your effective or real UID is 0.) """ if pty is None and not isinstance(usePTY, (tuple, list)): # no pty module and we didn't get a pty to use raise NotImplementedError( "cannot use PTYProcess on platforms without the pty module.") abstract.FileDescriptor.__init__(self, reactor) _BaseProcess.__init__(self, proto) if isinstance(usePTY, (tuple, list)): masterfd, slavefd, ttyname = usePTY else: masterfd, slavefd = pty.openpty() ttyname = os.ttyname(slavefd) try: self._fork(path, uid, gid, executable, args, environment, masterfd=masterfd, slavefd=slavefd) except: if not isinstance(usePTY, (tuple, list)): os.close(masterfd) os.close(slavefd) raise # we are now in parent process: os.close(slavefd) fdesc.setNonBlocking(masterfd) self.fd = masterfd self.startReading() self.connected = 1 self.status = -1 try: self.proto.makeConnection(self) except: log.err() registerReapProcessHandler(self.pid, self)
def _callEventCallback(self, rc, bytes, evt): owner = evt.owner why = None try: evt.callback(rc, bytes, evt) handfn = getattr(owner, 'getFileHandle', None) if not handfn: why = _NO_GETHANDLE elif handfn() == -1: why = _NO_FILEDESC if why: return # ignore handles that were closed except: why = sys.exc_info()[1] log.err() if why: owner.loseConnection(failure.Failure(why))
def fireEvent(self): """ Call the triggers added to this event. """ self.state = 'BEFORE' self.finishedBefore = [] beforeResults = [] while self.before: callable, args, kwargs = self.before.pop(0) self.finishedBefore.append((callable, args, kwargs)) try: result = callable(*args, **kwargs) except: log.err() else: if isinstance(result, Deferred): beforeResults.append(result) DeferredList(beforeResults).addCallback(self._continueFiring)
def _ebLogin(self, err, nickname): if err.check(ewords.AlreadyLoggedIn): self.privmsg( NICKSERV, nickname, "Already logged in. No pod people allowed!") elif err.check(ecred.UnauthorizedLogin): self.privmsg( NICKSERV, nickname, "Login failed. Goodbye.") else: log.msg("Unhandled error during login:"******"Server error during login. Sorry.") self.transport.loseConnection()
def login(self, message, host, port): parts = message.headers['authorization'][0].split(None, 1) a = self.authorizers.get(parts[0].lower()) if a: try: c = a.decode(parts[1]) except SIPError: raise except: log.err() self.deliverResponse(self.responseFromRequest(500, message)) else: c.username += '@' + self.host self.portal.login(c, None, IContact).addCallback( self._cbLogin, message, host, port).addErrback(self._ebLogin, message, host, port).addErrback(log.err) else: self.deliverResponse(self.responseFromRequest(501, message))
def login(self, message, host, port): parts = message.headers['authorization'][0].split(None, 1) a = self.authorizers.get(parts[0].lower()) if a: try: c = a.decode(parts[1]) except SIPError: raise except: log.err() self.deliverResponse(self.responseFromRequest(500, message)) else: c.username += '@' + self.host self.portal.login(c, None, IContact ).addCallback(self._cbLogin, message, host, port ).addErrback(self._ebLogin, message, host, port ).addErrback(log.err ) else: self.deliverResponse(self.responseFromRequest(501, message))
def connectionLost(self, reason): self.disconnected = True # Make sure to cleanup the other half _reader = self._reader _writer = self._writer protocol = self.protocol self._reader = self._writer = None self.protocol = None if _writer is not None and not _writer.disconnected: _writer.connectionLost(reason) if _reader is not None and not _reader.disconnected: _reader.connectionLost(reason) try: protocol.connectionLost(reason) except: log.err()
def registerReapProcessHandler(pid, process): """ Register a process handler for the given pid, in case L{reapAllProcesses} is called. @param pid: the pid of the process. @param process: a process handler. """ if pid in reapProcessHandlers: raise RuntimeError("Try to register an already registered process.") try: auxPID, status = os.waitpid(pid, os.WNOHANG) except: log.msg('Failed to reap %d:' % pid) log.err() auxPID = None if auxPID: process.processEnded(status) else: # if auxPID is 0, there are children but none have exited reapProcessHandlers[pid] = process
def doSelect(self, timeout): """ Run one iteration of the I/O monitor loop. This will run all selectables who had input or output readiness waiting for them. """ while 1: try: r, w, ignored = _select(self._reads.keys(), self._writes.keys(), [], timeout) break except ValueError, ve: # Possibly a file descriptor has gone negative? log.err() self._preenDescriptors() except TypeError, te: # Something *totally* invalid (object w/o fileno, non-integral # result) was passed log.err() self._preenDescriptors()
def doRead(self): if self.disconnected: # See the comment in the similar check in doWrite below. # Additionally, in order for anything other than returning # CONNECTION_DONE here to make sense, it will probably be necessary # to implement a way to switch back to TCP from TLS (actually, if # we did something other than return CONNECTION_DONE, that would be # a big part of implementing that feature). In other words, the # expectation is that doRead will be called when self.disconnected # is True only when the connection has been lost. It's possible # that the other end could stop speaking TLS and then send us some # non-TLS data. We'll end up ignoring that data and dropping the # connection. There's no unit tests for this check in the cases # where it makes a difference. The test suite only hits this # codepath when it would have otherwise hit the SSL.ZeroReturnError # exception handler below, which has exactly the same behavior as # this conditional. Maybe that's the only case that can ever be # triggered, I'm not sure. -exarkun return main.CONNECTION_DONE if self.writeBlockedOnRead: self.writeBlockedOnRead = 0 self._resetReadWrite() try: return Connection.doRead(self) except SSL.ZeroReturnError: return main.CONNECTION_DONE except SSL.WantReadError: return except SSL.WantWriteError: self.readBlockedOnWrite = 1 Connection.startWriting(self) Connection.stopReading(self) return except SSL.SysCallError, (retval, desc): if ((retval == -1 and desc == 'Unexpected EOF') or retval > 0): return main.CONNECTION_LOST log.err() return main.CONNECTION_LOST
def getPlugins(interface, package=None): """ Retrieve all plugins implementing the given interface beneath the given module. @param interface: An interface class. Only plugins which implement this interface will be returned. @param package: A package beneath which plugins are installed. For most uses, the default value is correct. @return: An iterator of plugins. """ if package is None: import reqs.twisted.plugins as package allDropins = getCache(package) for dropin in allDropins.itervalues(): for plugin in dropin.plugins: try: adapted = interface(plugin, None) except: log.err() else: if adapted is not None: yield adapted
def doRead(self): """ Called when my socket is ready for reading. """ read = 0 while read < self.maxThroughput: try: data, addr = self.socket.recvfrom(self.maxPacketSize) except socket.error, se: no = se.args[0] if no in (EAGAIN, EINTR, EWOULDBLOCK): return if (no == ECONNREFUSED) or (platformType == "win32" and no == WSAECONNRESET): if self._connectedAddr: self.protocol.connectionRefused() else: raise else: read += len(data) try: self.protocol.datagramReceived(data, addr) except: log.err()
def buildReactor(self): """ Create and return a reactor using C{self.reactorFactory}. """ try: reactor = self.reactorFactory() except: # Unfortunately, not all errors which result in a reactor # being unusable are detectable without actually # instantiating the reactor. So we catch some more here # and skip the test if necessary. We also log it to aid # with debugging, but flush the logged error so the test # doesn't fail. log.err(None, "Failed to install reactor") self.flushLoggedErrors() raise SkipTest(Failure().getErrorMessage()) else: if self.requiredInterface is not None: if not self.requiredInterface.providedBy(reactor): self.unbuildReactor(reactor) raise SkipTest("%r does not provide %r" % (reactor, self.requiredInterface)) self.addCleanup(self.unbuildReactor, reactor) return reactor