我正在实施自己的小外壳。如果我没有为这两个子进程创建新组,ls | cat
和ls | more
都可以正常工作。
但是,在我为这两个进程创建一个新进程组(第一个ls
进程是领导进程)后,只需在父进程中调用setpgid
即可。 ls | cat
始终有效但ls | more
挂起。
看起来我的一个进程陷入dup2
系统调用。还有其他我需要考虑的事情吗?如果在ls
进程调用setpgid
之前more
首先终止,会发生什么情况?我是否需要阻止ls
进程在execve
进程完成setpgid
之前不致电more
?
编辑:
我的代码:
有时会卡住。但是当我尝试添加printf
来定位时,它已成功完成。没有错误。
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define CHECK(syscall, msg) do { \
if ((syscall) == -1) { \
perror(msg); \
exit(1); \
} \
} while(0)
#define SAFE_CLOSE_NOT_STD(fd) do { \
if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != -1) { \
CHECK(close(fd), "close error"); \
fd = -1; \
} \
} while(0)
int main () {
int ls_pid, more_pid;
int pipefd[2];
char *ls_argv[] = { "/bin/ls", NULL };
char *more_argv[] = { "/usr/bin/more", NULL };
CHECK(pipe(pipefd), "pipe error");
CHECK(ls_pid = fork(), "fork error");
if (!ls_pid) {
CHECK(dup2(pipefd[1], STDOUT_FILENO), "dup2 error");
CHECK(close(pipefd[1]), "close error");
CHECK(execvp(ls_argv[0], ls_argv), "execvp error");
} else {
SAFE_CLOSE_NOT_STD(pipefd[1]);
}
setpgid(ls_pid, ls_pid);
CHECK(more_pid = fork(), "fork error");
if (!more_pid) {
CHECK(dup2(pipefd[0], STDIN_FILENO), "dup2 error");
CHECK(close(pipefd[0]), "close error");
CHECK(execvp(more_argv[0], more_argv), "execvp error");
} else {
SAFE_CLOSE_NOT_STD(pipefd[0]);
}
setpgid(more_pid, ls_pid); // it works if I remove this line
CHECK(wait(NULL), "wait error");
CHECK(wait(NULL), "wait error");
printf("Finish\n");
}
答案 0 :(得分:1)
Use _exit()
, not exit()
, after fork()
。 (这不是真正的问题,但你应该解决它。)
这里发生的是more
不在当前前台进程组中,因此不允许从终端读取输入并获取SIGTTIN
。 Use tcsetpgrp