Programming FIFO/Named PIPE in Linux
Previous post covers pipe, an IPC mechanism for processes that have common parent process. We refer to processes that have common parent process as related process. But for unrelated processes, pipe cannot be used, because one process has no way of referring to pipes have been created by another process.
When two unrelated processes share some information, an identifier must be associated with the shared information. Therefore, one process can create the IPC object and other processes can refer to the IPC object by the identifier. Linux provides named pipe (also called FIFO) to communication through pipe in two unrelated processes.
A FIFO is created by mkfifo function,
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
mkfifo creates a special file with name pathname. mode specifies the special FIFO file’s permissions. It is modified by the process’s umask: the created file will have the permission (mode & ~umask).
Once a FIFO is created, it can be operated like a usual file with the exception that both ends of FIFO need to be open first before reading and writing can begin. In other words, opening a file for reading blocks until another process open it for writing, and vice versa.
Below are two programs that uses named pipe to communicate with each other. It is modified from the pipe post example.
Firstly, the two programs need to agree on the pipe names. This is defined in a header file included by both of them.
#ifndef TEST_FIFO_H
#define TEST_FIFO_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define CS_FIFO_NAME "/tmp/cs"
#define SC_FIFO_NAME "/tmp/sc"
//user read, user write, group read and other read
#define FIFO_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#endif
Next, the server program creates two pipes for communication and opens one for read and one for write,
#include "fifo.h"
void createfifo() {
int rv;
if ((rv = mkfifo(CS_FIFO_NAME, FIFO_MODE)) == -1) {
perror("error making cs fifo: ");
return;
}
if ((rv = mkfifo(SC_FIFO_NAME, FIFO_MODE)) == -1) {
perror("error making sc fifo: ");
return;
}
}
void server(int readfd, int writefd) {
char msg[100];
int n;
if ((n = read(readfd, msg, 100)) < 0) {
perror("error reading...");
}
msg[n] = '\0';
printf("%d server received from client: %s\n", getpid(), msg);
printf("server enter something: ");
fgets(msg, 100, stdin);
write(writefd, msg, strlen(msg)-1); //-1: not send the newline
}
int main(int argc, char **argv) {
int readfd, writefd;
createfifo();
readfd = open(CS_FIFO_NAME, O_RDONLY, 0);
writefd = open(SC_FIFO_NAME, O_WRONLY, 0);
server(readfd, writefd);
close(readfd);
close(writefd);
return 0;
}
The client program also opens the two fifos for write and read.
#include "fifo.h"
void client(int readfd, int writefd) {
char msg[100];
int n;
char eof = EOF;
printf("%d client enter something: ", getpid());
fgets(msg, 100, stdin);
if (write(writefd, msg, strlen(msg)-1) == -1) { //-1: not send the newline
perror("error writing...");
exit(0);
}
if((n = read(readfd, msg, 100)) < 0){
perror("error reading...");
exit(0);
}
msg[n] = '\0';
printf("client received from server: %s\n", msg);
}
void removefifo() {
unlink(SC_FIFO_NAME);
unlink(CS_FIFO_NAME);
}
int main(int argc, char **argv) {
int readfd, writefd;
writefd = open(CS_FIFO_NAME, O_WRONLY, 0);
readfd = open(SC_FIFO_NAME, O_RDONLY, 0);
client(readfd, writefd);
close(readfd);
close(writefd);
removefifo();
return 0;
}
Note that if we swap the order of the two lines in the client source code, a deadlock will occur.
writefd = open(CS_FIFO_NAME, O_WRONLY, 0);
readfd = open(SC_FIFO_NAME, O_RDONLY, 0);
This is because the server blocks at opening CS_FIFO_NAME for reading and waits for client to open it for writing, if the client opens SC_FIFO_NAME for reading first, it also blocks and waits for server open it for writing. Both programs stuck forever.
Note that similar to pipes, it is also possible to create NONBLOCK FIFOs. Also the PIPE_BUF limits apply to FIFOs.
For a thorough explanation on these subjects, one can refer to reference 2.
References:
1. mkfifo man page: http://linux.die.net/man/3/mkfifo
2. Unix Network Programming, Volumn 2.
Leave a Reply Cancel reply
40% Discount on My Book — Android NDK Cookbook
Android NDK Cookbook ebook 40% discount with promotion code MREANC40 at Packt Publishing The promotion code is valid until 15th June.Categories
- Android Apps (18)
- Android Audio Editor (1)
- TS 2 (3)
- Video Converter Android (8)
- Video2Gif (1)
- Android Tutorial (26)
- Android Dev Tools (1)
- API illustrated (8)
- Multimedia API (3)
- ffmpeg on Android (4)
- NDK (6)
- UI (5)
- Animation (1)
- Code Snippet (2)
- Coding Beyond Technique (18)
- a word, a world (4)
- Bug Rectified (4)
- Programming Habit (1)
- Software as a Career (1)
- Software as User Experience (1)
- Compilers and Related (2)
- ELF (2)
- Computer Languages (31)
- C/C++ (13)
- Java (9)
- JavaScript (2)
- PHP (1)
- Python (8)
- Data Structure & Algorithms (29)
- Bits (1)
- Data Structure (5)
- Integers (10)
- BigInteger (1)
- Prime (4)
- Search (3)
- Sorting (5)
- Strings (5)
- Database (1)
- SQLite (1)
- Digital Signal Processing (33)
- Distributed Systems (17)
- Apache Cassandra (6)
- Apache Hadoop (8)
- Apache Avro (3)
- Apache Nutch (3)
- Apache Solr (1)
- Linux Study Notes (40)
- crontab (1)
- Linux Kernel Programming (8)
- Linux Programming (12)
- IPC (2)
- Linux Network Programming (5)
- Linux Signals (2)
- Linux Shell Scripting (1)
- ssh (3)
- Machinery (30)
- misc (1)
- My Ideas (1)
- My Project (3)
- Mobile Caching (1)
- Selective Decoding (2)
- My Publication (1)
- My Readings (1)
- Networking (15)
- Program for Performance (8)
- Uncategorized (1)
- Virtual Machine (2)
- Web Dev (8)
- web components (3)
- Android Apps (18)
Recent Comments
Archives
- May 2013 (1)
- April 2013 (1)
- March 2013 (4)
- December 2012 (2)
- November 2012 (6)
- October 2012 (6)
- September 2012 (3)
- August 2012 (13)
- July 2012 (15)
- June 2012 (3)
- May 2012 (8)
- April 2012 (4)
- March 2012 (13)
- February 2012 (19)
- January 2012 (9)
- December 2011 (11)
- November 2011 (12)
- October 2011 (4)
- September 2011 (12)
- August 2011 (16)
- July 2011 (15)
- June 2011 (6)
- May 2011 (10)
- April 2011 (13)
- March 2011 (20)
- February 2011 (4)
- November 2010 (2)
- May 2010 (1)
- April 2010 (1)
- February 2010 (1)




