Named pipes: FIFOs

  • One of the limitations of un-named(anonymous pipe) implemented by pipe() API is that it can be used to exchange information among related processes, that is, program that have been started from common ancestor process.
  • With the help of names pipe, an unrelated processes can also exchange data among each other.
  • They support bidirectional communication means same FIFO can be read from as well as written into.
  • A names pipe is a special type of file that exists as a name in the file system.
  • They are represented by a inode and exist independent of the process that is once created can be used by other process too.
  • Named pipes can be used to provide communication between processes on the same computer or between processes on different computers across a network. If the server service is running, all named pipes are accessible remotely. 
  • For example a Web Server can communicate with the database directly using a named pipe, instead of using a localhost address or listening to some port.They take a very small amount of memory.
int mkfifo (const char *file_name, mode_t access_mode);
  • The first argument defines the name of the file and second parameter is the mode that is permissions: read, write, execute.
  • A named pipe can be used with open, read, write, close as named pipe is a kind of file.

Prototype for open(), read(), write() and close()

int fd = open (const char *path, int flags,mode_t access_mode)
int read_bytes = read (int fd, void *buffer, size_t nbytes);
int write_bytes = write (int fd, void *buffer, size_t nbytes);
int ret = close (int fd); 
  • Return values are file descriptor, number of bytes read and number of bytes written and (0 on success and -1 on failure) respectively.
  • The most common flag is O_NONBLOCK which makes the file descriptor as non blocking that is read and write return immediately if there is no data to read or buffer is full respectively.

Creating a FIFO via Command Line:

Read Block:

[aprakash@wtl-lview-6 thread]$ mkfifo read
[aprakash@wtl-lview-6 thread]$ cat read
      /* Blocked until data is there to read */   
  • A FIFO name “read” is created and tries reading it with cat command, it goes to a block state until there is data to read.
  • Now if from another terminal data is written to this FIFO, it get unblocked.
/* Data is written from another terminal */
[aprakash@wtl-lview-6 thread]$ echo "unblocked">read
[aprakash@wtl-lview-6 thread]$ 

/* It automatically gets unblocked */
[aprakash@wtl-lview-6 thread]$ cat read
unblocked
[aprakash@wtl-lview-6 thread]$

Write Block:

/* create a FIFO and and write */
[aprakash@wtl-lview-6 thread]$ mkfifo write
[aprakash@wtl-lview-6 thread]$ echo "Hello">write
    /* It gets blocked as there is no read process */

/* On the other terminal, read the FIFO */
[aprakash@wtl-lview-6 thread]$ cat write
hello
[aprakash@wtl-lview-6 thread]$ 

/* The write on first terminal gets unblocked */
[aprakash@wtl-lview-6 thread]$ echo "Hello">write
[aprakash@wtl-lview-6 thread]$ 

Sample Program:
This program uses a common named pipe(FIFO) to communicate between client and server, client can send message infinitely and sends “bye” to end communication and close the pipe.

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

int main()
{
    int fd;
    char buf_read[80], buf_write[80];

    /* Path of the FIFO */
    char * myfifo = "/tmp/myfifo";

    /* Create a FIFO */
    mkfifo (myfifo, 0666);
    printf("FIFO_CLIENT: Send messages, infinitely, to end enter \"bye\"\n");

    while (1)
    {
        /* Open FIFO for write only */
        fd = open (myfifo, O_WRONLY);

        /* Take data to the buffer */
        printf("\n Enter the message for server:\n");
        fgets (buf_write, 80, stdin);

        /* Write data */
        write (fd, buf_write, strlen(buf_write)+1);
        printf("\n Message send is: %s\n", buf_write);
        close (fd);

        if (strncmp (buf_write, "bye", 3) == 0)
            break;
 
         /* Open FIFO for Read only */
         fd = open (myfifo, O_RDONLY);
 
         read (fd, buf_read, sizeof(buf_read));
         printf ("Message read is: %s\n", buf_read);
         close (fd);
     }
     return 0;
 }
  • server.c
 #include <string.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <stdlib.h>
 
 int main()
 {
     int fd;
 
     /* FIFO path */
     char * myfifo = "/tmp/myfifo";
     char buf_read[80], buf_write[80];
 
     while (1)
     {
         // First open in read only and read
         fd = open (myfifo, O_RDONLY);
         read (fd, buf_read, 80);
 
         // Print the read string and close
         printf ("Read message is: %s\n", buf_read);
         close (fd);
 
         if (strncmp ("bye",buf_read, 3) ==0 )
         {
            printf("\n Bye message from client.. Bye!!\n");
            break;
         }
 
         /* Now open in write mode and write */
         fd = open (myfifo, O_WRONLY);
 
         printf("\n Enter the message for client\n");
         fgets (buf_write, 80, stdin);
 
         write (fd, buf_write, strlen(buf_write)+1);
         printf("\n Message send is: %s\n", buf_write);
         close (fd);
     }
     return 0;
 }

Output:

Run server.c

[aprakash@wtl-lview-6 named_pipe]$ gcc server.c -o ser
[aprakash@wtl-lview-6 named_pipe]$ ./ser
Read message from client is: Hello
Enter the message for client:
    how r u?
Message send is: how r u?
Read message from client is: m fine
Enter the message for client
    ok
Message send is: ok
Read message from client is: bye
Bye message from client.. Bye!!
[aprakash@wtl-lview-6 named_pipe]$

Run client.c

[aprakash@wtl-lview-6 named_pipe]$ gcc client.c -o cli
[aprakash@wtl-lview-6 named_pipe]$ ./cli 
FIFO_CLIENT: Send messages, infinitely, to end enter "bye"

 Enter the message for server
       Hello

 Message send is: Hello
 Message read is: how r u?

 Enter the message for server
       m fine

 Message send is: m fine

 Message read is: ok

 Enter the message for server
       bye
 Message send is bye

 [aprakash@wtl-lview-6 named_pipe]$ 


Categories: Operating system (OS)

4 replies

Trackbacks

  1. Pipes - Tech Access
  2. Un-named Pipes - Tech Access
  3. Index of Operating System - Tech Access
  4. Inter-Process Communication(IPC) - Tech Access

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: