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.
👋 I'm Jim, a full-stack product engineer. Want to build an amazing product and a profitable business? Read more about me or Get in touch!

More by Jim

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