* Since can_poll_pty() is unsafe due to he possibility of the poll() call
authorZac Medico <zmedico@gentoo.org>
Sun, 13 Jul 2008 13:24:39 +0000 (13:24 -0000)
committerZac Medico <zmedico@gentoo.org>
Sun, 13 Jul 2008 13:24:39 +0000 (13:24 -0000)
  blocking forever, replace it with a simpler test on /dev/null that's
  derived from a test in a glib2 configure script.

* Remove PtyReaderTestCase since it has the same problem as can_poll_pty().

svn path=/main/trunk/; revision=11039

pym/_emerge/__init__.py
pym/portage/tests/process/test_poll.py

index 12cd9c69004be5f25b7ff8c9076ab418e5ed6014..e03b570725cd23da6515f35853638b7e413bd6c5 100644 (file)
@@ -7974,57 +7974,42 @@ class SequentialTaskQueue(SlotObject):
        def __len__(self):
                return len(self._task_queue) + len(self.running_tasks)
 
-_can_poll_pty = None
+_can_poll_device = None
 
-def can_poll_pty():
+def can_poll_device():
        """
-       Test if it's possible to use poll() on a pty device. This
+       Test if it's possible to use poll() on a device such as a pty. This
        is known to fail on Darwin.
        @rtype: bool
-       @returns: True if poll() on a pty device succeeds, False otherwise.
+       @returns: True if poll() on a device succeeds, False otherwise.
        """
 
-       global _can_poll_pty
-       if _can_poll_pty is not None:
-               return _can_poll_pty
+       global _can_poll_device
+       if _can_poll_device is not None:
+               return _can_poll_device
 
        if not hasattr(select, "poll"):
-               _can_poll_pty = False
-               return _can_poll_pty
+               _can_poll_device = False
+               return _can_poll_device
 
-       got_pty, master_fd, slave_fd = \
-               portage._create_pty_or_pipe(copy_term_size=sys.stdout.fileno())
-       if not got_pty:
-               os.close(master_fd)
-               os.close(slave_fd)
-               _can_poll_pty = False
-               return _can_poll_pty
-
-       test_string = 2 * "blah blah blah\n"
-
-       master_file = os.fdopen(master_fd, 'r')
-
-       task_scheduler = TaskScheduler(max_jobs=2, poll=select.poll())
-       scheduler = task_scheduler.sched_iface
-
-       producer = SpawnProcess(
-               args=["bash", "-c", "echo -n '%s'" % test_string],
-               fd_pipes={1:slave_fd,2:slave_fd}, scheduler=scheduler)
-
-       consumer = PipeReader(
-               input_files={"producer" : master_file},
-               scheduler=scheduler)
-
-       task_scheduler.add(producer)
-       task_scheduler.add(consumer)
-
-       def producer_start_cb(task):
-               os.close(slave_fd)
+       try:
+               dev_null = open('/dev/null', 'rb')
+       except IOError:
+               _can_poll_device = False
+               return _can_poll_device
+
+       p = select.poll()
+       p.register(dev_null.fileno(), PollConstants.POLLIN)
+
+       invalid_request = False
+       for f, event in p.poll():
+               if event & PollConstants.POLLNVAL:
+                       invalid_request = True
+                       break
+       dev_null.close()
 
-       producer.addStartListener(producer_start_cb)
-       task_scheduler.run()
-       _can_poll_pty = test_string == consumer.getvalue()
-       return _can_poll_pty
+       _can_poll_device = not invalid_request
+       return _can_poll_device
 
 def create_poll_instance():
        """
@@ -8032,7 +8017,7 @@ def create_poll_instance():
        PollSelectAdapter there is no poll() implementation or
        it is broken somehow.
        """
-       if can_poll_pty():
+       if can_poll_device():
                return select.poll()
        return PollSelectAdapter()
 
index 8a52f45777084a3d55f805f6fd50190ad135d3a9..96749d567924a11a4cc97284ebfe18e29521d9cf 100644 (file)
@@ -51,19 +51,3 @@ class PipeReaderTestCase(TestCase):
                task_scheduler.run()
 
                self._assertEqual(test_string, consumer.getvalue())
-
-class PtyReaderTestCase(PipeReaderTestCase):
-
-       def _assertEqual(self, test_string, consumer_value):
-               if test_string != consumer_value:
-                       # This test is expected to fail on some operating systems
-                       # such as Darwin that do not support poll() on pty devices.
-                       self.todo = True
-               self.assertEqual(test_string, consumer_value)
-
-       def _create_pipe(self):
-
-               got_pty, master_fd, slave_fd = \
-                       portage._create_pty_or_pipe(copy_term_size=sys.stdout.fileno())
-
-               return (master_fd, slave_fd)