Forkpty - Nest

I am trying to develop a simple telnet / server daemon that should run the program on a new socket connection. This part is working fine.

But I need to associate my new process with pty, because this process has some terminal capabilities (for example, readline).

The code I developed is (where socketfd is the new socket file descriptor for the new input connection):

int masterfd, pid; const char *prgName = "..."; char *arguments[10] = ....; if ((pid = forkpty(&masterfd, NULL, NULL, NULL)) < 0) perror("FORK"); else if (pid) return pid; else { close(STDOUT_FILENO); dup2(socketfd, STDOUT_FILENO); close(STDIN_FILENO); dup2(socketfd, STDIN_FILENO); close(STDERR_FILENO); dup2(socketfd, STDERR_FILENO); if (execvp(prgName, arguments) < 0) { perror("execvp"); exit(2); } } 

With this code, the file descriptor stdin / stdout / stderr of my "prgName" is associated with the socket (when viewed with ls -la / proc / PID / fd), and therefore the terminal capabilities of this process do not work.

The tests with connecting via ssh / sshd on the remote device and running "localy" (under the ssh connection) prgName show that stdin / stdout / stderr fd of this process "prgName" are connected with pty (and therefore the terminal capabilities of this process work fine) .

What am I doing wrong? How to bind my socketfd with pty (created by forkpty)?

thanks

Alex

+4
source share
1 answer

You must write code to transfer data from the socket to master pty and vice versa. This is usually the task of the parent process. Please note that data transfer must be bidirectional. There are many options: a select () loop that tracks both masterfd and socketfd

(just like a hint, very bad code, not for production !!! There is no error and eof check !!!)

 for (;;) { FD_ZERO(&set); FD_SET(masterfd,&set); FD_SET(socketfd,&set); select(...,&set,...); if (FD_ISSET(masterfd,&set)) { read(masterfd,&c,1); write(socketfd,&c,1); } if (FD_ISSET(sockerfd,&set)) { read(sochetfd,&c,1); write(masterfd,&c,1); } 

or a couple of threads, one for socketfd-> masterfd and one for transfers masterfd-> sockefd.

(just like a hint, very bad code, not for production !!!)

 /*thread 1 */ while (read(masterfd,&c,1) > 0) write(socketfd,&c,1); /*thread 2 */ while (read(socketfd,&c,1) > 0) write(masterfdfd,&c,1); 

In any case, you should add the code to the parent side of the branch.

Hi

--- EDIT --- Of course, you should not redirect fd 0,1 and 2 to socketfd in the child process.

+4
source

Source: https://habr.com/ru/post/1304880/


All Articles