FIFOs

Last edit

Changed: 5c5

< * A fifo is either writeable or readable for a process, not both like a pipe

to

> * A fifo is either writeable or readable for a process, not both like a pipe.


Using a FIFO file to pipe

How can I communicate using a file?

A FIFO file, also known as a named pipe, works like a normal pipe, except...:

Because it is a file, it has to be opened and closed. But being a file, it doesn't mean you can always read and write it - it is still a pipe. It has to be open at two ends:

A FIFO special file is created with the command mkfifo() or mknod().

The FIFO client

  /* fifoclient.c */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  
  /* the standard permissions of the two FIFOs that are created */
  #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
  /* the name of the file where clients put their data */
  #define CLIENT_MSG_FIFO_FILENAME "/tmp/client_msg_fifo" 
  /* the name of the file where the server put its data */
  #define SERVER_MSG_FIFO_FILENAME "/tmp/server_msg_fifo"
  
  #define N_MAX_MSG_SIZE 100
  
  int main (void)
  {
        FILE* p_server_msg_fifo;          /* points to FIFO with server output */
        FILE* p_client_msg_fifo;   /* points to FIFO where this client outputs */
        int n_client_pid;       /* to identify which client writes to the FIFO */
        char sz_message[N_MAX_MSG_SIZE];   /* the message which is transported */
       
        do
        {
              printf("What should I send to the server? ");
              scanf("%s", sz_message);
  
              /* send user input to pipe */
              p_client_msg_fifo = fopen(CLIENT_MSG_FIFO_FILENAME, "w");
              fprintf(p_client_msg_fifo, "%d%s", getpid(), sz_message); 
              fclose(p_client_msg_fifo);
  
              /* and now pick up the echo returned by the server */
              p_server_msg_fifo = fopen(SERVER_MSG_FIFO_FILENAME, "r");
              fscanf(p_server_msg_fifo, "%d%s", &n_client_pid, sz_message);
              fclose(p_server_msg_fifo);
              printf("S: %d, %s\n", n_client_pid, sz_message);  
        }
        while (1);
  
        return(0);
  }

The FIFO server

  /* fifoserver.c */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <errno.h>
  #include <sys/stat.h>
  #include <unistd.h>
  
  #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
  #define CLIENT_MSG_FIFO_FILENAME "/tmp/client_msg_fifo"
  #define SERVER_MSG_FIFO_FILENAME "/tmp/server_msg_fifo"
  #define FIFO_BUFSIZE 10
  #define N_MAX_MSG_SIZE 100
  
  
  int main(void)
  {
        FILE* p_client_msg_fifo;   /* filepointer to FIFO where client outputs */
        FILE* p_server_msg_fifo;    /* points to FIFO where the server outputs */
        int n_client_pid;       /* to identify which client writes to the FIFO */
        char sz_message[N_MAX_MSG_SIZE];   /* the message which is transported */
        int n_read_retval; /* to test the returnvalue of the FIFO reading func */
  
        umask(0);                 /* because you don't know what this value is */
        mkfifo(CLIENT_MSG_FIFO_FILENAME, FILE_MODE); 
        mkfifo(SERVER_MSG_FIFO_FILENAME, FILE_MODE);
  
        do
        {
              /* pick up the clients data */
              p_client_msg_fifo = fopen(CLIENT_MSG_FIFO_FILENAME, "r");
              n_read_retval = fscanf(p_client_msg_fifo, "%d%s", 
                                     &n_client_pid, sz_message);
              fclose(p_client_msg_fifo);
   
              /* throw the echo on the FIFO so the clients can pick it up */
              p_server_msg_fifo = fopen(SERVER_MSG_FIFO_FILENAME, "w");
              fprintf(p_server_msg_fifo, "%d%s", n_client_pid, sz_message);
              fclose(p_server_msg_fifo); 
        }
        while(1);
  
        return(0);
  }