gpt4 book ai didi

c - pipeline()-ing 程序会导致 EIO

转载 作者:行者123 更新时间:2023-11-30 17:32:51 24 4
gpt4 key购买 nike

我们有一个家庭作业问题,我们必须编写一个带有两个参数的程序,将它们作为 shell 命令执行,将第一个程序的标准输出通过管道传输到第二个程序的标准输入。

这是我的solution对于这个家庭作业问题。下面复制了相同的文件。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

#define SHELL "/bin/sh"

extern int main(int, char*[]);
static int readingend(int, int, const char*);
static int writingend(int, int, const char*);
static int usr1handler();

extern int
main(int argc, char *argv[])
{
int pipefd[2], status;
pid_t rpid, wpid;

if (argc != 3) {
fprintf(stderr, "Invalid argument count\n");
return (EXIT_FAILURE);
}

if (pipe(pipefd)) {
perror("Cannot make a pipe");
return (EXIT_FAILURE);
}

signal(SIGUSR1, (void(*)(int))usr1handler);

if ((rpid = fork()) < 0) {
perror("Cannot fork");
return (EXIT_FAILURE);
}

if (rpid == 0)
return (readingend(pipefd[0], pipefd[1], argv[2]));


if ((wpid = fork()) < 0) {
perror("Cannot fork");
kill(rpid, SIGKILL);
return (EXIT_FAILURE);
}

if (wpid == 0)
return (writingend(pipefd[0], pipefd[1], argv[1]));

close(pipefd[0]);
close(pipefd[1]);

waitpid(rpid, &status, 0);
return (status);
}

static int
readingend(int rfd, int wfd, const char *cmd)
{
close(wfd);
dup2(rfd, STDIN_FILENO);

/* execl() only returns on error */
execl(SHELL, SHELL, "-c", cmd, NULL);
fprintf(stderr, "Cannot execute %s: ", cmd);
perror(NULL);

/* clean up */
kill(getppid(), SIGUSR1);
return (EXIT_FAILURE);
}

static int
writingend(int rfd, int wfd, const char *cmd)
{
close(rfd);
dup2(wfd, STDOUT_FILENO);

execl(SHELL, SHELL, "-c", cmd, NULL);
fprintf(stderr, "Cannot execute %s: ", cmd);
perror(NULL);

/* clean up */
kill(getppid(), SIGUSR1);
return (EXIT_FAILURE);
}

static int
usr1handler()
{
/* child already printed diagnostic */
exit(EXIT_FAILURE);
}

问题在于,在某些调用中,第一个进程在从 stdin 读取时收到 EIO。这似乎只发生在某些 shell 上:它发生在 ksh93bash 上,但不会发生在 bosh 上。这样的错误看起来像这样:

$ LANG=C ./mypipe cat true$ cat: -: Input/output error

谁能告诉我为什么会出现这个错误?我该怎么做才能不再出现该错误?显然,必须有一种方法可以执行 cat | true 在普通 shell 中会产生所需的结果,而不会产生任何虚假的 EIO

最佳答案

发生此问题的原因是 true 立即终止,导致 mypipe 也终止,从而使 cat 孤立。如果发生这种情况,read() 可能会失败:

EIO

The process is a member of a background process attempting to read from its controlling terminal, the process is ignoring or blocking the SIGTTIN signal, or the process group is orphaned. This error may also be generated for implementation-defined reasons.

可以通过等待两个进程来防止此问题,如下所示:

extern int
main(int argc, char *argv[])
{
int status, estatus;

/* ... */


/* wait for both processes to terminate */
if (wait(&status) == rpid) {
estatus = status;
wait(&status);
} else {
wait(&status);
estatus = status;
}

return (estatus);
}

关于c - pipeline()-ing 程序会导致 EIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23983860/

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