gpt4 book ai didi

c - Chang的多管道

转载 作者:行者123 更新时间:2023-11-30 18:04:59 25 4
gpt4 key购买 nike

我正在尝试实现将运行多个 shell 命令链的程序:

        | --> cmd3 --> cmd4 -->
cmd2-->|
| --> cmd5 --> cmd6 -->|--> cmd7
|
|--> cmd8

等等...

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/types.h>

typedef struct command {
char* name;
char** argv;
} command;

command parsecmd(char* cmd) {
command c;

char delimiter[] = " ";
char* buf = malloc(sizeof(char) * strlen(cmd));
strcpy(buf, cmd);
char **args = malloc(sizeof(char*));

char* token = strtok(buf, delimiter);

int i = 0;
while (token != NULL) {
if (i == 0) {
c.name = token;
}

args[i] = token;

token = strtok(NULL, delimiter);
++i;
}

args[i] = NULL;

c.argv = args;

return c;
}

int mkproc(char *cmd, int outfd)
{
command c = parsecmd(cmd);
int pipeleft[2];
pipe(pipeleft);
if(!fork()){
close(pipeleft[1]);
dup2(pipeleft[0], 0);
dup2(outfd, 1);
execvp(c.name, c.argv);
}
close(pipeleft[0]);
return pipeleft[1];
}

int mktree(char *cmd, int ofd0, ...)
{
int piperight[2];
pipe(piperight);

int cmdin = mkproc(cmd, piperight[1]);
close(piperight[1]);
if(!fork()){
uchar buf[4096];
int n;

while((n=read(piperight[0], buf, sizeof buf))>0){
va_list ap;
int fd;
va_start(ap, ofd0);
for(fd=ofd0; fd!=-1; fd=va_arg(ap, int)){
write(fd, buf, n);
}
va_end(ap);
}
}
return cmdin;
}

int main(int argc, char* argv[]) {
// THIS WORK
int chain_in = mkproc("cat foo.txt", mkproc("sort", mkproc("wc -l", 1)));
// THIS WORK
int tree_in1 = mktree("cat /tmp/test.log", mkproc("grep a", 1), mkproc("wc -l", 2), -1);

// NOT WORK -> HANG!
int tree_in2 = mktree("cat /tmp/test.log",
mktree("grep test",
mkproc("uniq", mkproc("wc -l", 1)),
mkproc("wc -l", 2), -1),
mkproc("sort", 2), -1);
}

在子进程上运行 strace 时,它​​卡在从管道读取上,当在主进程上运行 starce 时,它​​也卡在 read 上......管道缓冲区为 64K,我一次只为每个管道写入 4k

发生了什么事?!

谢谢!!!

最佳答案

我发现您的代码至少有两个问题:

char* buf = malloc(sizeof(char) * strlen(cmd));

您需要为0 终止符分配比cmd 长度多1 的空间。由于 sizeof(char) 根据定义为 1,我会将上面的内容写为:

char *buf = malloc(strlen(cmd)+1);

此外,对于:

char **args = malloc(sizeof(char*));

您需要根据需要为尽可能多的参数分配空间:

char **args = malloc(n * sizeof *args);

其中n是参数的数量。

关于c - Chang的多管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7140594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com