twisted.python.runtime.platform.isWindows

Here are the examples of the python api twisted.python.runtime.platform.isWindows taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

26 Examples 7

Example 1

Project: mythbox Source File: filepath.py
Function: child
    def child(self, path):
        if platform.isWindows() and path.count(":"):
            # Catch paths like C:blah that don't have a slash
            raise InsecurePath("%r contains a colon." % (path,))
        norm = normpath(path)
        if slash in norm:
            raise InsecurePath("%r contains one or more directory separators" % (path,))
        newpath = abspath(joinpath(self.path, norm))
        if not newpath.startswith(self.path):
            raise InsecurePath("%r is not a child of %s" % (newpath, self.path))
        return self.clonePath(newpath)

Example 2

Project: mythbox Source File: test_logfile.py
    def test_specifiedPermissions(self):
        """
        Test specifying the permissions used on the log file.
        """
        log1 = logfile.LogFile(self.name, self.dir, defaultMode=0066)
        mode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
        if runtime.platform.isWindows():
            # The only thing we can get here is global read-only
            self.assertEquals(mode, 0444)
        else:
            self.assertEquals(mode, 0066)

Example 3

Project: TwistedBot Source File: filepath.py
Function: getinodenumber
    def getInodeNumber(self):
        """
        Retrieve the file serial number, also called inode number, which
        distinguishes this file from all other files on the same device.

        @raise: NotImplementedError if the platform is Windows, since the
                inode number would be a dummy value for all files in Windows
        @return: a number representing the file serial number
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return st.st_ino

Example 4

Project: TwistedBot Source File: filepath.py
Function: get_user_id
    def getUserID(self):
        """
        Returns the user ID of the file's owner.

        @raise: NotImplementedError if the platform is Windows, since the UID
                is always 0 on Windows
        @return: the user ID of the file's owner
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return st.st_uid

Example 5

Project: TwistedBot Source File: filepath.py
Function: get_group_id
    def getGroupID(self):
        """
        Returns the group ID of the file.

        @raise: NotImplementedError if the platform is Windows, since the GID
                is always 0 on windows
        @return: the group ID of the file
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return st.st_gid

Example 6

Project: SubliminalCollaborator Source File: reactormixins.py
Function: set_up
    def setUp(self):
        """
        Clear the SIGCHLD handler, if there is one, to ensure an environment
        like the one which exists prior to a call to L{reactor.run}.
        """
        if not platform.isWindows():
            self.originalHandler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)

Example 7

Project: SubliminalCollaborator Source File: filepath.py
Function: getinodenumber
    def getInodeNumber(self):
        """
        Retrieve the file serial number, also called inode number, which
        distinguishes this file from all other files on the same device.

        @raise: NotImplementedError if the platform is Windows, since the
                inode number would be a dummy value for all files in Windows
        @return: a number representing the file serial number
        @rtype: C{long}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return long(st.st_ino)

Example 8

Project: SubliminalCollaborator Source File: filepath.py
Function: get_user_id
    def getUserID(self):
        """
        Returns the user ID of the file's owner.

        @raise: NotImplementedError if the platform is Windows, since the UID
                is always 0 on Windows
        @return: the user ID of the file's owner
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return int(st.st_uid)

Example 9

Project: SubliminalCollaborator Source File: filepath.py
Function: get_group_id
    def getGroupID(self):
        """
        Returns the group ID of the file.

        @raise: NotImplementedError if the platform is Windows, since the GID
                is always 0 on windows
        @return: the group ID of the file
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return int(st.st_gid)

Example 10

Project: SubliminalCollaborator Source File: test_logfile.py
    def test_specifiedPermissions(self):
        """
        Test specifying the permissions used on the log file.
        """
        log1 = logfile.LogFile(self.name, self.dir, defaultMode=0066)
        mode = stat.S_IMODE(os.stat(self.path)[stat.ST_MODE])
        if runtime.platform.isWindows():
            # The only thing we can get here is global read-only
            self.assertEqual(mode, 0444)
        else:
            self.assertEqual(mode, 0066)

Example 11

Project: foolscap Source File: services.py
Function: remote_putfile
    def remote_putfile(self, name, source):
        #if "/" in name or name == "..":
        #    raise BadFilenameError()
        #targetfile = os.path.join(self.options.targetdir, name)

        # I think that .child() will reject attempts to follow symlinks out
        # of the target directory. It will also reject the use of
        # subdirectories: 'name' must not contain any slashes. To implement
        # allow-subdirectories, we should pass a list of dirnames and handle
        # it specially.
        targetfile = self.targetdir.child(name)

        #tmpfile = targetfile.temporarySibling()
        #
        # temporarySibling() creates a tempfile with the same extension as
        # the targetfile, which is useless for our purposes: one goal of
        # file-uploader is to let you send .deb packages to an APT
        # repository, and we need to hide the .deb from the package-index
        # building scripts until the whole file is present, so we want an
        # atomic rename from foo.deb.partial to foo.deb

        tmpfile = targetfile.siblingExtension(".partial")

        # TODO: use os.open and set the file mode earlier
        #f = open(tmpfile, "w")
        f = tmpfile.open("w")
        reader = FileUploaderReader(f, source)
        d = reader.read_file()
        def _done(res):
            f.close()
            if runtime.platform.isWindows() and targetfile.exists():
                os.unlink(targetfile.path)
            tmpfile.moveTo(targetfile)
            #targetfile.chmod(self.options["mode"])
            # older Twisteds do not have FilePath.chmod
            os.chmod(targetfile.path, self.options["mode"])
            return None
        def _err(fail):
            f.close()
            os.unlink(tmpfile.path)
            return fail
        d.addCallbacks(_done, _err)
        return d

Example 12

