fredjohnson
fredjohnson

Reputation: 197

Named PIPE (FIFO) reading content of file in C

Basically I want my client program to read data from a file (file name/path specified in the command line input) and copy that data to the FIFO and I want my server program to read from the FIFO and print every line.

For example if I want to print the contents of the /etc/passwd text file I run the program in the terminal in this way:

./server &
./client < /etc/passwd

However, instead of printing any output, it prints out nothing but 'done'. Why?
Here's my code:
server.c

//server.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define FIFONAME "myfifo"

int main(void){

    int n,fd;
    char buffer[1024];
    unlink(FIFONAME);

    //create FIFO

    if(mkfifo(FIFONAME,0666)<0){
        perror("server: mkfifo");
        exit(1);
    }
    //open FIFO for reading
    if((fd = open(FIFONAME, O_RDONLY))<0){
        perror("server: open");
        exit(1);
    }
    //READ from fifo UNTIL end of tile and print 
    //what we get on the standard input
    while((n=read(fd,buffer,sizeof(buffer)))>0){
        write(1, buffer, n);
    }

    close(fd);
    exit(0);
}

.
client.c

//client.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define FIFONAME "myfifo"

int main(void){

    int n,fd;
    char buffer[1024];

    /* open, read, and display the message from the FIFO */
    if((fd = open(FIFONAME, O_WRONLY))<0){
        perror("client: open");
        exit(1);
    }
    //read from standard input and copy data to the FIFO
    while (fgets(buffer, sizeof(buffer), stdin) != 0){
        fgets(buffer, sizeof(buffer), stdin);
        write(fd, buffer, n);
    }


    close(fd);
    exit(0);
}

Upvotes: 0

Views: 2764

Answers (1)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140148

this code is wrong:

 while (fgets(buffer, sizeof(buffer), stdin) != 0){
        fgets(buffer, sizeof(buffer), stdin);
        write(fd, buffer, n);

this loops consumes the input, then reads it again. You're losing the first (and possibly the only) buffer. I would do (maybe not the best code but works):

 while (1){
        if (fgets(buffer, sizeof(buffer), stdin)==0) break;
        write(fd, buffer, n);
 }

Aside, as noted in my comments, running the server in background to create the FIFO and running the client without waiting for the FIFO to be created is a potential race condition.

Upvotes: 2

Related Questions