【发布时间】:2014-12-01 07:42:07
【问题描述】:
谁能告诉我这段代码有什么问题。当我将该管道输出端用作另一个命令的输入时,我能够成功地写入管道,但无法获得输出。下面是代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> //for pid_t fork() and other system calls
#include <signal.h> //for signal()
#include <sys/types.h>
void command_EXECUTER(char *args[]);
void command_HANDLER(char *args[]);
int pipe_EXECUTER(char *args[], int in, int pos);
void shell_INIT(){
int is_interactive = isatty(STDOUT_FILENO);
if(is_interactive){
}
}
int main(int argc, char *argv[], char **envp){
char shell_INPUT[1024];
char *tokens[256];
int tok_counts = 0;
while(1){
memset(shell_INPUT,'\0',sizeof(shell_INPUT));
printf("\n%s@%s: ",getenv("USER"),getenv("SESSION"));
fgets(shell_INPUT,1024,stdin);
if((tokens[0] = strtok(shell_INPUT," \n)\t")) == NULL) continue;
tok_counts = 1;
while((tokens[tok_counts] = strtok(NULL, " \n\t")) != NULL) tok_counts++;
/*
int i=0;
while(tokens[i]){
printf("%s ",tokens[i]);
i++;
}
tokens[tok_counts] = NULL;*/
command_HANDLER(tokens);
}
return 0;
}
int fileIO_EXECUTER(char *args[], int in, int pos){
int fd;
pid_t pid;
if((pid=fork())==0){
switch(pos){
case 0:
dup2(fd, STDOUT_FILENO);
break;
}
}
}
int pipe_EXECUTER(char *args[], int in, int pos){
int fd[2];
pid_t pid;
pipe(fd);
if((pid=fork())==0){
printf("%s %s %s %d\n",args[0],args[1],args[2],pid);
fflush(stdout);
switch(pos){
case 0: dup2(fd[1], STDOUT_FILENO); //first command
//close(fd[1]);
break;
case 1: dup2(in, STDIN_FILENO); //in between command
dup2(fd[1], STDOUT_FILENO);
//close(fd[1]);
break;
case 2: dup2(in, STDIN_FILENO); //last command
//close(fd[1]);
break;
default: printf("wrong input variable\nexiting");
exit(1);
}
if(execvp(args[0],args)==-1) printf("%s: command not found",args[0]); fflush(stdout); kill(getpid(),SIGTERM);
}else if(pid<0){
printf("couldn't create child");
exit(1);
}else{
wait(pid);
}
return fd[0];
}
void command_EXECUTER(char *args[]){
pid_t pid;
if((pid=fork())<0){
printf("couldn't create the child");
exit(1);
}
else if(pid==0){
if((execvp(args[0],args))==-1) printf("%s: command not found",args[0]); fflush(stdout); kill(getpid(),SIGTERM);
}
else wait(pid);
}
void command_HANDLER(char *args[]){
int i=0;
int j=0;
char spec_chars[100];
while(args[i]){
if((strcmp(args[i],">")==0) || (strcmp(args[i],"<")==0) || (strcmp(args[i],"|")==0) || (strcmp(args[i],"&")==0) || (strcmp(args[i],"$")==0)){
spec_chars[j] = *args[i];
j++;
}
i++;
}
if(j==0){
if(strcmp(args[0],"exit")==0) exit(0);
else if(strcmp(args[0],"clear")==0) system("clear");
else command_EXECUTER(args);
}
else{
int in = 0;
int h = 0;
int pos=0;
char data[1024];
int k=i;
i = 0;
while(args[i]){
if(strcmp(args[i],"|")==0){
args[i] = (char *)NULL;
in = pipe_EXECUTER(args,in,pos);
int n = read(in,data,sizeof(data));
printf("%s %d\n",data,n);
fflush(stdout);
args = args+i+1;
//printf("%s something %s",args[0],args[1]);
pos = 1;
i=0;
}else if(strcmp(args[i],"<")==0){
}else if(strcmp(args[i],">")==0){
}else if(strcmp(args[i],"&")==0){
}
else{
i++;
}
}
in = pipe_EXECUTER(args,in,2);
}
}
例如,如果我使用
ls |排序
'in' 描述符里面会有 ls 但是 当'sort'访问相同的输出时,它会挂在那里......或者执行该命令的子进程永远不会死,并且由于这个父进程一直在等待。
【问题讨论】:
-
请编译所有警告和调试信息 (
gcc -Wall -Wextra -g) 然后使用调试器 (gdb);还针对每个syscalls(2) 测试失败(并在失败时使用perror)。也可以考虑使用strace&valgrind -
其实我才刚开始,不知道如何使用gdb或其他调试工具..如果你能帮忙..谢谢
-
不,你需要学习
gdb。这是一项可以使用多年的技能!阅读GDB documentation -
嘿,@BasileStarynkevitch 我研究并尝试了所有 gdb、strace 和 valgrind,但仍然没有运气:(
-
一些错误需要数周才能被发现。祝你好运!不要放弃。休息一下,然后继续寻找你的错误。不要忘记阅读您正在使用的每个系统调用的文档。特别是,您对
dup2的使用是错误的:您没有处理dup2的失败。另外,请在fork之前致电fflush