import os
import socket
import subprocess
import string
import logging

log = logging.getLogger('terminal')

class Terminal:
    def __init__(self, tty, socket):
        self.tty = tty
        self.socket = socket

    def __del__(self):
        self.socket.close()

TIMEOUT = 1 # Timeout in seconds for child opening a socket and sending the tty name

def create():
    socket_path = '/tmp/vscode-lldb-%d.sock' % os.getpid()
    try: os.unlink(socket_path)
    except OSError: pass
    ls = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ls.bind(socket_path)
    ls.listen(1)
    subprocess.Popen(['x-terminal-emulator', '-e', 'bash -c "tty | nc -U %s -q -1"' % socket_path]);

    try:
        ls.settimeout(TIMEOUT)
        conn, addr = ls.accept()
        os.unlink(socket_path)

        conn.settimeout(TIMEOUT)
        data = ''
        while True:
            data += conn.recv(32)
            lines = string.split(data, '\n')
            if len(lines) > 1:
                return Terminal(lines[0], conn)

    except (OSError, socket.timeout):
        raise Exception('Failed to create a new terminal')

import os
import socket
import subprocess
import string
import logging

log = logging.getLogger('terminal')

class Terminal:
    def __init__(self, tty, socket):
        self.tty = tty
        self.socket = socket

    def __del__(self):
        self.socket.close()

TIMEOUT = 3 # Timeout in seconds for child opening a socket and sending the tty name

def create():
    ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ls.bind(('127.0.0.1', 0))
    ls.listen(1)
    addr, port = ls.getsockname()
    # Open a TCP connection, send output of `tty`, wait till the socket gets closed from our end
    command = 'exec 3<>/dev/tcp/127.0.0.1/%d; tty >&3; read <&3' % port
    subprocess.Popen(['x-terminal-emulator', '-e', 'bash -c "%s"' % command]);

    try:
        ls.settimeout(TIMEOUT)
        conn, addr = ls.accept()
        conn.settimeout(TIMEOUT)
        output = ''
        while True:
            data = conn.recv(32)
            if len(data) == 0:
                reason = 'connection aborted'
                break
            log.info('received %s', data)
            output += data
            lines = string.split(output, '\n')
            if len(lines) > 1:
                return Terminal(lines[0], conn)
    except (OSError, socket.timeout):
        reason = 'timeout'

    raise Exception('Failed to create a new terminal: %s' % reason)

Use bash's built-in tcp support, drop dependency on netcat.
Use bash's built-in tcp support, drop dependency on netcat.

  import os
  import socket
  import subprocess
  import string
  import logging
  
  log = logging.getLogger('terminal')
  
  class Terminal:
      def __init__(self, tty, socket):
          self.tty = tty
          self.socket = socket
  
      def __del__(self):
          self.socket.close()
  
- TIMEOUT = 1 # Timeout in seconds for child opening a socket and sending the tty name
+ TIMEOUT = 3 # Timeout in seconds for child opening a socket and sending the tty name
  
  def create():
-     socket_path = '/tmp/vscode-lldb-%d.sock' % os.getpid()
-     try: os.unlink(socket_path)
-     except OSError: pass
-     ls = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+     ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-     ls.bind(socket_path)
+     ls.bind(('127.0.0.1', 0))
      ls.listen(1)
+     addr, port = ls.getsockname()
+     # Open a TCP connection, send output of `tty`, wait till the socket gets closed from our end
+     command = 'exec 3<>/dev/tcp/127.0.0.1/%d; tty >&3; read <&3' % port
-     subprocess.Popen(['x-terminal-emulator', '-e', 'bash -c "tty | nc -U %s -q -1"' % socket_path]);
+     subprocess.Popen(['x-terminal-emulator', '-e', 'bash -c "%s"' % command]);
  
      try:
          ls.settimeout(TIMEOUT)
          conn, addr = ls.accept()
-         os.unlink(socket_path)
- 
          conn.settimeout(TIMEOUT)
-         data = ''
+         output = ''
          while True:
-             data += conn.recv(32)
+             data = conn.recv(32)
+             if len(data) == 0:
+                 reason = 'connection aborted'
+                 break
+             log.info('received %s', data)
+             output += data
-             lines = string.split(data, '\n')
+             lines = string.split(output, '\n')
              if len(lines) > 1:
                  return Terminal(lines[0], conn)
+     except (OSError, socket.timeout):
+         reason = 'timeout'
  
-     except (OSError, socket.timeout):
-         raise Exception('Failed to create a new terminal')
+     raise Exception('Failed to create a new terminal: %s' % reason)
  
Use bash's built-in tcp support, drop dependency on netcat.
## Code Before:
import os
import socket
import subprocess
import string
import logging

log = logging.getLogger('terminal')

class Terminal:
    def __init__(self, tty, socket):
        self.tty = tty
        self.socket = socket

    def __del__(self):
        self.socket.close()

TIMEOUT = 1 # Timeout in seconds for child opening a socket and sending the tty name

def create():
    socket_path = '/tmp/vscode-lldb-%d.sock' % os.getpid()
    try: os.unlink(socket_path)
    except OSError: pass
    ls = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    ls.bind(socket_path)
    ls.listen(1)
    subprocess.Popen(['x-terminal-emulator', '-e', 'bash -c "tty | nc -U %s -q -1"' % socket_path]);

    try:
        ls.settimeout(TIMEOUT)
        conn, addr = ls.accept()
        os.unlink(socket_path)

        conn.settimeout(TIMEOUT)
        data = ''
        while True:
            data += conn.recv(32)
            lines = string.split(data, '\n')
            if len(lines) > 1:
                return Terminal(lines[0], conn)

    except (OSError, socket.timeout):
        raise Exception('Failed to create a new terminal')

## Instruction:
Use bash's built-in tcp support, drop dependency on netcat.
## Code After:
import os
import socket
import subprocess
import string
import logging

log = logging.getLogger('terminal')

class Terminal:
    def __init__(self, tty, socket):
        self.tty = tty
        self.socket = socket

    def __del__(self):
        self.socket.close()

TIMEOUT = 3 # Timeout in seconds for child opening a socket and sending the tty name

def create():
    ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ls.bind(('127.0.0.1', 0))
    ls.listen(1)
    addr, port = ls.getsockname()
    # Open a TCP connection, send output of `tty`, wait till the socket gets closed from our end
    command = 'exec 3<>/dev/tcp/127.0.0.1/%d; tty >&3; read <&3' % port
    subprocess.Popen(['x-terminal-emulator', '-e', 'bash -c "%s"' % command]);

    try:
        ls.settimeout(TIMEOUT)
        conn, addr = ls.accept()
        conn.settimeout(TIMEOUT)
        output = ''
        while True:
            data = conn.recv(32)
            if len(data) == 0:
                reason = 'connection aborted'
                break
            log.info('received %s', data)
            output += data
            lines = string.split(output, '\n')
            if len(lines) > 1:
                return Terminal(lines[0], conn)
    except (OSError, socket.timeout):
        reason = 'timeout'

    raise Exception('Failed to create a new terminal: %s' % reason)
