Bloody RS232…. Got API?
I recently wrote this in an e-mail discussion about the project I’ve recently been working on. It’s really a rant, but it’s also true.
In building our GPS tracking system, I had to build a parser for the TETRA device. Fundamentally, this is akin to building a modem driver for a serial modem really. Now, I decided long ago that we would go the route of supporting *nix and win32 accross the board, and we would make choices to facilitate this. This gives us a few things - the ability to develop on windows and unix simultaneously - the ability to provide no-cost and low maintenance solutions for long-term services.
My discovery simply verified my fears of the reality of kernel maturity accross the board.
- Even in the POSIX definition of RS232 I/O there is no well defined standard for accessing RS232. Well, the sad fact actually is, it’s in the POSIX standard, but other things are not. This means it’s inconcistent with most implementations, in some cases in trivial ways, others quite destrutive ways.
- The only clean *nix method was via kernel sysread and syswrite calls, through a POSIX termios interface for charecter flow control. This is a place where true POSIX complience lacks in many OSes IMRE.
- The Win32 API, whilst it provides a more standardised syscall set, requires direct kernel communication, as all of the available libraries are subject to severe limitations.
The result is:
- Unlike most other devices, there is no abstraction away from opening a kernel handle (win32) or filedescriptor (posix/unix) which is reliable and available (no standard ‘driver’ as such, maybe the modern definition of driver).
- Every single API that is available is buggy in some way, this includes API’s for: Perl, Python, Ruby, C/C++ with common OS libs, C#, VB, PHP, BASIC, Assembler. Now that’s a pretty extensive list.
- The above was true of all OSes too.
Some conclusions:
- Most programmers are very very poor indeed. (Many of the win32 libs were going to cause a segfault about every 950 days or so (by statistical calculation), at the data rate they were being used (low))
- Most software never sees proper testing in real world type states, prior to production. - Time and bit-level chaos are hard to test against in poor designs, and designs often miss these possibilities.
- Most people are unable to properly read or utilise standards.
UI oriented design sometimes aids this, and in the case of daemons, I/O oriented design can lead to some high claims too (in C mind.): http://cr.yp.to/qmail/guarantee.html
The modern approach is to provide simple agnostic interfaces between things and to seperate user facing code from system facing code. Whilst this paradigm shift is growing, it hasn’t reached the kernel or OS core libs yet, and may not for another 20 years. This industry moves fast though, and I’m hoping to help one day too, so it may come sooner.