我正在用c编写一个管道模拟.当有多个‘|’时,它崩溃了,其他进程必须读取前一个进程的输出.
#define _GNU_SOURCE
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
enum {
MAX_ARGS_COUNT = 256,
MAX_CHAIN_LINKS_COUNT = 256
};
pid_t pid_arr[MAX_CHAIN_LINKS_COUNT];
typedef struct {
char *command;
uint64_t argc;
char *argv[MAX_ARGS_COUNT];
} chain_link_t;
typedef struct {
uint64_t chain_links_count;
chain_link_t chain_links[MAX_CHAIN_LINKS_COUNT];
} chain_t;
void parse_commands(char *command, chain_link_t *link) {
char *tmp = command;
char *tmp2 = command;
link->argc = 1;
while ((tmp = strchr(tmp, ' '))) {
link->argv[link->argc - 1] = strndup(tmp2, tmp - tmp2);
link->argc++;
tmp2 = ++tmp;
}
if (strlen(tmp2) > 0) {
link->argv[link->argc - 1] = strdup(tmp2);
}
link->command = link->argv[0];
}
void create_chain(char *command, chain_t *chain) {
char *tmp = command;
char *tmp2 = command;
chain->chain_links_count = 0;
while ((tmp = strchr(tmp, '|'))) {
if (tmp[0] == ' ') {
++tmp;
}
parse_commands(strndup(tmp2, tmp - tmp2 - 1), &(chain->chain_links[chain->chain_links_count]));
tmp = tmp2 = tmp + 2;
++chain->chain_links_count;
}
if (strlen(tmp2) > 0) {
if (tmp2[0] == ' ') {
++tmp2;
}
parse_commands(strdup(tmp2), &(chain->chain_links[chain->chain_links_count]));
++chain->chain_links_count;
}
}
void run_chain(chain_t *chain) {
size_t size = chain->chain_links_count - 1;
if (chain->chain_links_count == 0) {
fprintf(stderr, "No commands provided.\n");
return;
}
int pipes[chain->chain_links_count][2];
for (int i = 0; i < chain->chain_links_count - 1; ++i) {
if (pipe(pipes[i]) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < chain->chain_links_count; ++i) {
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) { // Child process
if (i > 0) {
dup2(pipes[i - 1][0], STDIN_FILENO);
close(pipes[i - 1][0]);
close(pipes[i - 1][1]);
}
if (i < chain->chain_links_count - 1) {
dup2(pipes[i][1], STDOUT_FILENO);
close(pipes[i][0]);
close(pipes[i][1]);
}
execvp(chain->chain_links[i].command, chain->chain_links[i].argv);
perror("execvp");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < chain->chain_links_count - 1; ++i) {
close(pipes[i][0]);
close(pipes[i][1]);
}
for (int i = 0; i < chain->chain_links_count; ++i) {
wait(NULL);
}
}
int main(int argc, char *argv[]) {
chain_t chain;
create_chain(argv[1], &chain);
run_chain(&chain);
return 0;
}
也就是说,测试类型为"pwd"
、"ls"
、"ls -l"
、"ls -la"
、"ls -la | wc -c"
、"pwd | cut -d/ -f2"
、"ls -la | wc | echo "1" | echo "1" | echo "1" | echo "1" | echo "1" | echo "1" | echo "1""
,它工作成功,但在测试"ls -la | wc | wc -c"
中,它挂起在最后一个进程上.
我假设最后一个wc的输入为空,这就是它挂起的原因.
这可能是什么问题?