Project: crossbar Source File: process.py
    def _start_native_worker(self, wtype, id, options=None, details=None):

        assert(wtype in ['router', 'container', 'websocket-testee'])

        # prohibit starting a worker twice
        #
        if id in self._workers:
            emsg = "Could not start worker: a worker with ID '{}' is already running (or starting)".format(id)
            self.log.error(emsg)
            raise ApplicationError(u'crossbar.error.worker_already_running', emsg)

        # check worker options
        #
        options = options or {}
        try:
            if wtype == 'router':
                checkconfig.check_router_options(options)
            elif wtype == 'container':
                checkconfig.check_container_options(options)
            elif wtype == 'websocket-testee':
                checkconfig.check_websocket_testee_options(options)
            else:
                raise Exception("logic error")
        except Exception as e:
            emsg = "Could not start native worker: invalid configuration ({})".format(e)
            self.log.error(emsg)
            raise ApplicationError(u'crossbar.error.invalid_configuration', emsg)

        # allow override Python executable from options
        #
        if 'python' in options:
            exe = options['python']

            # the executable must be an absolute path, e.g. /home/oberstet/pypy-2.2.1-linux64/bin/pypy
            #
            if not os.path.isabs(exe):
                emsg = "Invalid worker configuration: python executable '{}' must be an absolute path".format(exe)
                self.log.error(emsg)
                raise ApplicationError(u'crossbar.error.invalid_configuration', emsg)

            # of course the path must exist and actually be executable
            #
            if not (os.path.isfile(exe) and os.access(exe, os.X_OK)):
                emsg = "Invalid worker configuration: python executable '{}' does not exist or isn't an executable".format(exe)
                self.log.error(emsg)
                raise ApplicationError(u'crossbar.error.invalid_configuration', emsg)
        else:
            exe = sys.executable

        # assemble command line for forking the worker
        #
        # all native workers (routers and containers for now) start
        # from the same script in crossbar/worker/process.py -- we're
        # invoking via "-m" so that .pyc files, __pycache__ etc work
        # properly.

        args = [exe, "-u", "-m", "crossbar.worker.process"]
        args.extend(["--cbdir", self._node._cbdir])
        args.extend(["--worker", str(id)])
        args.extend(["--realm", self._realm])
        args.extend(["--type", wtype])
        args.extend(["--loglevel", get_global_log_level()])

        # allow override worker process title from options
        #
        if options.get('title', None):
            args.extend(['--title', options['title']])

        # forward explicit reactor selection
        #
        if 'reactor' in options and sys.platform in options['reactor']:
            args.extend(['--reactor', options['reactor'][sys.platform]])
        # FIXME
        # elif self._node.options.reactor:
        #    args.extend(['--reactor', self._node.options.reactor])

        # create worker process environment
        #
        worker_env = create_process_env(options)

        # We need to use the same PYTHONPATH we were started with, so we can
        # find the Crossbar we're working with -- it may not be the same as the
        # one on the default path
        worker_env["PYTHONPATH"] = os.pathsep.join(sys.path)

        # log name of worker
        #
        worker_logname = {
            'router': 'Router',
            'container': 'Container',
            'websocket-testee': 'WebSocketTestee'
        }.get(wtype, 'Worker')

        # topic URIs used (later)
        #
        if wtype == 'router':
            starting_topic = 'crossbar.node.on_router_starting'
            started_topic = 'crossbar.node.on_router_started'
        elif wtype == 'container':
            starting_topic = 'crossbar.node.on_container_starting'
            started_topic = 'crossbar.node.on_container_started'
        elif wtype == 'websocket-testee':
            starting_topic = 'crossbar.node.on_websocket_testee_starting'
            started_topic = 'crossbar.node.on_websocket_testee_started'
        else:
            raise Exception("logic error")

        # add worker tracking instance to the worker map ..
        #
        if wtype == 'router':
            worker = RouterWorkerProcess(self, id, details.caller, keeplog=options.get('traceback', None))
        elif wtype == 'container':
            worker = ContainerWorkerProcess(self, id, details.caller, keeplog=options.get('traceback', None))
        elif wtype == 'websocket-testee':
            worker = WebSocketTesteeWorkerProcess(self, id, details.caller, keeplog=options.get('traceback', None))
        else:
            raise Exception("logic error")

        self._workers[id] = worker

        # create a (custom) process endpoint.
        #
        if platform.isWindows():
            childFDs = None  # Use the default Twisted ones
        else:
            # The communication between controller and container workers is
            # using WAMP running over 2 pipes.
            # For controller->container traffic this runs over FD 0 (`stdin`)
            # and for the container->controller traffic, this runs over FD 3.
            #
            # Note: We use FD 3, not FD 1 (`stdout`) or FD 2 (`stderr`) for
            # container->controller traffic, so that components running in the
            # container which happen to write to `stdout` or `stderr` do not
            # interfere with the container-controller communication.
            childFDs = {0: "w", 1: "r", 2: "r", 3: "r"}

        ep = WorkerProcessEndpoint(
            self._node._reactor, exe, args, env=worker_env, worker=worker,
            childFDs=childFDs)

        # ready handling
        #
        def on_ready_success(id):
            self.log.info("{worker} with ID '{id}' and PID {pid} started",
                          worker=worker_logname, id=worker.id, pid=worker.pid)

            self._node._reactor.addSystemEventTrigger(
                'before', 'shutdown',
                self._cleanup_worker, self._node._reactor, worker,
            )

            worker.status = 'started'
            worker.started = datetime.utcnow()

            started_info = {
                u'id': worker.id,
                u'status': worker.status,
                u'started': utcstr(worker.started),
                u'who': worker.who,
            }

            # FIXME: make start of stats printer dependent on log level ..
            worker.log_stats(5.)

            self.publish(started_topic, started_info, options=PublishOptions(exclude=details.caller))

            return started_info

        def on_ready_error(err):
            del self._workers[worker.id]
            emsg = 'Failed to start native worker: {}'.format(err.value)
            self.log.error(emsg)
            raise ApplicationError(u"crossbar.error.cannot_start", emsg, worker.getlog())

        worker.ready.addCallbacks(on_ready_success, on_ready_error)

        def on_exit_success(_):
            self.log.info("Node worker {worker.id} ended successfully", worker=worker)
            worker.log_stats(0)
            del self._workers[worker.id]
            return True

        def on_exit_error(err):
            self.log.info("Node worker {worker.id} ended with error ({err})", worker=worker, err=err)
            worker.log_stats(0)
            del self._workers[worker.id]
            return False

        def check_for_shutdown(was_successful):
            shutdown = False

            # automatically shutdown node whenever a worker ended (successfully, or with error)
            #
            if checkconfig.NODE_SHUTDOWN_ON_WORKER_EXIT in self._node._node_shutdown_triggers:
                self.log.info("Node worker ended, and trigger '{trigger}' active", trigger=checkconfig.NODE_SHUTDOWN_ON_WORKER_EXIT)
                shutdown = True

            # automatically shutdown node when worker ended with error
            #
            if not was_successful and checkconfig.NODE_SHUTDOWN_ON_WORKER_EXIT_WITH_ERROR in self._node._node_shutdown_triggers:
                self.log.info("Node worker ended with error, and trigger '{trigger}' active", trigger=checkconfig.NODE_SHUTDOWN_ON_WORKER_EXIT_WITH_ERROR)
                shutdown = True

            # automatically shutdown node when no more workers are left
            #
            if len(self._workers) == 0 and checkconfig.NODE_SHUTDOWN_ON_LAST_WORKER_EXIT in self._node._node_shutdown_triggers:
                self.log.info("No more node workers running, and trigger '{trigger}' active", trigger=checkconfig.NODE_SHUTDOWN_ON_LAST_WORKER_EXIT)
                shutdown = True

            # initiate shutdown (but only if we are not already shutting down)
            #
            if shutdown:
                if not self._shutdown_requested:
                    self.log.info("Node shutting down ..")
                    self.shutdown()
                else:
                    # ignore: shutdown already initiated ..
                    self.log.info("Node is already shutting down.")
            else:
                self.log.info(
                    "Node will continue to run (node shutdown triggers active: {triggers})",
                    triggers=self._node._node_shutdown_triggers,
                )

        d_on_exit = worker.exit.addCallbacks(on_exit_success, on_exit_error)
        d_on_exit.addBoth(check_for_shutdown)

        # create a transport factory for talking WAMP to the native worker
        #
        transport_factory = create_native_worker_client_factory(self._node._router_session_factory, worker.ready, worker.exit)
        transport_factory.noisy = False
        self._workers[id].factory = transport_factory

        # now (immediately before actually forking) signal the starting of the worker
        #
        starting_info = {
            u'id': id,
            u'status': worker.status,
            u'created': utcstr(worker.created),
            u'who': worker.who,
        }

        # the caller gets a progressive result ..
        if details.progress:
            details.progress(starting_info)

        # .. while all others get an event
        self.publish(starting_topic, starting_info, options=PublishOptions(exclude=details.caller))

        # now actually fork the worker ..
        #
        self.log.info("Starting {worker} with ID '{id}'...",
                      worker=worker_logname, id=id)
        self.log.debug("{worker} '{id}' command line is '{cmdline}'",
                       worker=worker_logname, id=id, cmdline=' '.join(args))

        d = ep.connect(transport_factory)

        def on_connect_success(proto):

            # this seems to be called immediately when the child process
            # has been forked. even if it then immediately fails because
            # e.g. the executable doesn't even exist. in other words,
            # I'm not sure under what conditions the deferred will errback ..

            pid = proto.transport.pid
            self.log.debug("Native worker process connected with PID {pid}",
                           pid=pid)

            # note the PID of the worker
            worker.pid = pid

            # proto is an instance of NativeWorkerClientProtocol
            worker.proto = proto

            worker.status = 'connected'
            worker.connected = datetime.utcnow()

        def on_connect_error(err):

            # not sure when this errback is triggered at all ..
            self.log.error("Interal error: connection to forked native worker failed ({err})", err=err)

            # in any case, forward the error ..
            worker.ready.errback(err)

        d.addCallbacks(on_connect_success, on_connect_error)

        return worker.ready

Example 13

Project: crossbar Source File: processtypes.py
    def __init__(self, controller, id, who, keeplog=None):
        """
        Ctor.

        :param controller: The node controller this worker was created by.
        :type controller: instance of NodeControllerSession
        :param id: The ID of the worker.
        :type id: str
        :param who: Who triggered creation of this worker.
        :type who: str
        :param keeplog: If not `None`, buffer log message received to be later
                        retrieved via getlog(). If `0`, keep infinite log internally.
                        If `> 0`, keep at most such many log entries in buffer.
        :type keeplog: int or None
        """
        self._logger = make_logger()

        self._controller = controller

        self.id = id
        self.who = who
        self.pid = None
        self.status = "starting"

        self.created = datetime.utcnow()
        self.connected = None
        self.started = None

        self._log_entries = deque(maxlen=10)

        if platform.isWindows():
            self._log_fds = [2]
        else:
            self._log_fds = [1, 2]
        self._log_lineno = 0
        self._log_topic = u'crossbar.worker.{}.on_log'.format(self.id)

        self._log_rich = None  # Does not support rich logs

        # track stats for worker->controller traffic
        self._stats = {}
        self._stats_printer = None

        # A deferred that resolves when the worker is ready.
        self.ready = Deferred()

        # A deferred that resolves when the worker has exited.
        self.exit = Deferred()
        self.exit.addBoth(self._dump_remaining_log)

Example 14

