| 198 | |
| 199 | @unittest.skip('TODO: RUSTPYTHON; "Not runnable. tty.tcgetwinsize" is required to setUp') |
| 200 | def test_fork(self): |
| 201 | debug("calling pty.fork()") |
| 202 | pid, master_fd = pty.fork() |
| 203 | self.addCleanup(os.close, master_fd) |
| 204 | if pid == pty.CHILD: |
| 205 | # stdout should be connected to a tty. |
| 206 | if not os.isatty(1): |
| 207 | debug("Child's fd 1 is not a tty?!") |
| 208 | os._exit(3) |
| 209 | |
| 210 | # After pty.fork(), the child should already be a session leader. |
| 211 | # (on those systems that have that concept.) |
| 212 | debug("In child, calling os.setsid()") |
| 213 | try: |
| 214 | os.setsid() |
| 215 | except OSError: |
| 216 | # Good, we already were session leader |
| 217 | debug("Good: OSError was raised.") |
| 218 | pass |
| 219 | except AttributeError: |
| 220 | # Have pty, but not setsid()? |
| 221 | debug("No setsid() available?") |
| 222 | pass |
| 223 | except: |
| 224 | # We don't want this error to propagate, escaping the call to |
| 225 | # os._exit() and causing very peculiar behavior in the calling |
| 226 | # regrtest.py ! |
| 227 | # Note: could add traceback printing here. |
| 228 | debug("An unexpected error was raised.") |
| 229 | os._exit(1) |
| 230 | else: |
| 231 | debug("os.setsid() succeeded! (bad!)") |
| 232 | os._exit(2) |
| 233 | os._exit(4) |
| 234 | else: |
| 235 | debug("Waiting for child (%d) to finish." % pid) |
| 236 | # In verbose mode, we have to consume the debug output from the |
| 237 | # child or the child will block, causing this test to hang in the |
| 238 | # parent's waitpid() call. The child blocks after a |
| 239 | # platform-dependent amount of data is written to its fd. On |
| 240 | # Linux 2.6, it's 4000 bytes and the child won't block, but on OS |
| 241 | # X even the small writes in the child above will block it. Also |
| 242 | # on Linux, the read() will raise an OSError (input/output error) |
| 243 | # when it tries to read past the end of the buffer but the child's |
| 244 | # already exited, so catch and discard those exceptions. It's not |
| 245 | # worth checking for EIO. |
| 246 | while True: |
| 247 | try: |
| 248 | data = os.read(master_fd, 80) |
| 249 | except OSError: |
| 250 | break |
| 251 | if not data: |
| 252 | break |
| 253 | sys.stdout.write(str(data.replace(b'\r\n', b'\n'), |
| 254 | encoding='ascii')) |
| 255 | |
| 256 | ##line = os.read(master_fd, 80) |
| 257 | ##lines = line.replace('\r\n', '\n').split('\n') |