A lot of these criticisms are about the OS not doing enough high level stuff for the programmer. If you want to see what happens when the OS does all that, have a look at Android, where the "OS" is what's giving you sockets, key value stores, structured logging, etc. because the only real APIs it's giving you are the Java ones. Now look at the horrible workarounds you need to apply to make old code compatible with newer versions as demands changed over the years tk focus more on user privacy and battery life.
For nearly every problem encountered here there's a standard people just ignore. You can implement structured logging at OS level, like Windows does, and see random binary data drops and text files appear all over your logging interface and your file system. Linux config should follow the XDG standard so that configuration for applications can be structured into directories except half the programs don't do that. Windows provides an API for this stuff (the registry) and it's near impossible to configure an application using the registry. The registry is also combined with random config files all over the system, of course, to make it extra difficult to modify a program's behaviour.
Most nice modern features are also missing because operating systems are still being made in C, not C++. The OS doesn't have a concept of objects so yes your socket function will have to fall back to calling select(). A lot of these abstractions for basic communications have been solved on Linux using DBUS, which provides a somewhat standardised interface for many OS daemon and GUI features, all not being used because programmers forget that it exists or because programmers want to use their own solution instead.
On Windows there's COM to try and help with that and well, see where that ended up: a versioned mess of pointers and factories to try to make it easier for everyone, where functionality sometimes completely breaks or needs to be emulated because it turned out the high level concept had a design flaw and now programs won't work if you fix it.
I've done some thought experiments about structuring an OS and a file system to store data consistently and easily parsable, with modern bindings for most concepts. In the end I've had to conclude that the only way to keep the system working like intended would be to either convince everyone to do exactly as I say or to only allow me to write software for such a system. Whatever structure I can think off will inevitably be too constrained for someone else and the middleware abstraction problem starts all over again.
My only conclusion is that I want the OS to be as simple as possible with people following common standards when they write applications, such as using YAML/ini/XML configuration with Syslogd logging and XDG directory structures for user data, with the technical abstractions left at the library level. If we can just get that, most of the inconsistency problem would be solved, but even this is too difficult to do in practice as it turns out.
For nearly every problem encountered here there's a standard people just ignore. You can implement structured logging at OS level, like Windows does, and see random binary data drops and text files appear all over your logging interface and your file system. Linux config should follow the XDG standard so that configuration for applications can be structured into directories except half the programs don't do that. Windows provides an API for this stuff (the registry) and it's near impossible to configure an application using the registry. The registry is also combined with random config files all over the system, of course, to make it extra difficult to modify a program's behaviour.
Most nice modern features are also missing because operating systems are still being made in C, not C++. The OS doesn't have a concept of objects so yes your socket function will have to fall back to calling select(). A lot of these abstractions for basic communications have been solved on Linux using DBUS, which provides a somewhat standardised interface for many OS daemon and GUI features, all not being used because programmers forget that it exists or because programmers want to use their own solution instead.
On Windows there's COM to try and help with that and well, see where that ended up: a versioned mess of pointers and factories to try to make it easier for everyone, where functionality sometimes completely breaks or needs to be emulated because it turned out the high level concept had a design flaw and now programs won't work if you fix it.
I've done some thought experiments about structuring an OS and a file system to store data consistently and easily parsable, with modern bindings for most concepts. In the end I've had to conclude that the only way to keep the system working like intended would be to either convince everyone to do exactly as I say or to only allow me to write software for such a system. Whatever structure I can think off will inevitably be too constrained for someone else and the middleware abstraction problem starts all over again.
My only conclusion is that I want the OS to be as simple as possible with people following common standards when they write applications, such as using YAML/ini/XML configuration with Syslogd logging and XDG directory structures for user data, with the technical abstractions left at the library level. If we can just get that, most of the inconsistency problem would be solved, but even this is too difficult to do in practice as it turns out.