Пример #1
0
    async def _testPipeLoggerToPipe(self, test_string, loop):
        """
		Test PipeLogger writing to a pipe connected to a PipeReader.
		This verifies that PipeLogger does not deadlock when writing
		to a pipe that's drained by a PipeReader running in the same
		process (requires non-blocking write).
		"""

        input_fd, writer_pipe = os.pipe()
        _set_nonblocking(writer_pipe)
        writer_pipe = os.fdopen(writer_pipe, 'wb', 0)
        writer = asyncio.ensure_future(
            _writer(writer_pipe, test_string.encode('ascii')))
        writer.add_done_callback(lambda writer: writer_pipe.close())

        pr, pw = os.pipe()

        consumer = PipeLogger(background=True,
                              input_fd=input_fd,
                              log_file_path=os.fdopen(pw, 'wb', 0),
                              scheduler=loop)
        consumer.start()

        # Before starting the reader, wait here for a moment, in order
        # to exercise PipeLogger's handling of EAGAIN during write.
        await asyncio.wait([writer], timeout=0.01)

        reader = _reader(pr)
        await writer
        content = await reader
        await consumer.async_wait()

        self.assertEqual(consumer.returncode, os.EX_OK)

        return content.decode('ascii', 'replace')
Пример #2
0
    def _async_start(self):
        pipe_logger = None
        filter_proc = None
        try:
            log_input = None
            if self.log_path is not None:
                log_filter_file = self.log_filter_file
                if log_filter_file is not None:
                    split_value = shlex_split(log_filter_file)
                    log_filter_file = split_value if split_value else None
                if log_filter_file:
                    filter_input, stdin = os.pipe()
                    log_input, filter_output = os.pipe()
                    try:
                        filter_proc = yield asyncio.create_subprocess_exec(
                            *log_filter_file,
                            env=self.env,
                            stdin=filter_input,
                            stdout=filter_output,
                            stderr=filter_output,
                            loop=self.scheduler)
                    except EnvironmentError:
                        # Maybe the command is missing or broken somehow...
                        os.close(filter_input)
                        os.close(stdin)
                        os.close(log_input)
                        os.close(filter_output)
                    else:
                        self._stdin = os.fdopen(stdin, 'wb', 0)
                        os.close(filter_input)
                        os.close(filter_output)

            if self._stdin is None:
                # Since log_filter_file is unspecified or refers to a file
                # that is missing or broken somehow, create a pipe that
                # logs directly to pipe_logger.
                log_input, stdin = os.pipe()
                self._stdin = os.fdopen(stdin, 'wb', 0)

            # Set background=True so that pipe_logger does not log to stdout.
            pipe_logger = PipeLogger(background=True,
                                     scheduler=self.scheduler,
                                     input_fd=log_input,
                                     log_file_path=self.log_path)

            yield pipe_logger.async_start()
        except asyncio.CancelledError:
            if pipe_logger is not None and pipe_logger.poll() is None:
                pipe_logger.cancel()
            if filter_proc is not None and filter_proc.returncode is None:
                filter_proc.terminate()
            raise

        self._main_task = asyncio.ensure_future(self._main(
            pipe_logger, filter_proc=filter_proc),
                                                loop=self.scheduler)
        self._main_task.add_done_callback(self._main_exit)
Пример #3
0
    def _start(self):
        filter_proc = None
        log_input = None
        if self.log_path is not None:
            log_filter_file = self.log_filter_file
            if log_filter_file is not None:
                split_value = shlex_split(log_filter_file)
                log_filter_file = split_value if split_value else None
            if log_filter_file:
                filter_input, stdin = os.pipe()
                log_input, filter_output = os.pipe()
                try:
                    filter_proc = PopenProcess(
                        proc=subprocess.Popen(
                            log_filter_file,
                            env=self.env,
                            stdin=filter_input,
                            stdout=filter_output,
                            stderr=filter_output,
                        ),
                        scheduler=self.scheduler,
                    )
                    filter_proc.start()
                except EnvironmentError:
                    # Maybe the command is missing or broken somehow...
                    os.close(filter_input)
                    os.close(stdin)
                    os.close(log_input)
                    os.close(filter_output)
                else:
                    self._stdin = os.fdopen(stdin, "wb", 0)
                    os.close(filter_input)
                    os.close(filter_output)

        if self._stdin is None:
            # Since log_filter_file is unspecified or refers to a file
            # that is missing or broken somehow, create a pipe that
            # logs directly to pipe_logger.
            log_input, stdin = os.pipe()
            self._stdin = os.fdopen(stdin, "wb", 0)

        # Set background=True so that pipe_logger does not log to stdout.
        pipe_logger = PipeLogger(
            background=True,
            scheduler=self.scheduler,
            input_fd=log_input,
            log_file_path=self.log_path,
        )
        pipe_logger.start()

        self._main_task_cancel = functools.partial(self._main_cancel,
                                                   filter_proc, pipe_logger)
        self._main_task = asyncio.ensure_future(self._main(
            filter_proc, pipe_logger),
                                                loop=self.scheduler)
        self._main_task.add_done_callback(self._main_exit)
    def testLazyImportPortageBaseline(self):
        """
        Check what modules are imported by a baseline module import.
        """

        env = os.environ.copy()
        pythonpath = env.get("PYTHONPATH")
        if pythonpath is not None and not pythonpath.strip():
            pythonpath = None
        if pythonpath is None:
            pythonpath = ""
        else:
            pythonpath = ":" + pythonpath
        pythonpath = PORTAGE_PYM_PATH + pythonpath
        env["PYTHONPATH"] = pythonpath

        # If python is patched to insert the path of the
        # currently installed portage module into sys.path,
        # then the above PYTHONPATH override doesn't help.
        env["PORTAGE_PYM_PATH"] = PORTAGE_PYM_PATH

        scheduler = global_event_loop()
        master_fd, slave_fd = os.pipe()
        master_file = os.fdopen(master_fd, "rb", 0)
        slave_file = os.fdopen(slave_fd, "wb")
        producer = SpawnProcess(
            args=self._baseline_import_cmd,
            env=env,
            fd_pipes={1: slave_fd},
            scheduler=scheduler,
        )
        producer.start()
        slave_file.close()

        consumer = PipeReader(input_files={"producer": master_file},
                              scheduler=scheduler)

        consumer.start()
        consumer.wait()
        self.assertEqual(producer.wait(), os.EX_OK)
        self.assertEqual(consumer.wait(), os.EX_OK)

        output = consumer.getvalue().decode("ascii", "replace").split()

        unexpected_modules = " ".join(
            sorted(x for x in output if self._module_re.match(x) is not None
                   and x not in self._baseline_imports))

        self.assertEqual("", unexpected_modules)
	def testLazyImportPortageBaseline(self):
		"""
		Check what modules are imported by a baseline module import.
		"""

		env = os.environ.copy()
		pythonpath = env.get('PYTHONPATH')
		if pythonpath is not None and not pythonpath.strip():
			pythonpath = None
		if pythonpath is None:
			pythonpath = ''
		else:
			pythonpath = ':' + pythonpath
		pythonpath = PORTAGE_PYM_PATH + pythonpath
		env['PYTHONPATH'] = pythonpath

		# If python is patched to insert the path of the
		# currently installed portage module into sys.path,
		# then the above PYTHONPATH override doesn't help.
		env['PORTAGE_PYM_PATH'] = PORTAGE_PYM_PATH

		scheduler = PollScheduler().sched_iface
		master_fd, slave_fd = os.pipe()
		master_file = os.fdopen(master_fd, 'rb', 0)
		slave_file = os.fdopen(slave_fd, 'wb')
		producer = SpawnProcess(
			args=self._baseline_import_cmd,
			env=env, fd_pipes={1:slave_fd},
			scheduler=scheduler)
		producer.start()
		slave_file.close()

		consumer = PipeReader(
			input_files={"producer" : master_file},
			scheduler=scheduler)

		consumer.start()
		consumer.wait()
		self.assertEqual(producer.wait(), os.EX_OK)
		self.assertEqual(consumer.wait(), os.EX_OK)

		output = consumer.getvalue().decode('ascii', 'replace').split()

		unexpected_modules = " ".join(sorted(x for x in output \
			if self._module_re.match(x) is not None and \
			x not in self._baseline_imports))

		self.assertEqual("", unexpected_modules)
Пример #6
0
    def add_manifest(self, mymanifests, myheaders, myupdates, myremoved,
                     commitmessage):
        myfiles = mymanifests[:]
        # If there are no header (SVN/CVS keywords) changes in
        # the files, this Manifest commit must include the
        # other (yet uncommitted) files.
        if not myheaders:
            myfiles += myupdates
            myfiles += myremoved
        myfiles.sort()

        fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
        mymsg = os.fdopen(fd, "wb")
        mymsg.write(_unicode_encode(commitmessage))
        mymsg.close()

        retval = self.vcs_settings.changes.commit(myfiles, commitmessagefile)
        # cleanup the commit message before possibly exiting
        try:
            os.unlink(commitmessagefile)
        except OSError:
            pass
        if retval != os.EX_OK:
            writemsg_level("!!! Exiting on %s (shell) "
                           "error code: %s\n" %
                           (self.vcs_settings.vcs, retval),
                           level=logging.ERROR,
                           noiselevel=-1)
            sys.exit(retval)
	def _start(self):
		pr, pw = os.pipe()
		self._files = {}
		self._files['pipe_read'] = os.fdopen(pr, 'rb', 0)
		self._files['pipe_write'] = os.fdopen(pw, 'wb', 0)
		for k, f in self._files.items():
			fcntl.fcntl(f.fileno(), fcntl.F_SETFL,
				fcntl.fcntl(f.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
		self._reg_id = self.scheduler.register(self._files['pipe_read'].fileno(),
			PollConstants.POLLIN, self._output_handler)
		self._registered = True
		threading_mod = threading
		if self._force_dummy:
			threading_mod = dummy_threading
		self._thread = threading_mod.Thread(target=self._run_lock)
		self._thread.start()
Пример #8
0
    def priming_commit(self, myupdates, myremoved, commitmessage):
        myfiles = myupdates + myremoved
        fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
        mymsg = os.fdopen(fd, "wb")
        mymsg.write(_unicode_encode(commitmessage))
        mymsg.close()

        separator = '-' * 78

        print()
        print(green("Using commit message:"))
        print(green(separator))
        print(commitmessage)
        print(green(separator))
        print()

        # Having a leading ./ prefix on file paths can trigger a bug in
        # the cvs server when committing files to multiple directories,
        # so strip the prefix.
        myfiles = [f.lstrip("./") for f in myfiles]

        retval = self.vcs_settings.changes.commit(myfiles, commitmessagefile)
        # cleanup the commit message before possibly exiting
        try:
            os.unlink(commitmessagefile)
        except OSError:
            pass
        if retval != os.EX_OK:
            writemsg_level("!!! Exiting on %s (shell) "
                           "error code: %s\n" %
                           (self.vcs_settings.vcs, retval),
                           level=logging.ERROR,
                           noiselevel=-1)
            sys.exit(retval)
Пример #9
0
    def _testPipeReader(self, master_fd, slave_fd, test_string):
        """
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

        # WARNING: It is very important to use unbuffered mode here,
        # in order to avoid issue 5380 with python3.
        master_file = os.fdopen(master_fd, 'rb', 0)
        scheduler = global_event_loop()

        consumer = PipeReader(input_files={"producer": master_file},
                              _use_array=self._use_array,
                              scheduler=scheduler)
        consumer.start()

        producer = scheduler.run_until_complete(
            asyncio.create_subprocess_exec("bash",
                                           "-c",
                                           self._echo_cmd % test_string,
                                           stdout=slave_fd,
                                           loop=scheduler))

        os.close(slave_fd)
        scheduler.run_until_complete(producer.wait())
        scheduler.run_until_complete(consumer.async_wait())

        self.assertEqual(producer.returncode, os.EX_OK)
        self.assertEqual(consumer.returncode, os.EX_OK)

        return consumer.getvalue().decode('ascii', 'replace')
Пример #10
0
	def add_manifest(self, mymanifests, myheaders, myupdates, myremoved,
					commitmessage):
		myfiles = mymanifests[:]
		# If there are no header (SVN/CVS keywords) changes in
		# the files, this Manifest commit must include the
		# other (yet uncommitted) files.
		if not myheaders:
			myfiles += myupdates
			myfiles += myremoved
		myfiles.sort()

		fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
		mymsg = os.fdopen(fd, "wb")
		mymsg.write(_unicode_encode(commitmessage))
		mymsg.close()

		retval = self.vcs_settings.changes.commit(myfiles, commitmessagefile)
		# cleanup the commit message before possibly exiting
		try:
			os.unlink(commitmessagefile)
		except OSError:
			pass
		if retval != os.EX_OK:
			writemsg_level(
				"!!! Exiting on %s (shell) "
				"error code: %s\n" % (self.vcs_settings.vcs, retval),
				level=logging.ERROR, noiselevel=-1)
			sys.exit(retval)
Пример #11
0
	def _testPipeReader(self, master_fd, slave_fd, test_string):
		"""
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

		# WARNING: It is very important to use unbuffered mode here,
		# in order to avoid issue 5380 with python3.
		master_file = os.fdopen(master_fd, 'rb', 0)
		scheduler = global_event_loop()

		consumer = PipeReader(
			input_files={"producer" : master_file},
			_use_array=self._use_array,
			scheduler=scheduler)

		producer = PopenProcess(
			pipe_reader=consumer,
			proc=subprocess.Popen(["bash", "-c", self._echo_cmd % test_string],
				stdout=slave_fd),
			scheduler=scheduler)

		producer.start()
		os.close(slave_fd)
		producer.wait()
		consumer.wait()

		self.assertEqual(producer.returncode, os.EX_OK)
		self.assertEqual(consumer.returncode, os.EX_OK)

		return consumer.getvalue().decode('ascii', 'replace')
Пример #12
0
 def setUp(self):
     fd, self.testfile = tempfile.mkstemp(suffix=".testdata",
                                          prefix=self.__class__.__name__,
                                          text=True)
     f = os.fdopen(fd, "w")
     f.write("\n".join(test_cps))
     f.close()
Пример #13
0
	def priming_commit(self, myupdates, myremoved, commitmessage):
		myfiles = myupdates + myremoved
		fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
		mymsg = os.fdopen(fd, "wb")
		mymsg.write(_unicode_encode(commitmessage))
		mymsg.close()

		separator = '-' * 78

		print()
		print(green("Using commit message:"))
		print(green(separator))
		print(commitmessage)
		print(green(separator))
		print()

		# Having a leading ./ prefix on file paths can trigger a bug in
		# the cvs server when committing files to multiple directories,
		# so strip the prefix.
		myfiles = [f.lstrip("./") for f in myfiles]

		retval = self.vcs_settings.changes.commit(myfiles, commitmessagefile)
		# cleanup the commit message before possibly exiting
		try:
			os.unlink(commitmessagefile)
		except OSError:
			pass
		if retval != os.EX_OK:
			writemsg_level(
				"!!! Exiting on %s (shell) "
				"error code: %s\n" % (self.vcs_settings.vcs, retval),
				level=logging.ERROR, noiselevel=-1)
			sys.exit(retval)
Пример #14
0
    def _testPipeLoggerToPipe(self, test_string, loop=None):
        """
		Test PipeLogger writing to a pipe connected to a PipeReader.
		This verifies that PipeLogger does not deadlock when writing
		to a pipe that's drained by a PipeReader running in the same
		process (requires non-blocking write).
		"""

        producer = PopenProcess(proc=subprocess.Popen(
            ["bash", "-c", self._echo_cmd % test_string],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT),
                                scheduler=loop)

        pr, pw = os.pipe()

        consumer = producer.pipe_reader = PipeLogger(
            background=True,
            input_fd=producer.proc.stdout,
            log_file_path=os.fdopen(pw, 'wb', 0))

        reader = _reader(pr, loop=loop)
        yield producer.async_start()
        content = yield reader
        yield producer.async_wait()
        yield consumer.async_wait()

        self.assertEqual(producer.returncode, os.EX_OK)
        self.assertEqual(consumer.returncode, os.EX_OK)

        coroutine_return(content.decode('ascii', 'replace'))
Пример #15
0
    def _testPipeReader(self, test_string):
        """
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

        if self._use_pty:
            got_pty, master_fd, slave_fd = _create_pty_or_pipe()
            if not got_pty:
                os.close(slave_fd)
                os.close(master_fd)
                skip_reason = "pty not acquired"
                self.portage_skip = skip_reason
                self.fail(skip_reason)
                return
        else:
            master_fd, slave_fd = os.pipe()

        # WARNING: It is very important to use unbuffered mode here,
        # in order to avoid issue 5380 with python3.
        master_file = os.fdopen(master_fd, 'rb', 0)
        slave_file = os.fdopen(slave_fd, 'wb', 0)
        task_scheduler = TaskScheduler(max_jobs=2)
        producer = SpawnProcess(
            args=["bash", "-c", self._echo_cmd % test_string],
            env=os.environ,
            fd_pipes={1: slave_fd},
            scheduler=task_scheduler.sched_iface)
        task_scheduler.add(producer)
        slave_file.close()

        consumer = PipeReader(input_files={"producer": master_file},
                              scheduler=task_scheduler.sched_iface,
                              _use_array=self._use_array)

        task_scheduler.add(consumer)

        # This will ensure that both tasks have exited, which
        # is necessary to avoid "ResourceWarning: unclosed file"
        # warnings since Python 3.2 (and also ensures that we
        # don't leave any zombie child processes).
        task_scheduler.run()
        self.assertEqual(producer.returncode, os.EX_OK)
        self.assertEqual(consumer.returncode, os.EX_OK)

        return consumer.getvalue().decode('ascii', 'replace')
Пример #16
0
	def _testPipeReader(self, test_string):
		"""
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

		if self._use_pty:
			got_pty, master_fd, slave_fd = _create_pty_or_pipe()
			if not got_pty:
				os.close(slave_fd)
				os.close(master_fd)
				skip_reason = "pty not acquired"
				self.portage_skip = skip_reason
				self.fail(skip_reason)
				return
		else:
			master_fd, slave_fd = os.pipe()

		# WARNING: It is very important to use unbuffered mode here,
		# in order to avoid issue 5380 with python3.
		master_file = os.fdopen(master_fd, 'rb', 0)
		slave_file = os.fdopen(slave_fd, 'wb', 0)
		task_scheduler = TaskScheduler(max_jobs=2)
		producer = SpawnProcess(
			args=["bash", "-c", self._echo_cmd % test_string],
			env=os.environ, fd_pipes={1:slave_fd},
			scheduler=task_scheduler.sched_iface)
		task_scheduler.add(producer)
		slave_file.close()

		consumer = PipeReader(
			input_files={"producer" : master_file},
			scheduler=task_scheduler.sched_iface, _use_array=self._use_array)

		task_scheduler.add(consumer)

		# This will ensure that both tasks have exited, which
		# is necessary to avoid "ResourceWarning: unclosed file"
		# warnings since Python 3.2 (and also ensures that we
		# don't leave any zombie child processes).
		task_scheduler.run()
		self.assertEqual(producer.returncode, os.EX_OK)
		self.assertEqual(consumer.returncode, os.EX_OK)

		return consumer.getvalue().decode('ascii', 'replace')
Пример #17
0
 def _processItem(self, item):
     filename = None
     fd, filename = mkstemp()
     f = os.fdopen(fd, 'w')
     f.write(item)
     f.close()
     try:
         return NewsItem(filename, 0)
     except TypeError:
         self.fail("Error while processing news item %s" % filename)
Пример #18
0
    def _start(self):
        self._files = self._files_dict()
        input_fd = os.open(self.input_fifo, os.O_RDONLY | os.O_NONBLOCK)
        self._files.pipe_in = os.fdopen(input_fd, 'rb')

        self._reg_id = self.scheduler.register(self._files.pipe_in.fileno(),
                                               self._registered_events,
                                               self._input_handler)

        self._registered = True
Пример #19
0
	def _start(self):
		self._files = self._files_dict()
		input_fd = os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK)
		self._files.pipe_in = os.fdopen(input_fd, 'rb')

		self._reg_id = self.scheduler.register(
			self._files.pipe_in.fileno(),
			self._registered_events, self._input_handler)

		self._registered = True
	def setUp(self):
		fd, self.testfile = tempfile.mkstemp(suffix=".testdata", prefix=self.__class__.__name__, text=True)
		f = os.fdopen(fd, 'w')
		for i in range(0, len(test_cps)):
			atom = test_cps[i]
			if i % 2 == 0:
				f.write(atom + ' abc def\n')
			else:
				f.write(atom + '\n')
		f.close()
Пример #21
0
	def _processItem(self, item):
		filename = None
		fd, filename = mkstemp()
		f = os.fdopen(fd, 'w')
		f.write(item)
		f.close()
		try:
			return NewsItem(filename, 0)
		except TypeError:
			self.fail("Error while processing news item %s" % filename)
Пример #22
0
    def add_manifest(self, mymanifests, myheaders, myupdates, myremoved,
                     commitmessage):
        myfiles = mymanifests[:]
        # If there are no header (SVN/CVS keywords) changes in
        # the files, this Manifest commit must include the
        # other (yet uncommitted) files.
        if not myheaders:
            myfiles += myupdates
            myfiles += myremoved
        myfiles.sort()

        fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
        mymsg = os.fdopen(fd, "wb")
        mymsg.write(_unicode_encode(commitmessage))
        mymsg.close()

        commit_cmd = []
        if self.options.pretend and self.vcs_settings.vcs is None:
            # substitute a bogus value for pretend output
            commit_cmd.append("cvs")
        else:
            commit_cmd.append(self.vcs_settings.vcs)
        commit_cmd.extend(self.vcs_settings.vcs_global_opts)
        commit_cmd.append("commit")
        commit_cmd.extend(self.vcs_settings.vcs_local_opts)
        if self.vcs_settings.vcs == "hg":
            commit_cmd.extend(["--logfile", commitmessagefile])
            commit_cmd.extend(myfiles)
        else:
            commit_cmd.extend(["-F", commitmessagefile])
            commit_cmd.extend(f.lstrip("./") for f in myfiles)

        try:
            if self.options.pretend:
                print("(%s)" % (" ".join(commit_cmd), ))
            else:
                retval = spawn(commit_cmd, env=self.repo_settings.commit_env)
                if retval != os.EX_OK:
                    if self.repo_settings.repo_config.sign_commit and self.vcs_settings.vcs == 'git' and \
                     not git_supports_gpg_sign():
                        # Inform user that newer git is needed (bug #403323).
                        logging.error(
                            "Git >=1.7.9 is required for signed commits!")

                    writemsg_level("!!! Exiting on %s (shell) "
                                   "error code: %s\n" %
                                   (self.vcs_settings.vcs, retval),
                                   level=logging.ERROR,
                                   noiselevel=-1)
                    sys.exit(retval)
        finally:
            try:
                os.unlink(commitmessagefile)
            except OSError:
                pass
Пример #23
0
	def add_manifest(self, mymanifests, myheaders, myupdates, myremoved,
					commitmessage):
		myfiles = mymanifests[:]
		# If there are no header (SVN/CVS keywords) changes in
		# the files, this Manifest commit must include the
		# other (yet uncommitted) files.
		if not myheaders:
			myfiles += myupdates
			myfiles += myremoved
		myfiles.sort()

		fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
		mymsg = os.fdopen(fd, "wb")
		mymsg.write(_unicode_encode(commitmessage))
		mymsg.close()

		commit_cmd = []
		if self.options.pretend and self.vcs_settings.vcs is None:
			# substitute a bogus value for pretend output
			commit_cmd.append("cvs")
		else:
			commit_cmd.append(self.vcs_settings.vcs)
		commit_cmd.extend(self.vcs_settings.vcs_global_opts)
		commit_cmd.append("commit")
		commit_cmd.extend(self.vcs_settings.vcs_local_opts)
		if self.vcs_settings.vcs == "hg":
			commit_cmd.extend(["--logfile", commitmessagefile])
			commit_cmd.extend(myfiles)
		else:
			commit_cmd.extend(["-F", commitmessagefile])
			commit_cmd.extend(f.lstrip("./") for f in myfiles)

		try:
			if self.options.pretend:
				print("(%s)" % (" ".join(commit_cmd),))
			else:
				retval = spawn(commit_cmd, env=self.repo_settings.commit_env)
				if retval != os.EX_OK:
					if self.repo_settings.repo_config.sign_commit and self.vcs_settings.vcs == 'git' and \
						not git_supports_gpg_sign():
						# Inform user that newer git is needed (bug #403323).
						logging.error(
							"Git >=1.7.9 is required for signed commits!")

					writemsg_level(
						"!!! Exiting on %s (shell) "
						"error code: %s\n" % (self.vcs_settings.vcs, retval),
						level=logging.ERROR, noiselevel=-1)
					sys.exit(retval)
		finally:
			try:
				os.unlink(commitmessagefile)
			except OSError:
				pass
Пример #24
0
 def setUp(self):
     fd, self.testfile = tempfile.mkstemp(
         suffix=".testdata", prefix=self.__class__.__name__, text=True
     )
     f = os.fdopen(fd, "w")
     for i in range(0, len(test_cps)):
         atom = test_cps[i]
         if i % 2 == 0:
             f.write(atom + " abc def\n")
         else:
             f.write(atom + "\n")
     f.close()
Пример #25
0
	def _reopen_input(self):
		"""
		Re-open the input stream, in order to suppress
		POLLHUP events (bug #339976).
		"""
		self._files.pipe_in.close()
		input_fd = os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK)
		self._files.pipe_in = os.fdopen(input_fd, 'rb', 0)
		self.scheduler.unregister(self._reg_id)
		self._reg_id = self.scheduler.register(
			self._files.pipe_in.fileno(),
			self._registered_events, self._input_handler)
	def _start(self):
		in_pr, in_pw = os.pipe()
		out_pr, out_pw = os.pipe()
		self._files = {}
		self._files['pipe_in'] = os.fdopen(in_pr, 'rb', 0)
		self._files['pipe_out'] = os.fdopen(out_pw, 'wb', 0)
		fcntl.fcntl(in_pr, fcntl.F_SETFL,
			fcntl.fcntl(in_pr, fcntl.F_GETFL) | os.O_NONBLOCK)
		self._reg_id = self.scheduler.register(in_pr,
			PollConstants.POLLIN, self._output_handler)
		self._registered = True
		self._proc = SpawnProcess(
			args=[portage._python_interpreter,
				os.path.join(portage._bin_path, 'lock-helper.py'), self.path],
				env=dict(os.environ, PORTAGE_PYM_PATH=portage._pym_path),
				fd_pipes={0:out_pr, 1:in_pw, 2:sys.stderr.fileno()},
				scheduler=self.scheduler)
		self._proc.addExitListener(self._proc_exit)
		self._proc.start()
		os.close(out_pr)
		os.close(in_pw)
