I'm trying to develop a simple "telnet/server" daemon which have to run a program on a new socket connection. This part working fine.
But I have to associate my new process to a pty, because this process have some terminal capabilities (like a readline).
The code I've developped 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 that code, the stdin / stdout / stderr file descriptor of my "prgName" are associated to the socket (when looking with ls -la /proc/PID/fd), and so, the terminal capabilities of this process doesn't work.
A test with a connection via ssh/sshd on the remote device, and executing "localy" (under the ssh connection) prgName, show that the stdin/stdout/stderr fd of this process "prgName" are associated to a pty (and so the terminal capabilities of this process are working fine).
What I am doing wrong? How to associate my socketfd with the pty (created by forkpty) ?
Thank
Alex
You must write some code to transfer data from the socket to the master pty and vice versa. It's usually a parent process' job. Note that the data transfer must be bidirectional. There are many options: a select()-driven cycle to track both the masterfd and the socketfd
(just as hint, very bad code, not for production!!! Missing error and eof checks!!!)
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 pair of threads, one for socketfd->masterfd and one for masterfd->sockefd transfers.
(just as 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);
Anyway you must add some code in the parent side of the branch.
Regards
---EDIT--- Of course, you must not redirect fd 0,1 and 2 to socketfd in the child process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With