C语言 进程分叉外壳,然后整个程序停止?



我有一个从 pipe(2( 的手册页复制的程序,经过修改,以便子分支一个 shell,父从 stdin 读取,将命令发送到要执行的子 shell。 这适用于第一个命令,但在运行该命令后,我收到一条消息,指出程序已停止,我返回到顶级 shell。

为什么会发生这种情况,我该如何阻止它?

信号(7( 说:

SIGTTIN      P1990      Stop    Terminal input for background process

但它不应该是一个后台进程,那么为什么它会停止呢?

接下来是一个终端会话,其中包含完整的源代码,gcc -Wall 的结果,并尝试运行该程序。 如您所见,我给出命令"日期",然后我被送回 到调用 shell,然后子 shell 执行"date"并显示输出,然后出现"exit"。 "fg"让我回到pipe_shell程序中,"正常运行时间"被发送到shell并运行,然后我可以做一个"echo",然后我被发送回顶级shell,"exit"再次出现。

sh-5.0$ cat pipe_shell.c
/* pipe_shell.c - learn about pipes
*
* Modified from the man page for pipe(2).
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int   pipefd[2];
pid_t cpid;
if (argc != 1) {
fprintf(stderr, "Usage: %sn", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { // Child reads from pipe
close(pipefd[1]);              // Close unused write end of pipe
close(STDIN_FILENO);           // shut off standard input
dup2(pipefd[0], STDIN_FILENO); // pipe output is standard input
close(pipefd[0]);              // close pipe output
execl("/bin/bash", "bash",
"--norc",
"-i",
(char *) 0);
perror("exec");
} else { // Parent writes to pipe
close(pipefd[0]);    // Close unused read end
char line[256];      // we take input from keyboard
while ( fgets(line, 255, stdin) != NULL ) {
write(pipefd[1], line, strlen(line));
}
close(pipefd[1]);    // Reader will see EOF
wait(NULL);          // Wait for child
exit(EXIT_SUCCESS);
}
}
sh-5.0$ gcc -Wall pipe_shell.c -o pipe_shell
sh-5.0$ ./pipe_shell
bash-5.0$ date
date
[1]+  Stopped(SIGTTIN)        ./pipe_shell
sh-5.0$ Wed 10 Jun 2020 12:16:28 PM EDT
bash-5.0$ exit
There are stopped jobs.
sh-5.0$ fg
./pipe_shell
uptime
uptime
12:16:52 up 154 days, 23:32,  5 users,  load average: 0.04, 0.05, 0.07
bash-5.0$ echo "foo"
[1]+  Stopped(SIGTTIN)        ./pipe_shell
echo "foo"
sh-5.0$ foo
bash-5.0$ exit
exit

尝试在没有bash-i选项的情况下运行程序,尽管您不会看到提示。

过于简化的 SIGTTIN 问题与read()、控制 tty 和过程组有关。 有关详细信息,一个不错的起点是搜索词 google.com:linux SIGTTIN;有一些文章深入研究了READ/TTY/PGRP。

要运行类似于小程序的交互式shell并可能解决大型程序的问题,您可以使用主/从伪设备。 有一个相关的库服务forkpty()。 此外,还有一个名为script的 UNIX/linux 实用程序,它将交互式 shell 会话记录到常规文件中;script的源代码是读取器 + 写入器进程、主/从伪设备和交互式 shell 的一个很好的例子。

相关内容

最新更新