Project: mythbox Source File: test_process.py
    def test_processExitedWithSignal(self):
        """
        The C{reason} argument passed to L{IProcessProtocol.processExited} is a
        L{ProcessTerminated} instance if the child process exits with a signal.
        """
        sigName = 'TERM'
        sigNum = getattr(signal, 'SIG' + sigName)
        exited = Deferred()
        source = (
            "import sys\n"
            # Talk so the parent process knows the process is running.  This is
            # necessary because ProcessProtocol.makeConnection may be called
            # before this process is exec'd.  It would be unfortunate if we
            # SIGTERM'd the Twisted process while it was on its way to doing
            # the exec.
            "sys.stdout.write('x')\n"
            "sys.stdout.flush()\n"
            "sys.stdin.read()\n")

        class Exiter(ProcessProtocol):
            def childDataReceived(self, fd, data):
                msg('childDataReceived(%d, %r)' % (fd, data))
                self.transport.signalProcess(sigName)

            def childConnectionLost(self, fd):
                msg('childConnectionLost(%d)' % (fd,))

            def processExited(self, reason):
                msg('processExited(%r)' % (reason,))
                # Protect the Deferred from the failure so that it follows
                # the callback chain.  This doesn't use the errback chain
                # because it wants to make sure reason is a Failure.  An
                # Exception would also make an errback-based test pass, and
                # that would be wrong.
                exited.callback([reason])

            def processEnded(self, reason):
                msg('processEnded(%r)' % (reason,))

        reactor = self.buildReactor()
        reactor.callWhenRunning(
            reactor.spawnProcess, Exiter(), sys.executable,
            [sys.executable, "-c", source], usePTY=self.usePTY)

        def cbExited((failure,)):
            # Trapping implicitly verifies that it's a Failure (rather than
            # an exception) and explicitly makes sure it's the right type.
            failure.trap(ProcessTerminated)
            err = failure.value
            if platform.isWindows():
                # Windows can't really /have/ signals, so it certainly can't
                # report them as the reason for termination.  Maybe there's
                # something better we could be doing here, anyway?  Hard to
                # say.  Anyway, this inconsistency between different platforms
                # is extremely unfortunate and I would remove it if I
                # could. -exarkun
                self.assertIdentical(err.signal, None)
                self.assertEqual(err.exitCode, 1)
            else:
                self.assertEqual(err.signal, sigNum)
                self.assertIdentical(err.exitCode, None)

Example 15

Project: mythbox Source File: filepath.py
Function: set_content
    def setContent(self, content, ext='.new'):
        """
        Replace the file at this path with a new file that contains the given
        bytes, trying to avoid data-loss in the meanwhile.

        On UNIX-like platforms, this method does its best to ensure that by the
        time this method returns, either the old contents I{or} the new contents
        of the file will be present at this path for subsequent readers
        regardless of premature device removal, program crash, or power loss,
        making the following assumptions:

            - your filesystem is journaled (i.e. your filesystem will not
              I{itself} lose data due to power loss)

            - your filesystem's C{rename()} is atomic

            - your filesystem will not discard new data while preserving new
              metadata (see U{http://mjg59.livejournal.com/108257.html} for more
              detail)

        On most versions of Windows there is no atomic C{rename()} (see
        U{http://bit.ly/win32-overwrite} for more information), so this method
        is slightly less helpful.  There is a small window where the file at
        this path may be deleted before the new file is moved to replace it:
        however, the new file will be fully written and flushed beforehand so in
        the unlikely event that there is a crash at that point, it should be
        possible for the user to manually recover the new version of their data.
        In the future, Twisted will support atomic file moves on those versions
        of Windows which I{do} support them: see U{Twisted ticket
        3004<http://twistedmatrix.com/trac/ticket/3004>}.

        This method should be safe for use by multiple concurrent processes, but
        note that it is not easy to predict which process's contents will
        ultimately end up on disk if they invoke this method at close to the
        same time.

        @param content: The desired contents of the file at this path.

        @type content: L{str}

        @param ext: An extension to append to the temporary filename used to
            store the bytes while they are being written.  This can be used to
            make sure that temporary files can be identified by their suffix,
            for cleanup in case of crashes.

        @type ext: C{str}
        """
        sib = self.temporarySibling(ext)
        f = sib.open('w')
        try:
            f.write(content)
        finally:
            f.close()
        if platform.isWindows() and exists(self.path):
            os.unlink(self.path)
        os.rename(sib.path, self.path)

