Learn more about Israeli war crimes in Gaza, funded by the USA, Germany, the UK and others.

What is a a FIFO, or “named pipe”? What is mkfifo in C?

Yet Another kind of “file” in UNIX is the “named pipe”, or “FIFO” (“First In, First Out”; i.e. a queue). The named pipe is created with the mkfifo system call. A named pipe is much like a traditional pipe, created with the pipe system call. However, while pipe provides access via two file descriptors, the named pipe is accessed via the filesystem at a path.

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char * path, mode_t mode);

Here’s an example. It creates a FIFO, forks, then the parent process talks to the child via the FIFO. (This could also be achieved with “unnamed pipes”.)

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

char const * const FIFO_PATH = "my_pipe";

int guard(int ret, char * err) {
  if (ret == -1) { perror(err); exit(1); }
  return ret;
}

void write_all(int fd, char * bytes, size_t nbyte) {
  ssize_t written = 0;
  while(written < nbyte) {
    written += guard(write(fd, bytes+written, nbyte-written), "Could not write to pipe");
  }
}

void write_str(int fd, char * chars) { write_all(fd, chars, strlen(chars)); }

int main(void) {
  guard(mkfifo(FIFO_PATH, 0777), "Could not create pipe");
  pid_t child_pid = fork();
  if (child_pid == 0) {
    // Child
    int pipe_read_fd = guard(open(FIFO_PATH, O_RDONLY), "Could not open pipe for reading");
    char buf[4];
    for (;;) {
      ssize_t num_read = guard(read(pipe_read_fd, buf, sizeof(buf)), "Could not read from pipe");
      if (num_read == 0) {
        write_str(1, "Read EOF; closing read end\n");
        guard(close(pipe_read_fd), "Could not close pipe read end");
        break;
      } else {
        write_str(1, "Read from pipe: ");
        write_all(1, buf, num_read);
        write_str(1, "\n");
      }
    }
  } else {
    // Parent
    int pipe_write_fd = guard(open(FIFO_PATH, O_WRONLY), "Could not open pipe for writing");
    write_str(pipe_write_fd, "Hello, pipe");
    guard(close(pipe_write_fd), "Could not close pipe write end");
  }

  return 0;
}

This prints:

$ ./a.out
Read from pipe: Hell
Read from pipe: o, p
Read from pipe: ipe
Read EOF; closing read end
Tagged #posix, #c, #programming, #ipc, #file-io, #pipes, #system-calls.

Similar posts

More by Jim

Want to build a fantastic product using LLMs? I work at Granola where we're building the future IDE for knowledge work. Come and work with us! Read more or get in touch!

This page copyright James Fisher 2017. Content is not associated with my employer. Found an error? Edit this page.