我正在尝试开发一个简单的“telnet/服务器”守护程序,该守护程序必须在新的套接字连接上运行程序。
这部分工作正常。
但是我必须将我的新流程与pty相关联,因为该流程具有某些终端功能(如readline)。
我开发的代码是(其中socketfd是新输入连接的新套接字文件描述符):
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);
}
}
使用该代码,我的“prgName”的stdin/stdout/stderr文件描述符与套接字关联(当使用ls -la/proc/PID/fd查找时),因此,此过程的终端功能不起作用。
通过远程设备上的ssh/sshd进行连接并执行“localy”(在ssh连接下)prgName的测试显示此进程“prgName”的stdin/stdout/stderr fd与pty相关联(因此该过程的终端功能运行正常)。
我做错了什么?
如何将我的socketfd与pty(由forkpty创建)关联?
感谢
亚历克斯
最佳答案
您必须编写一些代码才能将数据从套接字传输到主pty,反之亦然。通常是父流程的工作。请注意,数据传输必须是双向的。有很多选项:一个由select()驱动的周期,可同时跟踪masterfd和socketfd
(仅作为提示,非常糟糕的代码,不适用于生产!!缺少错误和eof检查!!!)
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);
}
或一对线程,一个用于socketfd-> masterfd,另一个用于masterfd-> sockefd传输。
(仅作为提示,非常糟糕的代码,不适用于生产!!!)
/*thread 1 */
while (read(masterfd,&c,1) > 0)
write(socketfd,&c,1);
/*thread 2 */
while (read(socketfd,&c,1) > 0)
write(masterfdfd,&c,1);
无论如何,您必须在分支的父级中添加一些代码。
问候
- -编辑 - -
当然,您不能在子进程中将fd 0,1和2重定向到socketfd。
关于c - forkpty- socket ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2500344/