Example 16

Project: mythbox Source File: test_ssl.py
    def _cbLostConns(self, results):
        (sSuccess, sResult), (cSuccess, cResult) = results

        self.failIf(sSuccess)
        self.failIf(cSuccess)

        acceptableErrors = [SSL.Error]

        # Rather than getting a verification failure on Windows, we are getting
        # a connection failure.  Without something like sslverify proxying
        # in-between we can't fix up the platform's errors, so let's just
        # specifically say it is only OK in this one case to keep the tests
        # passing.  Normally we'd like to be as strict as possible here, so
        # we're not going to allow this to report errors incorrectly on any
        # other platforms.

        if platform.isWindows():
            from twisted.internet.error import ConnectionLost
            acceptableErrors.append(ConnectionLost)

        sResult.trap(*acceptableErrors)
        cResult.trap(*acceptableErrors)

        return self.serverPort.stopListening()

Example 17

Project: mythbox Source File: test_stdio.py
    def test_normalFileStandardOut(self):
        """
        If L{StandardIO} is created with a file descriptor which refers to a
        normal file (ie, a file from the filesystem), L{StandardIO.write}
        writes bytes to that file.  In particular, it does not immediately
        consider the file closed or call its protocol's C{connectionLost}
        method.
        """
        onConnLost = defer.Deferred()
        proto = ConnectionLostNotifyingProtocol(onConnLost)
        path = filepath.FilePath(self.mktemp())
        self.normal = normal = path.open('w')
        self.addCleanup(normal.close)

        kwargs = dict(stdout=normal.fileno())
        if not platform.isWindows():
            # Make a fake stdin so that StandardIO doesn't mess with the *real*
            # stdin.
            r, w = os.pipe()
            self.addCleanup(os.close, r)
            self.addCleanup(os.close, w)
            kwargs['stdin'] = r
        connection = stdio.StandardIO(proto, **kwargs)

        # The reactor needs to spin a bit before it might have incorrectly
        # decided stdout is closed.  Use this counter to keep track of how
        # much we've let it spin.  If it closes before we expected, this
        # counter will have a value that's too small and we'll know.
        howMany = 5
        count = itertools.count()

        def spin():
            for value in count:
                if value == howMany:
                    connection.loseConnection()
                    return
                connection.write(str(value))
                break
            reactor.callLater(0, spin)
        reactor.callLater(0, spin)

        # Once the connection is lost, make sure the counter is at the
        # appropriate value.
        def cbLost(reason):
            self.assertEquals(count.next(), howMany + 1)
            self.assertEquals(
                path.getContent(),
                ''.join(map(str, range(howMany))))
        onConnLost.addCallback(cbLost)
        return onConnLost

Example 18

Project: TwistedBot Source File: filepath.py
    def child(self, path):
        """
        Create and return a new L{FilePath} representing a path contained by
        C{self}.

        @param path: The base name of the new L{FilePath}.  If this contains
            directory separators or parent references it will be rejected.
        @type path: C{bytes}

        @raise InsecurePath: If the result of combining this path with C{path}
            would result in a path which is not a direct child of this path.
        """
        if platform.isWindows() and path.count(b":"):
            # Catch paths like C:blah that don't have a slash
            raise InsecurePath("%r contains a colon." % (path,))
        norm = normpath(path)
        if self.sep in norm:
            raise InsecurePath("%r contains one or more directory separators" % (path,))
        newpath = abspath(joinpath(self.path, norm))
        if not newpath.startswith(self.path):
            raise InsecurePath("%r is not a child of %s" % (newpath, self.path))
        return self.clonePath(newpath)

Example 19

Project: TwistedBot Source File: filepath.py
Function: get_device
    def getDevice(self):
        """
        Retrieves the device containing the file.  The inode number and device
        number together uniquely identify the file, but the device number is
        not necessarily consistent across reboots or system crashes.

        @raise: NotImplementedError if the platform is Windows, since the
                device number would be 0 for all partitions on a Windows
                platform
        @return: a number representing the device
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return st.st_dev

Example 20

Project: TwistedBot Source File: filepath.py
Function: getnumberofhardlinks
    def getNumberOfHardLinks(self):
        """
        Retrieves the number of hard links to the file.  This count keeps
        track of how many directories have entries for this file.  If the
        count is ever decremented to zero then the file itself is discarded
        as soon as no process still holds it open.  Symbolic links are not
        counted in the total.

        @raise: NotImplementedError if the platform is Windows, since Windows
                doesn't maintain a link count for directories, and os.stat
                does not set st_nlink on Windows anyway.
        @return: the number of hard links to the file
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return st.st_nlink

