Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

select blocked?

14 views
Skip to first unread message

kafa...@my-deja.com

unread,
Nov 20, 2000, 3:00:00 AM11/20/00
to
Hi,All!
I am a newbie to python and try to write a middle layer
between the telnet and rxvt to provide some special analyse function. I
use the select module to listen on the stdin and pty-master-end which
connected with the telnet. but the select statement seems blocked when
the string passed from telnet not ended with a NewLine character. I
have searched the archive but chould not find the answer, can you give
me a help? thanks!
The source is attached.
---------------------------
#!/usr/bin/env python

import sys
import os
import pty
import select

def main():

(pid, fd) = pty.fork()

if pid == -1:
print "Couldn't fork"
sys.exit(1)
if pid == 0: # child process
os.execvp('telnet', ('telnet','localhost',))

# parent process
while 1:
delay = 1
(r,w,e) = select.select( [sys.stdin.fileno(), fd], [], [],
delay)
for File in r:
if File == sys.stdin.fileno():
#from_user = sys.stdin.read()
#from_user = sys.stdin.raw_input()
from_user = os.read( 0, 1024)
print "user input:"+from_user
if from_user == "q": break
#os.write( fd, from_user )

if File == fd:
from_telnet = os.read(fd, 1024)
sys.stdout.write( from_telnet )

if __name__ == '__main__': main()
---------------------------


Sent via Deja.com http://www.deja.com/
Before you buy.

Donn Cave

unread,
Nov 20, 2000, 3:00:00 AM11/20/00
to
Quoth kafa...@my-deja.com:

| I am a newbie to python and try to write a middle layer
| between the telnet and rxvt to provide some special analyse function. I
| use the select module to listen on the stdin and pty-master-end which
| connected with the telnet. but the select statement seems blocked when
| the string passed from telnet not ended with a NewLine character. I
| have searched the archive but chould not find the answer, can you give
| me a help? thanks!

The UNIX terminal driver is a line oriented device, it holds on to
your input line so that it can process backspaces and things like
that. If you want your program to see input immediately and directly,
you can turn this feature off, with the POSIX terminal control functions.
Afterwards, put it back the way it was!

Your program is appended, modified to do this. For more information on
the tty control bits, check your man pages. On my host that's
"man 4 termios", but the location varies from one platform to another.

Donn Cave, do...@u.washington.edu
----------------------------------------


#!/usr/bin/env python
import sys
import os
import pty
import select

import termios
import TERMIOS

def main():

(pid, fd) = pty.fork()
# Python won't return -1, rather will raise exception.


if pid == 0: # child process

try:


os.execvp('telnet', ('telnet','localhost',))

except:
# must not return to caller.
os._exit(0)

# parent process

iflag, oflag, cflag, lflag, ispeed, ospeed, cc = termios.tcgetattr(0)
lflag = lflag
raw_lflag = lflag & ~(TERMIOS.ICANON|TERMIOS.ECHO)
raw_iflag = iflag & ~(TERMIOS.ICRNL)
raw_cc = cc[:]
raw_cc[TERMIOS.VMIN] = 1
raw_cc[TERMIOS.VTIME] = 0
termios.tcsetattr(0, TERMIOS.TCSANOW, [raw_iflag, oflag, cflag,
raw_lflag, ispeed, ospeed, raw_cc])
try:


while 1:
delay = 1

from_user = ''
(r,w,e) = select.select([0, fd], [], [], delay)
for File in r:
if File == 0:
from_user = os.read(0, 1024)
# print 'user input:', repr(from_user)
os.write(fd, from_user)

if File == fd:
from_telnet = os.read(fd, 1024)

os.write(1, from_telnet)


if from_user == 'q':
break

except:
termios.tcsetattr(0, TERMIOS.TCSANOW, [iflag, oflag, cflag,
lflag, ispeed, ospeed, cc])
raise
termios.tcsetattr(0, TERMIOS.TCSANOW, [iflag, oflag, cflag,
lflag, ispeed, ospeed, cc])

if __name__ == '__main__':
main()

---------- Bonus version --------------


#!/usr/bin/env python
import sys
import os
import pty
import select

import termios
import TERMIOS

class TTY:
def __init__(self):
self.iflag, self.oflag, self.cflag, self.lflag, \
self.ispeed, self.ospeed, self.cc = termios.tcgetattr(0)
def raw(self):
raw_lflag = self.lflag & ~(TERMIOS.ICANON|TERMIOS.ECHO)
raw_iflag = self.iflag & ~(TERMIOS.ICRNL)
raw_cc = self.cc[:]
raw_cc[TERMIOS.VMIN] = 1
raw_cc[TERMIOS.VTIME] = 0
termios.tcsetattr(0, TERMIOS.TCSANOW, [raw_iflag, self.oflag,
self.cflag, raw_lflag, self.ispeed, self.ospeed,
raw_cc])
def restore(self):
termios.tcsetattr(0, TERMIOS.TCSANOW, [self.iflag, self.oflag,
self.cflag, self.lflag, self.ispeed, self.ospeed,
self.cc])

def main():
pid, fd = pty.fork()
# Python won't return -1, rather will raise exception.


if pid == 0: # child process

try:


os.execvp('telnet', ('telnet','localhost',))

except:
# must not return to caller.
os._exit(0)

# parent process

input = TTY()
input.raw()

try:


while 1:
delay = 1

from_user = ''
r, w, e = select.select([0, fd], [], [], delay)
for File in r:
if File == 0:
from_user = os.read(0, 1024)
# print 'user input:', repr(from_user)
os.write(fd, from_user)

if File == fd:
from_telnet = os.read(fd, 1024)

os.write(1, from_telnet)


if from_user == 'q':
break

except:
input.restore()
raise
input.restore()

0 new messages