If we invoke "OOP" here, why not invoke classes? Or rather "interfaces" in modern OOP-speak, or "traits" in other parts of the landscape.
There's a common trait among many objects: you can read a sequence of bytes from it. Disk files, sockets, various input devices, random number generators, etc. There's another common trait, writing a stream of bytes. Another, even more common pair of traits, is "opening" and then "closing" something.
All of them can be described using interfaces / traits to clearly communicate which sets of operations are applicable to which objects.
This e.g. can be neatly used to describe the "many things are a file" idea:
File passwords_file = Filesystem.make("/etc/passwd");
Readable password_readable = passwords_file.openRead(); // Could be openWrite().
Process zcat_process = Processes.make("zcat /tmp/something.gz");
Readable zcat_stdout = zcat_process.stdout.openRead(); // Can only be openRead().
ClientSocket sock = Network.makeClientSocket(host, port, options); // Unlike a file.
Readable sock_readable = sock.openRead();
for (Readable r in [password_readable, zcat_stdout, sock_redable]) {
byte b = r.read(); // Read one byte from each, no matter what it is.
}
But this would require a very different language, way more powerful than C (but also
not C++ please). Unlike in 1969, now we have languages like that, e.g. Rust and ATS-lang. Likely we need another 10-15 years for a viable, somehow widely used OS kernel written in such a language to emerge.