Example 21

Project: TwistedBot Source File: filepath.py
Function: set_content
    def setContent(self, content, ext=b'.new'):
        """
        Replace the file at this path with a new file that contains the given
        bytes, trying to avoid data-loss in the meanwhile.

        On UNIX-like platforms, this method does its best to ensure that by the
        time this method returns, either the old contents I{or} the new contents
        of the file will be present at this path for subsequent readers
        regardless of premature device removal, program crash, or power loss,
        making the following assumptions:

            - your filesystem is journaled (i.e. your filesystem will not
              I{itself} lose data due to power loss)

            - your filesystem's C{rename()} is atomic

            - your filesystem will not discard new data while preserving new
              metadata (see U{http://mjg59.livejournal.com/108257.html} for more
              detail)

        On most versions of Windows there is no atomic C{rename()} (see
        U{http://bit.ly/win32-overwrite} for more information), so this method
        is slightly less helpful.  There is a small window where the file at
        this path may be deleted before the new file is moved to replace it:
        however, the new file will be fully written and flushed beforehand so in
        the unlikely event that there is a crash at that point, it should be
        possible for the user to manually recover the new version of their data.
        In the future, Twisted will support atomic file moves on those versions
        of Windows which I{do} support them: see U{Twisted ticket
        3004<http://twistedmatrix.com/trac/ticket/3004>}.

        This method should be safe for use by multiple concurrent processes, but
        note that it is not easy to predict which process's contents will
        ultimately end up on disk if they invoke this method at close to the
        same time.

        @param content: The desired contents of the file at this path.

        @type content: L{bytes}

        @param ext: An extension to append to the temporary filename used to
            store the bytes while they are being written.  This can be used to
            make sure that temporary files can be identified by their suffix,
            for cleanup in case of crashes.

        @type ext: C{bytes}
        """
        sib = self.temporarySibling(ext)
        f = sib.open('w')
        try:
            f.write(content)
        finally:
            f.close()
        if platform.isWindows() and exists(self.path):
            os.unlink(self.path)
        os.rename(sib.path, self.path)

Example 22

Project: SubliminalCollaborator Source File: connectionmixins.py
    def test_disconnectWhileProducing(self):
        """
        If L{ITCPTransport.loseConnection} is called while a producer is
        registered with the transport, the connection is closed after the
        producer is unregistered.
        """
        reactor = self.buildReactor()

        # For some reason, pyobject/pygtk will not deliver the close
        # notification that should happen after the unregisterProducer call in
        # this test.  The selectable is in the write notification set, but no
        # notification ever arrives.  Probably for the same reason #5233 led
        # win32eventreactor to be broken.
        skippedReactors = ["Glib2Reactor", "Gtk2Reactor"]
        reactorClassName = reactor.__class__.__name__
        if reactorClassName in skippedReactors and platform.isWindows():
            raise SkipTest(
                "A pygobject/pygtk bug disables this functionality on Windows.")

        class Producer:
            def resumeProducing(self):
                log.msg("Producer.resumeProducing")

        port = reactor.listenTCP(0, serverFactoryFor(Protocol),
            interface=self.interface)

        finished = Deferred()
        finished.addErrback(log.err)
        finished.addCallback(lambda ign: reactor.stop())

        class ClientProtocol(Protocol):
            """
            Protocol to connect, register a producer, try to lose the
            connection, unregister the producer, and wait for the connection to
            actually be lost.
            """
            def connectionMade(self):
                log.msg("ClientProtocol.connectionMade")
                self.transport.registerProducer(Producer(), False)
                self.transport.loseConnection()
                # Let the reactor tick over, in case synchronously calling
                # loseConnection and then unregisterProducer is the same as
                # synchronously calling unregisterProducer and then
                # loseConnection (as it is in several reactors).
                reactor.callLater(0, reactor.callLater, 0, self.unregister)

            def unregister(self):
                log.msg("ClientProtocol unregister")
                self.transport.unregisterProducer()
                # This should all be pretty quick.  Fail the test
                # if we don't get a connectionLost event really
                # soon.
                reactor.callLater(
                    1.0, finished.errback,
                    Failure(Exception("Connection was not lost")))

            def connectionLost(self, reason):
                log.msg("ClientProtocol.connectionLost")
                finished.callback(None)

        clientFactory = ClientFactory()
        clientFactory.protocol = ClientProtocol
        reactor.connectTCP(self.interface, port.getHost().port, clientFactory)
        self.runReactor(reactor)

