您似乎在描述通知管道. OpenSSH sshd主循环调用select()等待它有事可做.被轮询的文件描述符包括到客户端的TCP连接以及用于服务活动通道的任何描述符.
sshd希望能够在收到SIGCHLD信号时中断select()调用.为此,sshd为SIGCHLD安装信号处理程序,并创建一个管道.当收到SIGCHLD信号时,信号处理程序将一个字节写入管道.管道的读取结束包含在select()轮询的文件描述符列表中.写入管道的行为将导致select()调用返回,并指示通知管道是可读的.
所有代码都在serverloop.c中:
/*
* we write to this pipe if a SIGCHLD is caught in order to avoid
* the race between select() and child_terminated
*/
static int notify_pipe[2];
static void
notify_setup(void)
{
if (pipe(notify_pipe) < 0) {
error("pipe(notify_pipe) failed %s", strerror(errno));
} else if ((fcntl(notify_pipe[0], F_SETFD, 1) == -1) ||
(fcntl(notify_pipe[1], F_SETFD, 1) == -1)) {
error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno));
close(notify_pipe[0]);
close(notify_pipe[1]);
} else {
set_nonblock(notify_pipe[0]);
set_nonblock(notify_pipe[1]);
return;
}
notify_pipe[0] = -1; /* read end */
notify_pipe[1] = -1; /* write end */
}
static void
notify_parent(void)
{
if (notify_pipe[1] != -1)
write(notify_pipe[1], "", 1);
}
[...]
/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
int save_errno = errno;
child_terminated = 1;
#ifndef _UNICOS
mysignal(SIGCHLD, sigchld_handler);
#endif
notify_parent();
errno = save_errno;
}
设置和执行select调用的代码在另一个名为wait_until_can_do_something()的函数中.它相当长,所以我不会在这里包含它. OpenSSH是开源的,this page描述了如何下载源代码.