gpt4 book ai didi

c - 在 C 中循环一个未命名的管道

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

好的,我搜索了这个但没找到。如果之前已经回答过,请道歉。

基本上我有一个类程序,它创建两个未命名的管道并使用它们在父进程和子进程之间进行通信。命令从父级传递给子级,子级执行它并向父级返回成功/错误消息。 Parent 然后打印出 Success/Error 消息。很简单,我有那个工作。现在的问题是我需要循环它直到用户给出“退出”命令。我想我需要一个 while 循环,但在尝试放置后程序仍然只运行一次然后退出。这就是我所拥有的。希望这是有道理的,我省略了代码的处理部分,因为该部分有效(就像我说的,对于一个类),但如果有任何不合理的地方,我会澄清。在此先感谢您的帮助。

while (strcmp(cmd,"exit") != 0)
{
/* Create Pipe P to pass command from the
parent process to the child process and check for errors.*/
pipe(p);

/*Create Pipe Q to pass command from the
child process to the parent process and check for errors. */
pipe(q);

/* Create child process */
pid = fork();

switch(pid){

case -1: /* fork failed */
perror("main: fork");
exit(1);
case 0: /* Child process */
/*****************************************
Stuff being executed in the child process
*****************************************/
default: /* Parent process */
printf ("Choose from the following list of commands.\n");
printf ("display\n");
printf ("chars\n");
printf ("lines\n");
printf ("words\n");
printf ("find\n");
printf ("exit\n");
fgets (cmd,10,stdin);

if ((c = strchr(cmd, '\n')) != NULL)
{
*c = '\0';
}
/**********************************
Pipes being opened and closed for
communication between parent and child
**************************************/
break;
}
return 0;
}
}

最佳答案

您需要在进入循环之前创建 child 。

您还需要更加小心管道。主(父)进程必须关闭它不会使用的管道末端,子进程也一样(注意子进程关闭父进程的另一端)。当然,如果 child 正在读取标准输入并在标准输出上写入,那么您必须安排将管道复制到正确的描述符,然后 child 关闭 pipe()< 返回的所有描述符调用。


试试这个大小 - 你必须扩展 be_childish() 来做真正的工作......

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>

static void be_childish(int p[2], int q[2]);
static void be_parental(int p[2], int q[2]);

static void err_exit(const char *fmt, ...)
{
int errnum = errno;
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n%d: %s\n", errnum, strerror(errnum));
exit(1);
}

int main(void)
{
int p[2]; /* Pipe to child */
int q[2]; /* Pipe to parent */
pid_t pid;

if (pipe(p) != 0)
err_exit("Failed to create pipe 1");

if (pipe(q) != 0)
err_exit("Failed to create pipe 2");

if ((pid = fork()) < 0)
err_exit("Failed to create child process");
else if (pid == 0)
be_childish(p, q);
else
be_parental(p, q);

return(0);
}

static int prompt(char *buffer, size_t buflen)
{
char *c;
printf("Choose from the following list of commands.\n");
printf("display\n");
printf("chars\n");
printf("lines\n");
printf("words\n");
printf("find\n");
printf("exit\n");
if (fgets(buffer, buflen, stdin) == 0)
return EOF;
if ((c = strchr(buffer, '\n')) != NULL)
*c = '\0';
if (strcmp(buffer, "exit") == 0)
return EOF;
return 0;
}

static void be_parental(int p[2], int q[2])
{
char cmd[10] = "";

if (close(p[0]) != 0 || close(q[1]) != 0)
err_exit("Parent: failed to close pipe");

while (prompt(cmd, sizeof(cmd)) != EOF)
{
char buffer[4096];
ssize_t nbytes;
if (write(p[1], cmd, strlen(cmd)) != (ssize_t)strlen(cmd))
err_exit("Write to child failed");
if ((nbytes = read(q[0], buffer, sizeof(buffer))) < 0)
err_exit("Read from child failed");
if (nbytes == 0)
return;
printf("%s\n", buffer);
}
}

static void be_childish(int p[2], int q[2])
{
char cmd[10] = "";
ssize_t nbytes;

if (close(p[1]) != 0 || close(q[0]) != 0)
err_exit("Child: failed to close pipe");

while ((nbytes = read(p[0], cmd, sizeof(cmd))) > 0)
{
char buffer[4096];
cmd[nbytes] = '\0';
/* Process command */
strcpy(buffer, "Response from child: ");
strcat(buffer, cmd);
if (write(q[1], buffer, strlen(buffer)) != (ssize_t)strlen(buffer))
err_exit("Write to parent failed");
}
}

关于c - 在 C 中循环一个未命名的管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5785870/

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