I kinda wonder if pseduo-devices like /dev/null and /dev/zero are implemented as device drivers within the kernel. I'm sure they are, but not exactly 100% sure. Both /dev/null and /dev/zero device files have same major number but different minor numbers; they use the same driver which doesn't really drive a physical hardware and the minor numbers to specify different functionality within the driver.
Is my hypothesis right?
At least classically, all devices — pseudo or not — were implemented as device drivers in the kernel. Frequently, the implementations of the support functions were minimal for the pseudo-devices. The write code for /dev/null
does nothing successfully (and the same is likely true of /dev/zero
); the read code for /dev/null
reports 'no data'; the read code for /dev/zero
zeroes the buffer that it is given. And so on. Things may have changed a little over the last 20 years, but that's more or less how it used to be and how I'd expect it still to be (but I live to be surprised).
On the Linux system I'm using, and maybe on other Linux systems,
/dev/null
,/dev/zero
and/dev/random
all have the same major number though.
That needn't be a problem. They have different minor numbers, and as a result can and do do different things from each other, just as different disk drives may share a major number but the minor numbers distinguish different subsections of the main device, or even different drives altogether.
On a Mac (running macOS Sierra 10.12.5), /dev/null
and /dev/zero
share the same major number, and /dev/random
and /dev/urandom
share the same major number that's different from the other two.
crw-rw-rw- 1 root wheel 3, 2 Jul 10 20:10 /dev/null
crw-rw-rw- 1 root wheel 14, 0 Jun 13 13:34 /dev/random
crw-rw-rw- 1 root wheel 14, 1 Jun 13 13:34 /dev/urandom
crw-rw-rw- 1 root wheel 3, 3 Jun 13 13:34 /dev/zero
More intriguing is that there are a number of devices with the same major and minor numbers:
crw------- 1 jleffler staff 0, 0 Jul 8 01:54 /dev/console
crw-rw-rw- 1 root wheel 0, 0 Jun 13 13:34 /dev/fbt
crw-rw-rw- 1 root wheel 0, 0 Jun 13 13:34 /dev/lockstat
crw-rw-rw- 1 root wheel 0, 0 Jun 13 13:34 /dev/machtrace
crw-rw-rw- 1 root wheel 0, 0 Jun 13 13:34 /dev/profile
crw-rw-rw- 1 root wheel 0, 0 Jun 13 13:34 /dev/sdt
crw-rw-rw- 1 root wheel 0, 0 Jun 13 13:34 /dev/systrace
I'm not sure how those distinguish what they're supposed to do.