...
Code Block |
---|
cchild = fork(); // fork 函数的返回,子进程从此处执行,子进程返回 0,父进程返回子进程的 pid,错误返回 -1,errorno 说明错误原因 switch (cchild) { case 0: errlog(LOG_DEBUG, "child of %d execing %s", getppid(), av[0]); // evecvp 执行的是 ssh 命令,此处阻塞执行 execvp(av[0], av); errlog(LOG_ERR, "%s: %s", av[0], strerror(errno)); /* else can loop restarting! */ // 使用 SIGTERM kill 父进程 kill(getppid(), SIGTERM); _exit(1); break; case -1: // 出错的情况下 cchild = 0; xerrlog(LOG_ERR, "fork: %s", strerror(errno)); break; default: // 父进程继续执行 errlog(LOG_INFO, "ssh child pid is %d", (int)cchild); set_sig_handlers(); retval = ssh_watch(sock); dolongjmp = 0; clear_alarm_timer(); unset_sig_handlers(); if (retval == P_EXITOK || retval == P_EXITERR) return retval; break; } |
...
监控子进程
在 conn_test 函数中实现了监听端口了传输数据的流程,用于 ssh 进程的隧道是否联通。
Code Block |
---|
conn_test
|-- conn_remote(char *host, char *port)
|-- conn_poll_for_accept(int sock, struct pollfd *pfd)
|-- conn_send_and_receive(char *rp, char *wp, size_t len, struct pollfd *pfd, int ntopoll) |
程序启动时已经调用了 conn_listen
监听端口。conn_test
调用的三个程序分别负责连接,accept
以及发送接收数据。
循环的时候,通过 SIGALRM 信号触发的连接测试,并定时准备下一次测试。