- 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)
Leave a Reply