forkpty - 套接字

发布于 2024-08-26 18:32:12 字数 984 浏览 11 评论 0原文

我正在尝试开发一个简单的“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 创建)关联?

感谢

Alex

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘦怹 2024-09-02 18:32:12

您必须编写一些代码来将数据从套接字传输到主 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。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文