Example 23

Project: SubliminalCollaborator Source File: filepath.py
Function: child
    def child(self, path):
        """
        Create and return a new L{FilePath} representing a path contained by
        C{self}.

        @param path: The base name of the new L{FilePath}.  If this contains
            directory separators or parent references it will be rejected.
        @type path: C{str}

        @raise InsecurePath: If the result of combining this path with C{path}
            would result in a path which is not a direct child of this path.
        """
        if platform.isWindows() and path.count(":"):
            # Catch paths like C:blah that don't have a slash
            raise InsecurePath("%r contains a colon." % (path,))
        norm = normpath(path)
        if self.sep in norm:
            raise InsecurePath("%r contains one or more directory separators" % (path,))
        newpath = abspath(joinpath(self.path, norm))
        if not newpath.startswith(self.path):
            raise InsecurePath("%r is not a child of %s" % (newpath, self.path))
        return self.clonePath(newpath)

Example 24

Project: SubliminalCollaborator Source File: filepath.py
Function: get_device
    def getDevice(self):
        """
        Retrieves the device containing the file.  The inode number and device
        number together uniquely identify the file, but the device number is
        not necessarily consistent across reboots or system crashes.

        @raise: NotImplementedError if the platform is Windows, since the
                device number would be 0 for all partitions on a Windows
                platform
        @return: a number representing the device
        @rtype: C{long}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return long(st.st_dev)

Example 25

Project: SubliminalCollaborator Source File: filepath.py
Function: getnumberofhardlinks
    def getNumberOfHardLinks(self):
        """
        Retrieves the number of hard links to the file.  This count keeps
        track of how many directories have entries for this file.  If the
        count is ever decremented to zero then the file itself is discarded
        as soon as no process still holds it open.  Symbolic links are not
        counted in the total.

        @raise: NotImplementedError if the platform is Windows, since Windows
                doesn't maintain a link count for directories, and os.stat
                does not set st_nlink on Windows anyway.
        @return: the number of hard links to the file
        @rtype: C{int}
        @since: 11.0
        """
        if platform.isWindows():
            raise NotImplementedError

        st = self.statinfo
        if not st:
            self.restat()
            st = self.statinfo
        return int(st.st_nlink)

Example 26

Project: SubliminalCollaborator Source File: test_stdio.py
    def test_normalFileStandardOut(self):
        """
        If L{StandardIO} is created with a file descriptor which refers to a
        normal file (ie, a file from the filesystem), L{StandardIO.write}
        writes bytes to that file.  In particular, it does not immediately
        consider the file closed or call its protocol's C{connectionLost}
        method.
        """
        onConnLost = defer.Deferred()
        proto = ConnectionLostNotifyingProtocol(onConnLost)
        path = filepath.FilePath(self.mktemp())
        self.normal = normal = path.open('w')
        self.addCleanup(normal.close)

        kwargs = dict(stdout=normal.fileno())
        if not platform.isWindows():
            # Make a fake stdin so that StandardIO doesn't mess with the *real*
            # stdin.
            r, w = os.pipe()
            self.addCleanup(os.close, r)
            self.addCleanup(os.close, w)
            kwargs['stdin'] = r
        connection = stdio.StandardIO(proto, **kwargs)

        # The reactor needs to spin a bit before it might have incorrectly
        # decided stdout is closed.  Use this counter to keep track of how
        # much we've let it spin.  If it closes before we expected, this
        # counter will have a value that's too small and we'll know.
        howMany = 5
        count = itertools.count()

        def spin():
            for value in count:
                if value == howMany:
                    connection.loseConnection()
                    return
                connection.write(str(value))
                break
            reactor.callLater(0, spin)
        reactor.callLater(0, spin)

        # Once the connection is lost, make sure the counter is at the
        # appropriate value.
        def cbLost(reason):
            self.assertEqual(count.next(), howMany + 1)
            self.assertEqual(
                path.getContent(),
                ''.join(map(str, range(howMany))))
        onConnLost.addCallback(cbLost)
        return onConnLost