0

I am trying to use named pipe to communicated between process. It is not behaving as expected , it is reading the same message again and again .

process 1 : ( creates a pipe , and start reading till it reads over or it reads 100 message )

    char* myfifo = "/tmp/omgfifo"; 
    if ( feature_head == NULL ) {
        vty_out(vty,"%s%s", ERR_STR ,VTY_NEWLINE);
        return  CMD_WARNING ;
    }
    vtysh_diag_list_features(feature_head,vty);
    /* Create UDS connection for ovs-appctl. */
    rc = mkfifo(myfifo,0777);
    if(rc == -1)
    {
        vty_out(vty,"mkfifo errorno  : %d %s",errno,VTY_NEWLINE);
    }
    fd = open(myfifo, O_RDONLY);
    if(fcntl(fd, F_GETFL ) & O_NONBLOCK)
    {
        vty_out(vty,"non block is enabled %s",VTY_NEWLINE);  
    }
    if(fd == -1)
    {
        vty_out(vty,"fd errorno  : %d %s",errno,VTY_NEWLINE);
    }
    else
    {
    while(flag)
    {
        retval ++;
        buf[0] = "\0"
        rc = read(fd,buf,MAX_BUF);
        if(retval > 100)
        {
            flag = 0;
            break;
        }
        if(rc == -1)
        {
            flag = 0;
            vty_out(vty,"read errorno  : %d %s",errno,VTY_NEWLINE);
        }
        else
        {
        if(strlen(buf) > 3 && strcmp(buf,"over"))
        {
            vty_out(vty,"gone case %s",VTY_NEWLINE);
            flag = 0;
        }
        vty_out(vty,"%3d:%s %s",retval,buf,VTY_NEWLINE);
        }
    }
    close(fd);
    }
    unlink(myfifo);
    vty_out(vty,"SIGN : done");
    return CMD_SUCCESS;

process 2 (write to the same pipe)

int fd;
char * myfifo = "/tmp/omgfifo";

fd = open(myfifo, O_WRONLY);
if(fd == -1)
{
    vty_out(vty,"fd errorno  : %d %s",errno,VTY_NEWLINE);
}
else
{
    if(fcntl(fd, F_GETFL ) & O_NONBLOCK)
{
    vty_out(vty,"non block is enabled %s",VTY_NEWLINE);  
}
    if(write(fd, "Hi", sizeof("Hi"))== -1)
    {
        vty_out(vty,"write h errorno  : %d %s",errno,VTY_NEWLINE);
        }
if(write(fd, "Hi1", sizeof("Hi1"))== -1)
    {
        vty_out(vty,"write h1 errorno  : %d %s",errno,VTY_NEWLINE);
        }

if(write(fd, "over", sizeof("over")) == -1)
    {
        vty_out(vty,"write o errorno  : %d %s",errno,VTY_NEWLINE);
        }
if(write(fd, "Hi2", sizeof("Hi2")) == -1)
    {
        vty_out(vty,"write h2 errorno  : %d %s",errno,VTY_NEWLINE);
        }

if(write(fd, "Hi3", sizeof("Hi3")) == -1)
    {
        vty_out(vty,"write h3 errorno  : %d %s",errno,VTY_NEWLINE);
        }
if(close(fd)!=0)
{
    vty_out(vty,"close errorno  : %d %s",errno,VTY_NEWLINE);
}
}

    return 0;

output of process 1( at times it is Hi1 and at times it is over

  1:Hi 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
SIGN : done

fd of both the process is blocking. Can someone shed some light about why prcoess 1 is reading some message again and again and again

manimuthu m a
  • 61
  • 1
  • 9

1 Answers1

3

When you close the fd on the writing part, read receives an end-of-file and returns 0 (and the buffer is not changed, so it keeps containing "Hi"). You should at least check for this condition (in general you should use read's return value as number of bytes actually read). In general there is no guarantee that there is a perfect match between read and write. "write" just enqueues characters, and "read" receives up to the number you pass as third parameter (MAX_BUF). So what is happening is that you receive the whole set of characters in a single read operation, and then you get EOF on further reads. It's on you to split the buffer and find the parts.

Giuseppe Guerrini
  • 4,274
  • 17
  • 32
  • sorry it is actually, both the process are blocking . Non-block is not enabled in both process. – manimuthu m a Jul 12 '16 at 06:48
  • before closing , process 2 write Hi1 if that is the case then the message should be Hi5 right ? after closing , how to make process 1 wait for new read instead of EOF . because if what ur saying is true mean , read is keeping on reading EOF – manimuthu m a Jul 12 '16 at 06:59
  • I suggest you to print also read's return value. It would help you in figuring out what is going on. Anyway you should use that value to decide how many characters are valid in receive buffer. – Giuseppe Guerrini Jul 12 '16 at 07:10
  • i have modified the code, as you mentioned read is reading eof . But why? – manimuthu m a Jul 12 '16 at 07:28
  • Uhm... it behaves as if there were still a close after the first write. Weird. By the way, I suggest you to change the line "buf[0] = "\0" " (you probably wanted to write "buf[0]='\0';") with "memset(buf,0,MAX_BUF)" to make sure not to reuse old values. – Giuseppe Guerrini Jul 12 '16 at 07:39
  • all the write is going as a single message and why are we getting multiple EOF – manimuthu m a Jul 12 '16 at 11:15
  • In general there is no guarantee that there is a perfect match between read and write. "write" just enqueues characters, and "read" receives up to the number you pass as third parameter (MAX_BUF). So what is happening is that you receive the whole set of characters in a single read operation (it's on you to split the buffer and find the parts), and then you get EOF on further reads. You will keep getting EOF because this is the state of your file descriptor. You must check the condition (read==0) and go out from the loop. - [added to my answer] – Giuseppe Guerrini Jul 12 '16 at 12:54
  • one last question , but without starting my second process i didn't receive EOF – manimuthu m a Jul 13 '16 at 05:12
  • Correct: EOF in case of pipes indicates that the counterpart has CLOSED the file descriptor - this means that it must have opened it before. More precisely, EOF is detected when the last write part's file descriptor is closed, i.e. when there aren't "writers" anymore. It is indeed possible to have multiple "open" on the write part at the same time (= more than one writer file descriptor) – Giuseppe Guerrini Jul 13 '16 at 05:56