简体   繁体   中英

Disable echo with pseudoterminal connected to socket

I am writing a TCP server application that interacts with terminals. It accepts incoming TCP connections directly and then handles I/O all within the process. One requirement is to be able to disable echo when necessary, nothing too out of the ordinary.

I was initially trying to call tcgetattr directly on the TCP socket fd, which failed since you can't call tcgetattr and tcsetattr on sockets, you have to call them on TTY/PTY fds. So I created a pseudoterminal pair and inserted them in the middle. The master fd relays to the TCP socket fd.

Now, I am able to disable canonical mode, but for some reason I can't disable the echo.

I have the following architecture:

[Client] <--- TCP socket ---> [Server] socket fd <---> PTY master <---> PTY slave

This is all in a single process. I'm not doing forkpty type stuff like most PTY examples do. I'm simply launching another thread to handle the PTY master, which relays between the PTY master FD and the socket FD. The actual application thread reads and writes only using the slave FD.

All the examples I see of putting the PTY into "raw" mode (to disable echo, etc.) do so on STDIN_FILENO , which in my case would be where the socket fd is (for example, The Linux Programming Interface, ch. 62-4):

if (ttySetRaw(STDIN_FILENO, &userTermios) == -1)
 errExit("ttySetRaw");

These program examples all assume a program is launched from a terminal, but in my case, since my program is the.network login service, it's creating a pseudoterminal from scratch and relaying directly to the socket: there's no "STDIN" in the middle anywhere, and this is a multithreaded program so using STDIN would make no sense.

tcsetattr succeeds for term.c_lflag &= ~ECHO; on the slave FD, but clearly this doesn't seem to be sufficient. Since you can't do terminal operations directly on socket FDs, how would I properly disable echo here? If I debug data relayed in the PTY master thread, I'm not seeing input characters relayed back to the socket, but yet I still see them on the terminal. If I try to call tcsetattr on the master FD, this not only doesn't work but also has the effect of re-enabling input buffering, making the problem worse. But these are the only fds I can touch, so I'm confused what else to try here.

Ended up finding that this was due to Te.net's local echo, not anything pseudoterminal-related after all.

This can't be disabled using termios , you have to send Te.net escape sequences to do so:

#include <arpa/telnet.h>

unsigned char echo_ctl[] = {IAC, WILL, TELOPT_ECHO}; 
write(fd, echo_ctl, 3);

Source: http://www.verycomputer.com/174_d636f401932e1db5_1.htm


Similarly, if using a tool like.netcat to test, you'd want to do something like stty -echo && nc 127.0.0.1 23

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM