fifo IPC

A FIFO special file (a named pipe) is similar to a pipe, except that it is accessed as part of the filesystem. It can be opened by multiple processes for reading or writing. When processes are exchanging data via the FIFO, the kernel passes all data internally without writing it to the filesystem. Thus, the FIFO special file has no contents on the filesystem; the filesystem entry merely serves as a reference point so that processes can access the pipe using a name in the filesystem. for more info refer manual page(man 3 fifo).

properties of fifo

  • fifo is called named pipe
  • its looks like a file in the linux file system with zero size

Screenshot

* it has to be open at both end (read side and write side) to do any IO operation.

Command to create fifo

 mkfifo $fifo_name

Command to remove/delete fifo

 rm $fifo_name

C API to create fifo

 #include <sys/types.h>
 #include <sys/stat.h>

 int mkfifo(const char *pathname, mode_t mode);

Where: pathname will be your file. mode will be file permission for example 0666

C API to remove/delete fifo

 #include <unistd.h>

 int unlink(const char *pathname);

Examples 1

In this example, will create a writer process which open write-end of fifo and write some string. and a client process which open read-end of fifo and read string sent by server process.

Server process

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

int main()
{
	int i;
	int fd;
	int ret;
	char *myfifo = "/tmp/testfifo";
	char *buff = "Hello\n";

	if (access(myfifo, F_OK) != 0) {
		mkfifo(myfifo, 0666);
	} else {
		printf("fifo %s already exist\n", myfifo);
	}

	fd = open(myfifo, O_WRONLY);
	if (fd < 0) {
		fprintf(stderr, "Failed to open fifo\n");
		return -1;
	}

	for (i=0; i<10; i++) {
		ret = write(fd, buff, strlen(buff));
		if (ret <= 0) {
			fprintf(stderr, "Failed to write to fifo");
		} else {
			printf("%d byte written\n", ret);
		}
		sleep(1);
	}
	sleep(1);

	close(fd);
	return 0;
}

client process

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

int main()
{
	int i;
	int fd;
	int ret;
	char *myfifo = "/tmp/testfifo";
	char buff[10];

	if (access(myfifo, F_OK) != 0) {
		mkfifo(myfifo, 0666);
	} else {
		printf("fifo %s already exist\n", myfifo);
	}

	fd = open(myfifo, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Failed to open fifo\n");
		return -1;
	}

	for (i=0; i<10; i++) {
		memset(buff, 0, sizeof(buff));
		ret = read(fd, buff, sizeof(buff));
		if (ret <= 0) {
			fprintf(stderr, "Failed to read from fifo\n");
		} else {
			printf("read %d byte data: %s\n", ret, buff);
		}
	}
	sleep(1);

	close(fd);
	return 0;
}

Example 2

Writer

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

int main()
{
    int i;
    int fd;
    int ret;
    char *myfifo = "/tmp/testfifo";
    char *buff = "Hello\n";

    if (access(myfifo, F_OK) != 0) {
        mkfifo(myfifo, 0666);
    } else {
        printf("fifo %s already exist\n", myfifo);
    }

    fd = open(myfifo, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open fifo\n");
        return -1;
    }

    for (i=0; i<10; i++) {
        ret = write(fd, buff, strlen(buff));
        if (ret <= 0) {
            fprintf(stderr, "Failed to write to fifo");
        } else {
            printf("%d byte written\n", ret);
        }
        sleep(1);
    }
    sleep(1);

    close(fd);
    return 0;
}


Reader

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

int main()
{
    int i;
    int fd;
    int ret;
    char *myfifo = "/tmp/testfifo";
    char buff[10];

    if (access(myfifo, F_OK) != 0) {
        mkfifo(myfifo, 0666);
    } else {
        printf("fifo %s already exist\n", myfifo);
    }

    fd = open(myfifo, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open fifo\n");
        return -1;
    }

    for (i=0; i<50; i++) {
        memset(buff, 0, sizeof(buff));
        ret = read(fd, buff, sizeof(buff));
        if (ret <= 0) {
            fprintf(stderr, "Failed to read from fifo\n");
        } else {
            printf("read %d byte data: %s\n", ret, buff);
        }
    }
    sleep(1);

    close(fd);
    return 0;
}


Example 3

Writer

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

int main()
{
    int i;
    int fd;
    int ret;
    char *myfifo = "/tmp/testfifo";
    char *buff = "Hello\n";

    if (access(myfifo, F_OK) != 0) {
        mkfifo(myfifo, 0666);
    } else {
        printf("fifo %s already exist\n", myfifo);
    }

    fd = open(myfifo, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open fifo\n");
        return -1;
    }

    for (i=0; i<50; i++) {
        ret = write(fd, buff, strlen(buff));
        if (ret <= 0) {
            fprintf(stderr, "Failed to write to fifo\n");
        } else {
            printf("%d byte written\n", ret);
        }
        sleep(1);
    }
    sleep(1);

    close(fd);
    return 0;
}


Reader

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

int main()
{
    int i;
    int fd;
    int ret;
    char *myfifo = "/tmp/testfifo";
    char buff[10];

    if (access(myfifo, F_OK) != 0) {
        mkfifo(myfifo, 0666);
    } else {
        printf("fifo %s already exist\n", myfifo);
    }

    fd = open(myfifo, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open fifo\n");
        return -1;
    }

    for (i=0; i<10; i++) {
        memset(buff, 0, sizeof(buff));
        ret = read(fd, buff, sizeof(buff));
        if (ret <= 0) {
            fprintf(stderr, "Failed to read from fifo\n");
        } else {
            printf("read %d byte data: %s\n", ret, buff);
        }
    }
    sleep(1);

    close(fd);
    return 0;
}


What is going here.

Example 4

Writer

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

void sigpipe_handler(int sig)
{
	printf("\nreceived SIGPIPE\n");
}

int main()
{
    int i;
    int fd;
    int ret;
    char *myfifo = "/tmp/testfifo";
    char *buff = "Hello\n";

	/* Register sigpipe handler */
	signal(SIGPIPE, sigpipe_handler); 

    if (access(myfifo, F_OK) != 0) {
        mkfifo(myfifo, 0666);
    } else {
        printf("fifo %s already exist\n", myfifo);
    }

    fd = open(myfifo, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open fifo\n");
        return -1;
    }

    for (i=0; i<50; i++) {
        ret = write(fd, buff, strlen(buff));
        if (ret <= 0) {
            fprintf(stderr, "Failed to write to fifo\n");
        } else {
            printf("%d byte written\n", ret);
        }
        sleep(1);
    }
    sleep(1);

    close(fd);
    return 0;
}


Reader

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

int main()
{
    int i;
    int fd;
    int ret;
    char *myfifo = "/tmp/testfifo";
    char buff[10];

    if (access(myfifo, F_OK) != 0) {
        mkfifo(myfifo, 0666);
    } else {
        printf("fifo %s already exist\n", myfifo);
    }

    fd = open(myfifo, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open fifo\n");
        return -1;
    }

    for (i=0; i<10; i++) {
        memset(buff, 0, sizeof(buff));
        ret = read(fd, buff, sizeof(buff));
        if (ret <= 0) {
            fprintf(stderr, "Failed to read from fifo\n");
        } else {
            printf("read %d byte data: %s\n", ret, buff);
        }
    }
    sleep(1);

    close(fd);
    return 0;
}


fifo buffer size

In Linux versions before 2.6.11, the capacity of a pipe/fifo was the same as the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11, the pipe/fifo capacity is 16 pages (i.e., 65,536 bytes in a system with a page size of 4096 bytes). Since Linux 2.6.35, the default pipe/fifo capacity is 16 pages, but the capacity can be modified using the fcntl(2).

To get fifo size

#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

size = fcntl(fd, F_GETPIPE_SZ);

To increase fifo size

fcntl(fd, F_SETPIPE_SZ, new_size);

©2023-2024 rculock.com