user4132350
user4132350

Reputation:

program using named pipes crashed

The program is about providing message between people created via FIFO by selected,

./a.out create name_of_person

The first condition if( strcmp(argv[1], "create") == 0 ) works properly, but after that, after selecting ./a.out name1 name2 message and while compiling the program hangs out (it's else condition).

How can I solve the problem?

#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;
}

Upvotes: 0

Views: 1051

Answers (1)

Werner Henze
Werner Henze

Reputation: 16726

From man 3 mkfifo:

However, it has to be open at both ends simultaneously before you can proceed to do any input or output operations on it. Opening a FIFO for reading normally blocks until some other process opens the same FIFO for writing, and vice versa.

In your line

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

you are opening both fifos for reading. Both opens will block until also a writer opens the fifo. BTW, this if leaks both opened file descriptors.

Your later processing

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

has the same problem of blocking during open until a write opens the fifo. And there is another problem: you are opening the fifo for reading only but you are writing to it only.

You need to replace your open for checking if the files exists. Remove it - your later open will fail - or replace it with a stat. And you need to implement both sides of the messaging to test it, not only one side (or you need to run a shell command to write to or read from the fifo in parallel to your program to test it).

Other problems in your code:

  1. You are not including the right header for kill - and you are calling kill without the needed parameters.
  2. You are not including the right header for mkfifo.

You should consider enabling more warnings to see those problems in your code.

Upvotes: 2

Related Questions