管道进程未终止
我在实现 myshell 的同时实现了管道。
进入管道的进程有 dup2 (fd[pcount][WRITEEND] ,STDOUT_FILENO) 从管道接收输入的进程有dup2(fd[pcount-1][READEND, STDIN_FILENO]) 然后我关闭了所有的fd。
我运行了所有进程并关闭了父进程中留下的所有管道 fd。
当ls |命令中输入grep c,出现grep: (standard input): Bad file detector等错误。会有什么问题呢?我关闭了所有的fd。
** 编辑:
正如你所说,我修改了一些代码。我带来了主程序 我将按位运算符(~)更改为“!”它解决了很多问题(我想我在花了一个漫长的夜晚查看代码后已经失去了冷静)
还有最后一个问题。在后台,程序运行没有任何问题,但在前台,grep打印结果后并没有退出。
对于 ls | grep.c,打印结果,但 grep 并未终止。
如果您能猜出哪个部分可能出现问题,我将不胜感激。
问题变了,所以修改了标题。 **
int main(void){
int idx = 0;
bool pipe_start_flag = false;
char cmdline[MAXLINE]; /* Command line */
while (1) {
/* Read */
// init global variable(pcount, reap_count)
pcount = 0; reap_count = 0;
printf("> ");
fgets(cmdline, MAXLINE, stdin);
if (feof(stdin))
exit(0);
/* Evaluate */
eval(cmdline);
}
}
void eval(char *cmdline){
int idx = 0, pidx = 0;
char * argv[MAXARGS];
char buffer[MAXARGS];
char * envp[2] = {"/usr/bin/", "0"};
int fd[MAXPIP][2];
bool pipe_start_flag = false; // this argv print output to the WriteEnd of Pipe;
bool pipe_end_flag = false; // this argv input from ReadEnd of Pipe
bg = preproc_command(cmdline, &idx);
strcpy(buffer, cmdline);
while(buffer[idx] != '\0'){
/*check if it is piped process*/
pipe_start_flag = pipe_end_flag; // if last process was piping process, then this process is a piped process
parse_line(&buffer[idx], argv, &idx, &pipe_end_flag); // parse until it meets '\0' or '|'(assign its (index-1) on idx)
if(pipe_end_flag) // if there is '|' character we set pipe
pipe(fd[pcount]);
if(!builtin_command(argv)){
pid[pcount] = Fork();
if(pid[pcount] == 0){
if(pipe_end_flag){
dup2(fd[pcount][WRITEEND],STDOUT_FILENO);
}
if(pipe_start_flag){
dup2(fd[pcount-1][READEND] ,STDIN_FILENO);
}
for(int i = 0; i < pcount; i++){
close(fd[i][READEND]);
close(fd[i][WRITEEND]);
}
if(!pipe_start_flag || pipe_end_flag){ // if it is not the last process
close(fd[pcount][READEND]);
close(fd[pcount][WRITEEND]);
}
// we should get input from fd[READEND] and put it on argv
execvp(argv[0], argv);
}
else{ // parent proce
if(!bg){
pidx = waitpid(-1, NULL, WUNTRACED);
}
else{ // background process
}
++pcount;
}
++idx;
}
if(pipe_start_flag){ // close pipe in main process
for(int i = 1; i < pcount ; i++){
close(fd[i-1][READEND]);
close(fd[i-1][WRITEEND]);
}
}
I implemented pipes while implementing myshell.
The process for entering the pipe has dup2 (fd[pcount][WRITEEND] ,STDOUT_FILENO)
The process of receiving input from the pipe has dup2 (fd[pcount-1][READEND, STDIN_FILENO])
And I closed all fds.
And I ran all the processes and closed all the pipe fd left in the parent process.
And when ls | grep c was entered in the command, an error such as grep: (standard input): Bad file descriptor occurred. What would be the problem? I closed all the fds.
** Edited:
As you said, I modified some of the codes. I brought the main program
and I Changed the Bitwise operator(~) to '!' and it solved a lot of problems (I think I've lost my composure after spending a long night looking at the code)
There is a final problem. In the background, the program runs without any problems, but in the foreground, grep does not exit after printing the results.
For ls | grep.c, the result are printed, but grep is not terminated.
I'd appreciate it if you could guess which part could be the problem.
The problem has changed, so I have revised the title.
**
int main(void){
int idx = 0;
bool pipe_start_flag = false;
char cmdline[MAXLINE]; /* Command line */
while (1) {
/* Read */
// init global variable(pcount, reap_count)
pcount = 0; reap_count = 0;
printf("> ");
fgets(cmdline, MAXLINE, stdin);
if (feof(stdin))
exit(0);
/* Evaluate */
eval(cmdline);
}
}
void eval(char *cmdline){
int idx = 0, pidx = 0;
char * argv[MAXARGS];
char buffer[MAXARGS];
char * envp[2] = {"/usr/bin/", "0"};
int fd[MAXPIP][2];
bool pipe_start_flag = false; // this argv print output to the WriteEnd of Pipe;
bool pipe_end_flag = false; // this argv input from ReadEnd of Pipe
bg = preproc_command(cmdline, &idx);
strcpy(buffer, cmdline);
while(buffer[idx] != '\0'){
/*check if it is piped process*/
pipe_start_flag = pipe_end_flag; // if last process was piping process, then this process is a piped process
parse_line(&buffer[idx], argv, &idx, &pipe_end_flag); // parse until it meets '\0' or '|'(assign its (index-1) on idx)
if(pipe_end_flag) // if there is '|' character we set pipe
pipe(fd[pcount]);
if(!builtin_command(argv)){
pid[pcount] = Fork();
if(pid[pcount] == 0){
if(pipe_end_flag){
dup2(fd[pcount][WRITEEND],STDOUT_FILENO);
}
if(pipe_start_flag){
dup2(fd[pcount-1][READEND] ,STDIN_FILENO);
}
for(int i = 0; i < pcount; i++){
close(fd[i][READEND]);
close(fd[i][WRITEEND]);
}
if(!pipe_start_flag || pipe_end_flag){ // if it is not the last process
close(fd[pcount][READEND]);
close(fd[pcount][WRITEEND]);
}
// we should get input from fd[READEND] and put it on argv
execvp(argv[0], argv);
}
else{ // parent proce
if(!bg){
pidx = waitpid(-1, NULL, WUNTRACED);
}
else{ // background process
}
++pcount;
}
++idx;
}
if(pipe_start_flag){ // close pipe in main process
for(int i = 1; i < pcount ; i++){
close(fd[i-1][READEND]);
close(fd[i-1][WRITEEND]);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论