gpt4 book ai didi

c - 在 C 中编写我自己的管道函数

转载 作者:太空宇宙 更新时间:2023-11-04 04:28:04 25 4
gpt4 key购买 nike

我正在尝试在 C 中编写自己的管道函数。首先,一旦我已经 fork 并进入子项,我将检查以检测管道的输入位置,如下所示。我正在遍历我自己创建的 StringArray (sa),并将之前的 token 复制到 char cmd1[64](之前已初始化)并将之后的 token 复制到 char cmd2[64]。 int 管道被赋予下一步的值。

if(strcmp(sa[i], "|") == 0)
{
printf("got to the pipe\n");
sa[i]=NULL;
strcpy(cmd1, sa[i-1]);
strcpy(cmd2, sa[i+1]);
piping=2;
}

然后,程序到达这个语句:

if (piping)
{
if (pipe(fd) != 0){
perror("Failed to create pipe");
}
if ((cpPid = fork()) == -1){
perror("Failed to fork");
}
if (cpPid == 0){
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
execvp(cmd1, sa);
error("failed to exec command 1");
}
else
{
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
execvp(cmd2, sa);
error("failed to exec command 2");
}
}

我的程序完全崩溃,只给出未知错误 10275024。有人可以帮我找出问题所在吗?

最佳答案

请看一下这个工作示例,它可以帮助您使用 C 执行管道。

#include <assert.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>

typedef int Pipe[2];

/* exec_nth_command() and exec_pipe_command() are mutually recursive */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output);

static void err_vsyswarn(char const *fmt, va_list args) {
int errnum = errno;
vfprintf(stderr, fmt, args);
if (errnum != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
}

static void err_syswarn(char const *fmt, ...) {
va_list args;
err_vsyswarn(fmt, args);;
}

static void err_sysexit(char const *fmt, ...) {
va_list args;
err_vsyswarn(fmt, args);
exit(1);
}

/* With the standard output plumbing sorted, execute Nth command */
static void exec_nth_command(int ncmds, char ***cmds) {
assert(ncmds >= 1);
if (ncmds > 1) {
pid_t pid;
Pipe input;
if (pipe(input) != 0)
err_sysexit("Failed to create pipe");
if ((pid = fork()) < 0)
err_sysexit("Failed to fork");
if (pid == 0) {
/* Child */
exec_pipe_command(ncmds - 1, cmds, input);
}
/* Fix standard input to read end of pipe */
dup2(input[0], 0);
close(input[0]);
close(input[1]);
}
execvp(cmds[ncmds - 1][0], cmds[ncmds - 1]);
err_sysexit("Failed to exec %s", cmds[ncmds - 1][0]);
/*NOTREACHED*/
}
/* exec_nth_command() and exec_pipe_command() are mutually recursive */
/* Given pipe, plumb it to standard output, then execute Nth command */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output) {
assert(ncmds >= 1);
/* Fix stdout to write end of pipe */
dup2(output[1], 1);
close(output[0]);
close(output[1]);
exec_nth_command(ncmds, cmds);
}

/* Execute the N commands in the pipeline */
static void exec_pipeline(int ncmds, char ***cmds) {
assert(ncmds >= 1);
pid_t pid;
if ((pid = fork()) < 0)
err_syswarn("Failed to fork");
if (pid != 0)
return;
exec_nth_command(ncmds, cmds);
}

/* who | awk '{print $1}' | sort | uniq -c | sort -n */
static char *cmd0[] = {"who", 0};
static char *cmd1[] = {"awk", "{print $1}", 0};
static char *cmd2[] = {"sort", 0};
static char *cmd3[] = {"uniq", "-c", 0};
static char *cmd4[] = {"sort", "-n", 0};

static char **cmds[] = {cmd0, cmd1, cmd2, cmd3, cmd4};
static int ncmds = sizeof(cmds) / sizeof(cmds[0]);

int main(int argc, char **argv) {
exec_pipeline(ncmds, cmds);
return (0);
}

代码中的流水线示例是

谁 | awk '{print $1}' |排序 | uniq-c |排序-n

您可以使用任何管道。

测试:

dac@dac-Latitude-E7450 ~/C/> 
who | awk '{print $1}' | sort | uniq -c | sort -n
1 dac
dac@dac-Latitude-E7450 ~/C/> gcc main.c
dac@dac-Latitude-E7450 ~/C/> ./a.out
1 dac

关于c - 在 C 中编写我自己的管道函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39493754/

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