java 引用悬挂,C壳体在处理管道时悬挂

我正在研究一个C shell,并且在使用任意数量的管道时遇到了麻烦 . 当我运行外壳时,它会挂在任何管道上 . 出于某种原因,当我做 ls -la | sort 时,它会挂起,直到我输入东西并按下Ctrl D.我知道它与管道没有关闭有关,但是打印语句显示管道3,4,5都得到了在父母和孩子都关闭 . 我've been at this for a few hours and don'知道为什么这不起作用 . 任何帮助将非常感激 .

原始代码:

char *current_command;

current_command = strtok_r(cmdline_copy, "|", &cmdline_copy);

char *commands[100][MAX_ARGS]; //Max 100 piped commands with each having MAX_ARGS arguments

int i = 0;

while (current_command != NULL) { //Go through each command and add it to the array

char *copy = malloc(strlen(current_command)*sizeof(char)); //Copy of curretn command

strcpy(copy, current_command);

char *args_t[MAX_ARGS];

int nargs_t = get_args(copy, args_t);

memcpy(commands[i], args_t, sizeof(args_t)*nargs_t); //Copy the command and it's arguments to the 2d array

i++;

current_command = strtok_r(NULL, "|\n", &cmdline_copy); //Use reentrant version of strtok to prevent fighting with get_args function

}

int fd[2*(i-1)]; //Set up the pipes i.e fd[0,1] is first pipe, fd[1,2] second pipe, etc.

for (int j = 0; j < i*2; j+=2) {

pipe(fd+j);

}

//Here is where we do the commands

for (int j = 0; j < i; j++) {

pid = fork(); //Fork

if (pid == 0) { //Child process

if (j == 0) { //First process

printf("Child Closed %d\n", fd[0]);

close(fd[0]);

dup2(fd[1], fileno(stdout));

}

else if (j == i -1) { //Last process

dup2(fd[j], fileno(stdin));

printf("Child closed %d\n", fd[j]);

printf("Child closed %d\n", fd[j+1]);

close(fd[j+1]);

close(fd[j]);

}

else { //Middle processes

dup2(fd[j], fileno(stdin));

dup2(fd[j+1], fileno(stdout));

printf("Child closed %d\n", fd[j]);

close(fd[j]);

}

execvp(commands[j][0], commands[j]);

}

else if (pid > 0) { //Parent

printf("Parent closed %d\n", fd[j]);

close(fd[j]);

printf("Parent closed %d\n", fd[j+1]);

close(fd[j+1]);

waitpid(pid, NULL, 0); //Wait for the process

}

else {

perror("Error with fork");

exit(1);

}

}

最终守则:

char *current_command;

current_command = strtok_r(cmdline_copy, "|", &cmdline_copy);

char *commands[100][MAX_ARGS]; //Max 100 piped commands with each having MAX_ARGS arguments

int command_count = 0;

while (current_command != NULL) { //Go through each command and add it to the array

char *copy = malloc(strlen(current_command)*sizeof(char)); //Copy of curretn command because get_args uses strtok

strcpy(copy, current_command);

char *args_t[MAX_ARGS];

int nargs_t = get_args(copy, args_t);

memcpy(commands[command_count], args_t, sizeof(args_t)*nargs_t); //Copy the command and it's arguments to the 2d array

command_count++;

current_command = strtok_r(NULL, "|\n", &cmdline_copy); //Use reentrant version of strtok to prevent fighting with get_args function

}

int fd[command_count*2-1];

pid_t pids[command_count];

for (int j = 0; j < command_count*2; j+=2) { //Open up a pair of pipes for every command

pipe(fd+j);

}

for (int j = 0; j < command_count; j++) {

pids[j] = fork();

if (pids[j] == 0) { //Child process

if (j == 0) { //Duplicate only stdout pipe for first pipe

dup2(fd[1], fileno(stdout));

}

else if (j == (command_count-1)) { //Duplicate only stdin for last pipe

up2(fd[2*(command_count-1)-2], fileno(stdin));

}

else { //Duplicate both stdin and stdout

dup2(fd[2*(j-1)], fileno(stdin));

dup2(fd[2*j+1], fileno(stdout));

}

for (int k = 0; k < j*2; k++) { //Close all fds

close(fd[k]);

}

execvp(commands[j][0], commands[j]); //Exec the command

}

else if (pids[j] < 0) {

perror("Error forking");

}

}

for (int k = 0; k < command_count*2; k++) { //Parent closes all fds

close(fd[k]);

}

waitpid(pids[command_count-1], NULL, 0); //Wait for only the last process;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值