Skip to content

Commit c359571

Browse files
committed
Use select in tubes.interactive()
1 parent 6457c33 commit c359571

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

pwnlib/tubes/tube.py

+27-13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import abc
66
import logging
77
import re
8+
import select
89
import six
910
import string
1011
import subprocess
@@ -17,6 +18,7 @@
1718
from pwnlib import atexit
1819
from pwnlib import term
1920
from pwnlib.context import context
21+
from pwnlib.exception import PwnlibException
2022
from pwnlib.log import Logger
2123
from pwnlib.timeout import Timeout
2224
from pwnlib.tubes.buffer import Buffer
@@ -862,21 +864,33 @@ def recv_thread():
862864
t.start()
863865

864866
try:
865-
while not go.isSet():
866-
if term.term_mode:
867-
data = term.readline.readline(prompt = prompt, float = True)
868-
else:
869-
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
870-
data = stdin.read(1)
867+
while not go.isSet() and self.connected():
868+
# Block until there is input on stdin or there's input on the receiving side
869+
try:
870+
rfds, _, _ = select.select([sys.stdin, self], [], [])
871+
except PwnlibException:
872+
# If the process stops while we're waiting for input, an
873+
# exception will be thrown
874+
go.set()
875+
continue
871876

872-
if data:
873-
try:
874-
self.send(data)
875-
except EOFError:
877+
# If the there's input on stdin, handle it. Otherwise, on the
878+
# next iteration of the loop we'll check if the receiving side disconnected
879+
if sys.stdin in rfds:
880+
if term.term_mode:
881+
data = term.readline.readline(prompt = prompt, float = True)
882+
else:
883+
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
884+
data = stdin.read(1)
885+
886+
if data:
887+
try:
888+
self.send(data)
889+
except EOFError:
890+
go.set()
891+
self.info('Got EOF while sending in interactive')
892+
else:
876893
go.set()
877-
self.info('Got EOF while sending in interactive')
878-
else:
879-
go.set()
880894
except KeyboardInterrupt:
881895
self.info('Interrupted')
882896
go.set()

0 commit comments

Comments
 (0)