Unix defects
This tries to list all the defects that are present in Unix, an OS from the early 70's. I consider "Unix" what current Unix clones (BSDs, illumos, Linux, …) have implemented.
None of this should be present in brand new systems except within a cleanly-separated compatibility layer (like Plan9 ape).
NULL
-Terminated strings
O(n)
while length prefix is constant-time aka O(1)
.NULL
. While for length prefix you can reuse the source string as-is via an offset (or pointer), followed by a byte length.NULL
being present in the middle of a string? Or NULL
being absent?errno
Implementation-defined, had to become stored in thread-local-storage in modern systems so it's not actually a global variable… enjoy.
It's also a very poor way to handle errors, if you're wondering where the occasional "Error: Success" comes from: This is it.
And of course, it means having a pretty much static amount of possible errors.
nsswitch.conf
, resolv.conf
, …
Because falsely language-independent configurations with implementation-defined options are the best.
Please consider: Clean ABI; Virtual filesystems (could look like tcb shadow for passwd
); or proper servers instead.
It's associated functions (getaddrinfo(3)
, gethostbyname(3)
, …) also do not allow to do any query that aren't precooked for you, for example you cannot query DNS records like SRV
, arguably it's DNS-specific but still ought to be present in a standard library.
getaddrinfo(3)
Related to nsswitch.conf
.
- Enjoy most developers having to write code to handle multiple records. Hopefully an unreachable/slow host isn't fatal…
- Cannot handle Happy Eyeballs (one of the ways to support IPv6)
- Doesn't handles
SRV
records, similarly to how email is usingMX
records (not handled either but at least it's a special case).
Compare this to Plan9 dial(2)
which also has a nice NetConnInfo
structure.
gethostbyname(3)
The older brother of getaddrinfo(3)
, it doesn't handles multiple records.
Filesystem I/O
Removable storage has been a thing on computers since more or less the beginning (punched cards, tape, floppies, CDs, …).
Buggy storage devices also happen too often to be ignorable.
Networked filesystems and services exposing a filesystem (Plan9, FUSE) have also been there for a long time.
Yet somehow, even modern Unixes usually cannot handle them properly, leaving uninterruptible processes if they happen to use I/O syscalls on an errorneous target.
Even BSD sockets work better on this front (which is probably why libnfs
exists).
Filesystem Queries
Most network protocols today have the ability to ask the server to search inside some database. Meanwhile Unix filesystems don't even integrate glob
, instead this function is stuck to standard libraries. With people relying on third-party I/O-trashing central databases/indexes (again removable/network storage are a thing) from non-standard solutions like locate
that are difficult to reuse in other programs.
Meaning that applications also often roll their own solution.
Compare this to Haiku
Filesystem lack of transactions
On Unixes, thanks to the lack of grouping writes into transactions (ie. BEGIN … COMMIT
in SQL). The only way to get atomicity is to do manual Copy-on-Write: Copy to a temporary location, write there and then rename to the final destination, meaning you need to have full control over it to avoid race-conditions. And for atomicity over multiple files, a common parent directory is needed, otherwise you're in a bad state between the first rename and the last one.
It also means:
- Can't do safe operating system updates without ignoring the traditional hierarchy or separating in different filesystems (luckily ZFS subvolumes exists)
- Horribly slow, you need to copy the file(s), even with hardlinking the ones you're not writing to, it takes a very long time