16

What is the difference between mkfifo() and mknod() while creating a named pipe?

I tried searching but couldn't get a satisfactory answer.

Delapouite
  • 9,469
  • 5
  • 36
  • 41
babybear
  • 804
  • 1
  • 10
  • 24

1 Answers1

26

Using mkfifo() is standardized and portable. Using mknod() in general, is not portable — it is a part of POSIX (despite a statement to the contrary in an earlier version of this answer). The POSIX specification says that mkfifo() should be preferred. Otherwise, there is no difference between a FIFO created by mkfifo() and mknod().

Note that mknod() can be used to create other device types than just FIFOs. It can create block special and character special devices. Once upon a very (very, very) long time ago, mknod() was used to create directories too — in the days before there was a mkdir() or rmdir() system call. After creating the directory, you had to use link() twice to create the . and .. entries in the new directory. (And you had to have root privileges to use it, so the mkdir and rmdir commands were SUID root.) File systems are a lot more reliable nowadays because that's no longer part of the game.

Reference: Version 7 Unix — circa 1979.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    Uhm, my `mknod` manpage says «POSIX.1-2001 says: "The only portable use of `mknod()` is to create a FIFO-special file. If `mode` is not `S_IFIFO` or `dev` is not `0`, the behavior of `mknod()` is unspecified."», so it seems that `mknod` with `S_IFIFO` *is* indeed standard. This is confirmed by http://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html, with the caveat that "The `mkfifo()` function is preferred over this function for making FIFO special files." – Matteo Italia Mar 26 '17 at 00:19
  • 1
    @MatteoItalia: Oh — hmm, thanks. You're correct that `mknod()` is in POSIX — much to my surprise. Given the existence of `mkfifo()` (and `mkdir()` and `rmdir()`), the function is really superfluous; I'm surprised that it is standardized. It's curious that the function is illustrated in the spec with an uninitialized value for the third argument: `dev_t dev; int status = mknod("/home/cnd/mod_done", S_IFIFO | S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, dev);` — `dev` is not shown as initialized. Setting it to 0 would be sane; there was verbiage in the 7th Edition manual suggesting that. – Jonathan Leffler Mar 26 '17 at 00:29