Пример #27
0
	def _start(self):
		self._files = self._files_dict()
		input_fd = os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK)

		# File streams are in unbuffered mode since we do atomic
		# read and write of whole pickles.
		self._files.pipe_in = os.fdopen(input_fd, 'rb', 0)

		self._reg_id = self.scheduler.register(
			self._files.pipe_in.fileno(),
			self._registered_events, self._input_handler)

		self._registered = True
Пример #28
0
	def testPipeReader(self):
		"""
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

		test_string = 2 * "blah blah blah\n"

		scheduler = PollScheduler().sched_iface
		master_fd, slave_fd = os.pipe()
		master_file = os.fdopen(master_fd, 'rb', 0)
		slave_file = os.fdopen(slave_fd, 'wb')
		producer = SpawnProcess(
			args=["bash", "-c", "echo -n '%s'" % test_string],
			env=os.environ, fd_pipes={1:slave_fd},
			scheduler=scheduler)
		producer.start()
		slave_file.close()

		consumer = PipeReader(
			input_files={"producer" : master_file},
			scheduler=scheduler)

		consumer.start()

		# This will ensure that both tasks have exited, which
		# is necessary to avoid "ResourceWarning: unclosed file"
		# warnings since Python 3.2 (and also ensures that we
		# don't leave any zombie child processes).
		scheduler.schedule()
		self.assertEqual(producer.returncode, os.EX_OK)
		self.assertEqual(consumer.returncode, os.EX_OK)

		output = consumer.getvalue().decode('ascii', 'replace')
		self.assertEqual(test_string, output)
Пример #29
0
    def _start(self):

        log_file_path = self.log_file_path
        if hasattr(log_file_path, 'write'):
            self._log_file_nb = True
            self._log_file = log_file_path
            _set_nonblocking(self._log_file.fileno())
        elif log_file_path is not None:
            try:
                self._log_file = open(
                    _unicode_encode(log_file_path,
                                    encoding=_encodings["fs"],
                                    errors="strict"),
                    mode="ab",
                )

                if log_file_path.endswith(".gz"):
                    self._log_file_real = self._log_file
                    self._log_file = gzip.GzipFile(filename="",
                                                   mode="ab",
                                                   fileobj=self._log_file)

                portage.util.apply_secpass_permissions(
                    log_file_path,
                    uid=portage.portage_uid,
                    gid=portage.portage_gid,
                    mode=0o660,
                )
            except FileNotFoundError:
                if self._was_cancelled():
                    self._async_wait()
                    return
                raise

        if isinstance(self.input_fd, int):
            self.input_fd = os.fdopen(self.input_fd, 'rb', 0)

        fd = self.input_fd.fileno()

        fcntl.fcntl(fd, fcntl.F_SETFL,
                    fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)

        self._io_loop_task = asyncio.ensure_future(self._io_loop(
            self.input_fd),
                                                   loop=self.scheduler)
        self._io_loop_task.add_done_callback(self._io_loop_done)
        self._registered = True
Пример #30
0
    def priming_commit(self, myupdates, myremoved, commitmessage):
        myfiles = myupdates + myremoved
        fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
        mymsg = os.fdopen(fd, "wb")
        mymsg.write(_unicode_encode(commitmessage))
        mymsg.close()

        separator = '-' * 78

        print()
        print(green("Using commit message:"))
        print(green(separator))
        print(commitmessage)
        print(green(separator))
        print()

        # Having a leading ./ prefix on file paths can trigger a bug in
        # the cvs server when committing files to multiple directories,
        # so strip the prefix.
        myfiles = [f.lstrip("./") for f in myfiles]

        commit_cmd = [self.vcs_settings.vcs]
        commit_cmd.extend(self.vcs_settings.vcs_global_opts)
        commit_cmd.append("commit")
        commit_cmd.extend(self.vcs_settings.vcs_local_opts)
        commit_cmd.extend(["-F", commitmessagefile])
        commit_cmd.extend(myfiles)

        try:
            if self.options.pretend:
                print("(%s)" % (" ".join(commit_cmd), ))
            else:
                retval = spawn(commit_cmd, env=self.repo_settings.commit_env)
                if retval != os.EX_OK:
                    writemsg_level("!!! Exiting on %s (shell) "
                                   "error code: %s\n" %
                                   (self.vcs_settings.vcs, retval),
                                   level=logging.ERROR,
                                   noiselevel=-1)
                    sys.exit(retval)
        finally:
            try:
                os.unlink(commitmessagefile)
            except OSError:
                pass
Пример #31
0
	def priming_commit(self, myupdates, myremoved, commitmessage):
		myfiles = myupdates + myremoved
		fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
		mymsg = os.fdopen(fd, "wb")
		mymsg.write(_unicode_encode(commitmessage))
		mymsg.close()

		separator = '-' * 78

		print()
		print(green("Using commit message:"))
		print(green(separator))
		print(commitmessage)
		print(green(separator))
		print()

		# Having a leading ./ prefix on file paths can trigger a bug in
		# the cvs server when committing files to multiple directories,
		# so strip the prefix.
		myfiles = [f.lstrip("./") for f in myfiles]

		commit_cmd = [self.vcs_settings.vcs]
		commit_cmd.extend(self.vcs_settings.vcs_global_opts)
		commit_cmd.append("commit")
		commit_cmd.extend(self.vcs_settings.vcs_local_opts)
		commit_cmd.extend(["-F", commitmessagefile])
		commit_cmd.extend(myfiles)

		try:
			if self.options.pretend:
				print("(%s)" % (" ".join(commit_cmd),))
			else:
				retval = spawn(commit_cmd, env=self.repo_settings.commit_env)
				if retval != os.EX_OK:
					writemsg_level(
						"!!! Exiting on %s (shell) "
						"error code: %s\n" % (self.vcs_settings.vcs, retval),
						level=logging.ERROR, noiselevel=-1)
					sys.exit(retval)
		finally:
			try:
				os.unlink(commitmessagefile)
			except OSError:
				pass
Пример #32
0
	def _testPipeReader(self, test_string):
		"""
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

		if self._use_pty:
			got_pty, master_fd, slave_fd = _create_pty_or_pipe()
			if not got_pty:
				os.close(slave_fd)
				os.close(master_fd)
				skip_reason = "pty not acquired"
				self.portage_skip = skip_reason
				self.fail(skip_reason)
				return
		else:
			master_fd, slave_fd = os.pipe()

		# WARNING: It is very important to use unbuffered mode here,
		# in order to avoid issue 5380 with python3.
		master_file = os.fdopen(master_fd, 'rb', 0)
		scheduler = global_event_loop()

		consumer = PipeReader(
			input_files={"producer" : master_file},
			_use_array=self._use_array,
			scheduler=scheduler)

		producer = PopenProcess(
			pipe_reader=consumer,
			proc=subprocess.Popen(["bash", "-c", self._echo_cmd % test_string],
				stdout=slave_fd),
			scheduler=scheduler)

		producer.start()
		os.close(slave_fd)
		producer.wait()

		self.assertEqual(producer.returncode, os.EX_OK)
		self.assertEqual(consumer.returncode, os.EX_OK)

		return consumer.getvalue().decode('ascii', 'replace')
