程序使用命名管道崩溃

时间:2014-11-14 14:22:27

标签: c linux named-pipes

该程序是关于在通过FIFO创建的人员之间提供消息,

./a.out create name_of_person

第一个条件if( strcmp(argv[1], "create") == 0 )正常工作,但在此之后,选择./a.out name1 name2 message并在编译程序时挂起(这是其他情况)。

我该如何解决这个问题?

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

int main(int argc, char* argv[]) {

 int i = 0;
 int fifo = -1;

 if( strcmp(argv[1], "create") == 0 ) { 
    int fifo = mkfifo(argv[2], 0666);

    if( ( fifo == -1) ) {
        perror("\n The problem occured. The program exited. \n");
        printf("error %d : %s \n", errno, strerror (errno));
    exit( 1 );
    }
 }

 else if( strcmp(argv[2], "history") == 0 ) {

  int process1 = fork();

  if( process1 == 0 ) {

    int process2 = fork();

    if( process2 == 0 )
     {
        char c;
        if (fifo == 0) {
        int FILE = open(argv[1], O_RDONLY);

        for(i=3; i<argc; i++) {
        read( FILE, argv[i], 1 );
        //while( ( Scanner = read( odFILE, &c, 1) ) > 0 )
        }

        close( FILE );
        }
    }
    kill();
 }
 }

 else 
 {

 if( (open(argv[1], O_RDONLY, 0777) == -1) || (open(argv[2], O_RDONLY, 0777) == -1) ) 
 {
  perror("The user does not exist."); 
  exit(1);
 }

 printf("< ");
 printf("%s", argv[1]);
 printf(" -> ");
 printf("%s", argv[2]);
 printf(" > : ");

 for(i=3; i<argc; i++) printf("%s", argv[i]);

 int process1 = fork();

 if( process1 == 0 ) {



int process2 = fork();

    if( process2 == 0 ) {
        int FILE = open(argv[2], O_RDONLY);
        write( FILE, argv[3], sizeof(argv[3]) );
        close( FILE );
    }

    kill();
 }
}

 return 0;
}

1 个答案:

答案 0 :(得分:2)

来自man 3 mkfifo

  

但是,必须在两端同时打开它才能继续对其进行任何输入或输出操作。打开FIFO以便正常读取块,直到某个其他进程打开相同的FIFO进行写入,反之亦然。

在你的行

if( (open(argv[1], O_RDONLY, 0777) == -1) || (open(argv[2], O_RDONLY, 0777) == -1) )

你正在打开两个读数。两个打开都将阻止,直到作家打开fifo。 顺便说一下,这会泄漏两个打开的文件描述符。

您以后的处理

int FILE = open(argv[2], O_RDONLY);
write( FILE, argv[3], sizeof(argv[3]) );
close( FILE );

在打开期间阻塞相同的问题,直到写入打开fifo。还有另外一个问题:你只是打开fifo阅读,但你只是在写它。

您需要替换open以检查文件是否存在。删除它 - 稍后打开将失败 - 或用stat替换它。并且你需要实现消息传递的两个方面来测试它,不仅是一方(或者你需要运行一个shell命令来写入或读取fifo并行程序来测试它)。

代码中的其他问题:

  1. 你没有为kill添加正确的标题 - 你在没有所需参数的情况下调用kill。
  2. 您没有为mkfifo添加正确的标题。
  3. 您应该考虑启用更多警告,以便在代码中查看这些问题。