2 import subprocess, socket, fcntl, select
4 class sshsocket(object):
5 def __init__(self, host, path, user = None, port = None):
8 args += ["-u", str(user)]
10 args += ["-p", str(int(port))]
12 args += ["python3", "-m", "pdm.sshsock", path]
13 self.proc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
14 self.inbuf = bytearray()
15 fcntl.fcntl(self.proc.stdout, fcntl.F_SETFL, fcntl.fcntl(self.proc.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
18 raise socket.error("unexpected reply from %s: %r" % (host, head))
25 raise socket.error("unexpected EOF in SSH socket stream")
37 raise socket.error(buf.decode("utf-8"))
39 raise socket.error("unexpected reply from %s: %r" % (host, head))
42 if self.proc is not None:
43 self.proc.stdin.close()
44 self.proc.stdout.close()
48 def send(self, data, flags = 0):
49 self.proc.stdin.write(data)
50 self.proc.stdin.flush()
53 def recv(self, buflen, flags = 0):
54 while len(self.inbuf) == 0:
56 rv = os.read(self.proc.stdout.fileno(), max(4096, buflen))
57 except BlockingIOError:
58 if flags & socket.MSG_DONTWAIT:
60 select.select([self.proc.stdout], [], [])
63 rv = bytes(self.inbuf[:buflen])
64 self.inbuf[:buflen] = b""
68 return self.proc.stdout.fileno()
74 fcntl.fcntl(sys.stdin.buffer, fcntl.F_SETFL, fcntl.fcntl(sys.stdin.buffer, fcntl.F_GETFL) | os.O_NONBLOCK)
75 sk = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
78 sk.connect(sys.argv[1])
79 except socket.error as err:
80 sys.stdout.write("SSOCK-connect: %s\n" % err)
83 sys.stdout.write("SSOCK+\n")
89 if buf1: wfd.append(sk)
90 if buf2: wfd.append(sys.stdout.buffer)
91 rfd, wfd, efd = select.select([sk, sys.stdin.buffer], wfd, [])
98 if sys.stdin.buffer in rfd:
99 ret = sys.stdin.buffer.read()
107 if sys.stdout.buffer in wfd:
108 sys.stdout.buffer.write(buf2)
109 sys.stdout.buffer.flush()
114 if __name__ == "__main__":