Пример #33
0
	def _start(self):

		log_file_path = self.log_file_path
		if hasattr(log_file_path, 'write'):
			self._log_file_nb = True
			self._log_file = log_file_path
			_set_nonblocking(self._log_file.fileno())
		elif log_file_path is not None:
			self._log_file = open(_unicode_encode(log_file_path,
				encoding=_encodings['fs'], errors='strict'), mode='ab')
			if log_file_path.endswith('.gz'):
				self._log_file_real = self._log_file
				self._log_file = gzip.GzipFile(filename='', mode='ab',
					fileobj=self._log_file)

			portage.util.apply_secpass_permissions(log_file_path,
				uid=portage.portage_uid, gid=portage.portage_gid,
				mode=0o660)

		if isinstance(self.input_fd, int):
			self.input_fd = os.fdopen(self.input_fd, 'rb', 0)

		fd = self.input_fd.fileno()

		fcntl.fcntl(fd, fcntl.F_SETFL,
			fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)

		# FD_CLOEXEC is enabled by default in Python >=3.4.
		if sys.hexversion < 0x3040000:
			try:
				fcntl.FD_CLOEXEC
			except AttributeError:
				pass
			else:
				fcntl.fcntl(fd, fcntl.F_SETFD,
					fcntl.fcntl(fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)

		self._io_loop_task = asyncio.ensure_future(self._io_loop(self.input_fd), loop=self.scheduler)
		self._io_loop_task.add_done_callback(self._io_loop_done)
		self._registered = True
Пример #34
0
	def testPipeReader(self):
		"""
		Use a poll loop to read data from a pipe and assert that
		the data written to the pipe is identical to the data
		read from the pipe.
		"""

		test_string = 2 * "blah blah blah\n"

		master_fd, slave_fd = self._create_pipe()
		master_file = os.fdopen(master_fd, 'rb')

		task_scheduler = TaskScheduler(max_jobs=2)
		scheduler = task_scheduler.sched_iface

		class Producer(SpawnProcess):
			def _spawn(self, args, **kwargs):
				rval = SpawnProcess._spawn(self, args, **kwargs)
				os.close(kwargs['fd_pipes'][1])
				return rval

		producer = Producer(
			args=["bash", "-c", "echo -n '%s'" % test_string],
			fd_pipes={1:slave_fd}, scheduler=scheduler)

		consumer = PipeReader(
			input_files={"producer" : master_file},
			scheduler=scheduler)

		task_scheduler.add(producer)
		task_scheduler.add(consumer)

		task_scheduler.run()

		if sys.hexversion >= 0x3000000:
			test_string = test_string.encode()

		self._assertEqual(test_string, consumer.getvalue())
Пример #35
0
    def _start(self):

        if self.cancelled:
            return

        if self.fd_pipes is None:
            self.fd_pipes = {}
        fd_pipes = self.fd_pipes
        fd_pipes.setdefault(0, sys.stdin.fileno())
        fd_pipes.setdefault(1, sys.stdout.fileno())
        fd_pipes.setdefault(2, sys.stderr.fileno())

        # flush any pending output
        for fd in fd_pipes.values():
            if fd == sys.stdout.fileno():
                sys.stdout.flush()
            if fd == sys.stderr.fileno():
                sys.stderr.flush()

        self._files = self._files_dict()
        files = self._files

        master_fd, slave_fd = self._pipe(fd_pipes)
        fcntl.fcntl(master_fd, fcntl.F_SETFL,
                    fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

        logfile = None
        if self._can_log(slave_fd):
            logfile = self.logfile

        null_input = None
        fd_pipes_orig = fd_pipes.copy()
        if self.background:
            # TODO: Use job control functions like tcsetpgrp() to control
            # access to stdin. Until then, use /dev/null so that any
            # attempts to read from stdin will immediately return EOF
            # instead of blocking indefinitely.
            null_input = open('/dev/null', 'rb')
            fd_pipes[0] = null_input.fileno()
        else:
            fd_pipes[0] = fd_pipes_orig[0]

        files.process = os.fdopen(master_fd, 'rb')
        if logfile is not None:

            fd_pipes[1] = slave_fd
            fd_pipes[2] = slave_fd

            files.log = open(_unicode_encode(logfile,
                                             encoding=_encodings['fs'],
                                             errors='strict'),
                             mode='ab')
            if logfile.endswith('.gz'):
                files.log = gzip.GzipFile(filename='',
                                          mode='ab',
                                          fileobj=files.log)

            portage.util.apply_secpass_permissions(logfile,
                                                   uid=portage.portage_uid,
                                                   gid=portage.portage_gid,
                                                   mode=0o660)

            if not self.background:
                files.stdout = os.fdopen(os.dup(fd_pipes_orig[1]), 'wb')

            output_handler = self._output_handler

        else:

            # Create a dummy pipe so the scheduler can monitor
            # the process from inside a poll() loop.
            fd_pipes[self._dummy_pipe_fd] = slave_fd
            if self.background:
                fd_pipes[1] = slave_fd
                fd_pipes[2] = slave_fd
            output_handler = self._dummy_handler

        kwargs = {}
        for k in self._spawn_kwarg_names:
            v = getattr(self, k)
            if v is not None:
                kwargs[k] = v

        kwargs["fd_pipes"] = fd_pipes
        kwargs["returnpid"] = True
        kwargs.pop("logfile", None)

        self._reg_id = self.scheduler.register(files.process.fileno(),
                                               self._registered_events,
                                               output_handler)
        self._registered = True

        retval = self._spawn(self.args, **kwargs)

        os.close(slave_fd)
        if null_input is not None:
            null_input.close()

        if isinstance(retval, int):
            # spawn failed
            self._unregister()
            self._set_returncode((self.pid, retval))
            self.wait()
            return

        self.pid = retval[0]
        portage.process.spawned_pids.remove(self.pid)
Пример #36
0
 def BuildFile(self):
     fd, self.fname = mkstemp()
     f = os.fdopen(fd, 'w')
     f.write("%s %s" % (self.cpv, ' '.join(self.useflags)))
     f.close()
Пример #37
0
	def BuildFile(self):
		fd, self.fname = mkstemp()
		f = os.fdopen(fd, 'w')
		f.write("%s %s" % (self.cpv, ' '.join(self.useflags)))
		f.close()
Пример #38
0
	def _send_reply(self, reply):
		output_fd = os.open(self.output_fifo, os.O_WRONLY|os.O_NONBLOCK)
		output_file = os.fdopen(output_fd, 'wb')
		pickle.dump(reply, output_file)
		output_file.close()
	def _start(self):
		settings = self.settings
		settings.setcpv(self.cpv)
		ebuild_path = self.ebuild_path

		eapi = None
		if 'parse-eapi-glep-55' in settings.features:
			pf, eapi = portage._split_ebuild_name_glep55(
				os.path.basename(ebuild_path))
		if eapi is None and \
			'parse-eapi-ebuild-head' in settings.features:
			eapi = portage._parse_eapi_ebuild_head(
				codecs.open(_unicode_encode(ebuild_path,
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'],
				errors='replace'))

		if eapi is not None:
			if not portage.eapi_is_supported(eapi):
				self.metadata_callback(self.cpv, self.ebuild_path,
					self.repo_path, {'EAPI' : eapi}, self.ebuild_mtime)
				self.returncode = os.EX_OK
				self.wait()
				return

			settings.configdict['pkg']['EAPI'] = eapi

		debug = settings.get("PORTAGE_DEBUG") == "1"
		master_fd = None
		slave_fd = None
		fd_pipes = None
		if self.fd_pipes is not None:
			fd_pipes = self.fd_pipes.copy()
		else:
			fd_pipes = {}

		fd_pipes.setdefault(0, sys.stdin.fileno())
		fd_pipes.setdefault(1, sys.stdout.fileno())
		fd_pipes.setdefault(2, sys.stderr.fileno())

		# flush any pending output
		for fd in fd_pipes.values():
			if fd == sys.stdout.fileno():
				sys.stdout.flush()
			if fd == sys.stderr.fileno():
				sys.stderr.flush()

		fd_pipes_orig = fd_pipes.copy()
		self._files = self._files_dict()
		files = self._files

		master_fd, slave_fd = os.pipe()
		fcntl.fcntl(master_fd, fcntl.F_SETFL,
			fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

		fd_pipes[self._metadata_fd] = slave_fd

		self._raw_metadata = []
		files.ebuild = os.fdopen(master_fd, 'rb')
		self._reg_id = self.scheduler.register(files.ebuild.fileno(),
			self._registered_events, self._output_handler)
		self._registered = True

		retval = portage.doebuild(ebuild_path, "depend",
			settings["ROOT"], settings, debug,
			mydbapi=self.portdb, tree="porttree",
			fd_pipes=fd_pipes, returnpid=True)

		os.close(slave_fd)

		if isinstance(retval, int):
			# doebuild failed before spawning
			self._unregister()
			self.returncode = retval
			self.wait()
			return

		self.pid = retval[0]
		portage.process.spawned_pids.remove(self.pid)
Пример #40
0
 def BuildFile(self):
     fd, self.fname = mkstemp()
     f = os.fdopen(fd, 'w')
     for c in self.cpv:
         f.write("%s %s\n" % (c, ' '.join(self.keywords)))
     f.close()
	def BuildFile(self):
		fd, self.fname = mkstemp()
		f = os.fdopen(fd, 'w')
		for k, v in self.items.items():
			f.write('%s=%s\n' % (k,v))
		f.close()
Пример #42
0
 def _send_reply(self, reply):
     output_fd = os.open(self.output_fifo, os.O_WRONLY | os.O_NONBLOCK)
     output_file = os.fdopen(output_fd, 'wb')
     pickle.dump(reply, output_file)
     output_file.close()
Пример #43
0
	def _start(self):

		if self.cancelled:
			return

		if self.fd_pipes is None:
			self.fd_pipes = {}
		fd_pipes = self.fd_pipes
		fd_pipes.setdefault(0, sys.stdin.fileno())
		fd_pipes.setdefault(1, sys.stdout.fileno())
		fd_pipes.setdefault(2, sys.stderr.fileno())

		# flush any pending output
		for fd in fd_pipes.values():
			if fd == sys.stdout.fileno():
				sys.stdout.flush()
			if fd == sys.stderr.fileno():
				sys.stderr.flush()

		self._files = self._files_dict()
		files = self._files

		master_fd, slave_fd = self._pipe(fd_pipes)
		fcntl.fcntl(master_fd, fcntl.F_SETFL,
			fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

		logfile = None
		if self._can_log(slave_fd):
			logfile = self.logfile

		null_input = None
		fd_pipes_orig = fd_pipes.copy()
		if self.background:
			# TODO: Use job control functions like tcsetpgrp() to control
			# access to stdin. Until then, use /dev/null so that any
			# attempts to read from stdin will immediately return EOF
			# instead of blocking indefinitely.
			null_input = open('/dev/null', 'rb')
			fd_pipes[0] = null_input.fileno()
		else:
			fd_pipes[0] = fd_pipes_orig[0]

		# WARNING: It is very important to use unbuffered mode here,
		# in order to avoid issue 5380 with python3.
		files.process = os.fdopen(master_fd, 'rb', 0)
		if logfile is not None:

			fd_pipes[1] = slave_fd
			fd_pipes[2] = slave_fd

			files.log = open(_unicode_encode(logfile,
				encoding=_encodings['fs'], errors='strict'), mode='ab')
			if logfile.endswith('.gz'):
				self._log_file_real = files.log
				files.log = gzip.GzipFile(filename='', mode='ab',
					fileobj=files.log)

			portage.util.apply_secpass_permissions(logfile,
				uid=portage.portage_uid, gid=portage.portage_gid,
				mode=0o660)

			if not self.background:
				files.stdout = os.fdopen(os.dup(fd_pipes_orig[1]), 'wb')

			output_handler = self._output_handler

		else:

			# Create a dummy pipe so the scheduler can monitor
			# the process from inside a poll() loop.
			fd_pipes[self._dummy_pipe_fd] = slave_fd
			if self.background:
				fd_pipes[1] = slave_fd
				fd_pipes[2] = slave_fd
			output_handler = self._dummy_handler

		kwargs = {}
		for k in self._spawn_kwarg_names:
			v = getattr(self, k)
			if v is not None:
				kwargs[k] = v

		kwargs["fd_pipes"] = fd_pipes
		kwargs["returnpid"] = True
		kwargs.pop("logfile", None)

		self._reg_id = self.scheduler.register(files.process.fileno(),
			self._registered_events, output_handler)
		self._registered = True

		retval = self._spawn(self.args, **kwargs)

		os.close(slave_fd)
		if null_input is not None:
			null_input.close()

		if isinstance(retval, int):
			# spawn failed
			self._unregister()
			self._set_returncode((self.pid, retval))
			self.wait()
			return

		self.pid = retval[0]
		portage.process.spawned_pids.remove(self.pid)
Пример #44
0
def _test_pty_eof(fdopen_buffered=False):
	"""
	Returns True if this issues is fixed for the currently
	running version of python: http://bugs.python.org/issue5380
	Raises an EnvironmentError from openpty() if it fails.

	NOTE: This issue is only problematic when array.fromfile()
	is used, rather than os.read(). However, array.fromfile()
	is preferred since it is approximately 10% faster.

	New development: It appears that array.fromfile() is usable
	with python3 as long as fdopen is called with a bufsize
	argument of 0.
	"""

	use_fork = False

	test_string = 2 * "blah blah blah\n"
	test_string = _unicode_decode(test_string,
		encoding='utf_8', errors='strict')

	# may raise EnvironmentError
	master_fd, slave_fd = pty.openpty()

	# Non-blocking mode is required for Darwin kernel.
	fcntl.fcntl(master_fd, fcntl.F_SETFL,
		fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

	# Disable post-processing of output since otherwise weird
	# things like \n -> \r\n transformations may occur.
	mode = termios.tcgetattr(slave_fd)
	mode[1] &= ~termios.OPOST
	termios.tcsetattr(slave_fd, termios.TCSANOW, mode)

	# Simulate a subprocess writing some data to the
	# slave end of the pipe, and then exiting.
	pid = None
	if use_fork:
		pids = spawn_bash(_unicode_encode("echo -n '%s'" % test_string,
			encoding='utf_8', errors='strict'), env=os.environ,
			fd_pipes={0:sys.stdin.fileno(), 1:slave_fd, 2:slave_fd},
			returnpid=True)
		if isinstance(pids, int):
			os.close(master_fd)
			os.close(slave_fd)
			raise EnvironmentError('spawn failed')
		pid = pids[0]
	else:
		os.write(slave_fd, _unicode_encode(test_string,
			encoding='utf_8', errors='strict'))
	os.close(slave_fd)

	# If using a fork, we must wait for the child here,
	# in order to avoid a race condition that would
	# lead to inconsistent results.
	if pid is not None:
		os.waitpid(pid, 0)

	if fdopen_buffered:
		master_file = os.fdopen(master_fd, 'rb')
	else:
		master_file = os.fdopen(master_fd, 'rb', 0)
	eof = False
	data = []
	iwtd = [master_file]
	owtd = []
	ewtd = []

	while not eof:

		events = select.select(iwtd, owtd, ewtd)
		if not events[0]:
			eof = True
			break

		buf = array.array('B')
		try:
			buf.fromfile(master_file, 1024)
		except (EOFError, IOError):
			eof = True

		if not buf:
			eof = True
		else:
			try:
				# Python >=3.2
				data.append(buf.tobytes())
			except AttributeError:
				data.append(buf.tostring())

	master_file.close()

	return test_string == _unicode_decode(b''.join(data), encoding='utf_8', errors='strict')
Пример #45
0
 def BuildFile(self):
     fd, self.fname = mkstemp()
     f = os.fdopen(fd, "w")
     f.write("\n".join(test_cps))
     f.close()
	def setUp(self):
		fd, self.testfile = tempfile.mkstemp(suffix=".testdata", prefix=self.__class__.__name__, text=True)
		f = os.fdopen(fd, 'w')
		f.write("\n".join(test_cps))
		f.close()
Пример #47
0
 def BuildFile(self):
     fd, self.fname = mkstemp()
     f = os.fdopen(fd, 'w')
     for k, v in self.items.items():
         f.write('%s=%s\n' % (k, v))
     f.close()
	def _start(self):
		settings = self.settings
		settings.setcpv(self.cpv)
		ebuild_path = self.ebuild_hash.location

		# the caller can pass in eapi in order to avoid
		# redundant _parse_eapi_ebuild_head calls
		eapi = self.eapi
		if eapi is None and \
			'parse-eapi-ebuild-head' in settings.features:
			with io.open(_unicode_encode(ebuild_path,
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'],
				errors='replace') as f:
				eapi = portage._parse_eapi_ebuild_head(f)

		if eapi is not None:
			if not portage.eapi_is_supported(eapi):
				self.metadata = self.metadata_callback(self.cpv,
					self.repo_path, {'EAPI' : eapi}, self.ebuild_hash)
				self._set_returncode((self.pid, os.EX_OK << 8))
				self.wait()
				return

			settings.configdict['pkg']['EAPI'] = eapi

		debug = settings.get("PORTAGE_DEBUG") == "1"
		master_fd = None
		slave_fd = None
		fd_pipes = None
		if self.fd_pipes is not None:
			fd_pipes = self.fd_pipes.copy()
		else:
			fd_pipes = {}

		null_input = open('/dev/null', 'rb')
		fd_pipes.setdefault(0, null_input.fileno())
		fd_pipes.setdefault(1, sys.stdout.fileno())
		fd_pipes.setdefault(2, sys.stderr.fileno())

		# flush any pending output
		for fd in fd_pipes.values():
			if fd == sys.stdout.fileno():
				sys.stdout.flush()
			if fd == sys.stderr.fileno():
				sys.stderr.flush()

		fd_pipes_orig = fd_pipes.copy()
		self._files = self._files_dict()
		files = self._files

		master_fd, slave_fd = os.pipe()
		fcntl.fcntl(master_fd, fcntl.F_SETFL,
			fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

		fd_pipes[self._metadata_fd] = slave_fd

		self._raw_metadata = []
		files.ebuild = os.fdopen(master_fd, 'rb', 0)
		self._reg_id = self.scheduler.register(files.ebuild.fileno(),
			self._registered_events, self._output_handler)
		self._registered = True

		retval = portage.doebuild(ebuild_path, "depend",
			settings=settings, debug=debug,
			mydbapi=self.portdb, tree="porttree",
			fd_pipes=fd_pipes, returnpid=True)

		os.close(slave_fd)
		null_input.close()

		if isinstance(retval, int):
			# doebuild failed before spawning
			self._unregister()
			self._set_returncode((self.pid, retval << 8))
			self.wait()
			return

		self.pid = retval[0]
		portage.process.spawned_pids.remove(self.pid)
Пример #49
0
def _test_pty_eof():
    """
	Returns True if this issues is fixed for the currently
	running version of python: http://bugs.python.org/issue5380
	Raises an EnvironmentError from openpty() if it fails.
	"""

    use_fork = False

    test_string = 2 * "blah blah blah\n"
    test_string = _unicode_decode(test_string,
                                  encoding='utf_8',
                                  errors='strict')

    # may raise EnvironmentError
    master_fd, slave_fd = pty.openpty()

    # Non-blocking mode is required for Darwin kernel.
    fcntl.fcntl(master_fd, fcntl.F_SETFL,
                fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

    # Disable post-processing of output since otherwise weird
    # things like \n -> \r\n transformations may occur.
    mode = termios.tcgetattr(slave_fd)
    mode[1] &= ~termios.OPOST
    termios.tcsetattr(slave_fd, termios.TCSANOW, mode)

    # Simulate a subprocess writing some data to the
    # slave end of the pipe, and then exiting.
    pid = None
    if use_fork:
        pids = spawn_bash(_unicode_encode("echo -n '%s'" % test_string,
                                          encoding='utf_8',
                                          errors='strict'),
                          env=os.environ,
                          fd_pipes={
                              0: sys.stdin.fileno(),
                              1: slave_fd,
                              2: slave_fd
                          },
                          returnpid=True)
        if isinstance(pids, int):
            os.close(master_fd)
            os.close(slave_fd)
            raise EnvironmentError('spawn failed')
        pid = pids[0]
    else:
        os.write(
            slave_fd,
            _unicode_encode(test_string, encoding='utf_8', errors='strict'))
    os.close(slave_fd)

    # If using a fork, we must wait for the child here,
    # in order to avoid a race condition that would
    # lead to inconsistent results.
    if pid is not None:
        os.waitpid(pid, 0)

    master_file = os.fdopen(master_fd, 'rb')
    eof = False
    data = []
    iwtd = [master_file]
    owtd = []
    ewtd = []

    while not eof:

        events = select.select(iwtd, owtd, ewtd)
        if not events[0]:
            eof = True
            break

        buf = array.array('B')
        try:
            buf.fromfile(master_file, 1024)
        except (EOFError, IOError):
            eof = True

        if not buf:
            eof = True
        else:
            data.append(
                _unicode_decode(buf.tostring(),
                                encoding='utf_8',
                                errors='strict'))

    master_file.close()

    return test_string == ''.join(data)
Пример #50
0
 def BuildFile(self):
     fd, self.fname = mkstemp()
     f = os.fdopen(fd, "w")
     f.write("\n".join(test_cps))
     f.close()
Пример #51
0
    def _start(self):
        settings = self.settings
        settings.setcpv(self.cpv)
        ebuild_path = self.ebuild_path

        eapi = None
        if eapi is None and \
         'parse-eapi-ebuild-head' in settings.features:
            eapi = portage._parse_eapi_ebuild_head(
                codecs.open(_unicode_encode(ebuild_path,
                                            encoding=_encodings['fs'],
                                            errors='strict'),
                            mode='r',
                            encoding=_encodings['repo.content'],
                            errors='replace'))

        if eapi is not None:
            if not portage.eapi_is_supported(eapi):
                self.metadata_callback(self.cpv, self.ebuild_path,
                                       self.repo_path, {'EAPI': eapi},
                                       self.ebuild_mtime)
                self._set_returncode((self.pid, os.EX_OK))
                self.wait()
                return

            settings.configdict['pkg']['EAPI'] = eapi

        debug = settings.get("PORTAGE_DEBUG") == "1"
        master_fd = None
        slave_fd = None
        fd_pipes = None
        if self.fd_pipes is not None:
            fd_pipes = self.fd_pipes.copy()
        else:
            fd_pipes = {}

        fd_pipes.setdefault(0, sys.stdin.fileno())
        fd_pipes.setdefault(1, sys.stdout.fileno())
        fd_pipes.setdefault(2, sys.stderr.fileno())

        # flush any pending output
        for fd in fd_pipes.values():
            if fd == sys.stdout.fileno():
                sys.stdout.flush()
            if fd == sys.stderr.fileno():
                sys.stderr.flush()

        fd_pipes_orig = fd_pipes.copy()
        self._files = self._files_dict()
        files = self._files

        master_fd, slave_fd = os.pipe()
        fcntl.fcntl(master_fd, fcntl.F_SETFL,
                    fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)

        fd_pipes[self._metadata_fd] = slave_fd

        self._raw_metadata = []
        files.ebuild = os.fdopen(master_fd, 'rb')
        self._reg_id = self.scheduler.register(files.ebuild.fileno(),
                                               self._registered_events,
                                               self._output_handler)
        self._registered = True

        retval = portage.doebuild(ebuild_path,
                                  "depend",
                                  settings["ROOT"],
                                  settings,
                                  debug,
                                  mydbapi=self.portdb,
                                  tree="porttree",
                                  fd_pipes=fd_pipes,
                                  returnpid=True)

        os.close(slave_fd)

        if isinstance(retval, int):
            # doebuild failed before spawning
            self._unregister()
            self._set_returncode((self.pid, retval))
            self.wait()
            return

        self.pid = retval[0]
        portage.process.spawned_pids.remove(self.pid)
	def BuildFile(self):
		fd, self.fname = mkstemp()
		f = os.fdopen(fd, 'w')
		for c in self.cpv:
			f.write("%s %s\n" % (c,' '.join(self.keywords)))
		f.close()