This layout emphasizes content more than random-access navigational abilities. You may still find your way around the site by clicking the Navigate This Site... link at the very top of each page. The separate navigation page keeps things nice and organized, and I only need to update a single repository of links whenever I add, edit, or remove pages. Besides, wouldn't it be annoying if everything you read had a table of contents on each and every page?
Please refer to the new weblog for further news updates. The old-style system of new news news synopses is now obsolete.
Well, I have finally commenced writing the socket implementation for OpenAX.25's Link Manager daemon RPC functionality. My progress, so far, is that it opens a socket, binds a UNIX-domain address to it, and is able to close it when programs terminate. Additionally, there is an event loop which handles timeouts gracefully.
It's actually not quite a daemon just yet, but it can be with less than an hour's worth of coding. Here's how:
#include "RPCManager.h"
/* ... */
/* Not needed if you lack a remote "shutdown" command. */
static int done;
/* ... RPC "methods" here ... */
void main(int argc, char *argv[]) {
RPCManager *rpcd = RPCManager_alloc();
int erc;
if(rpcd != NULL) {
if(RPCManager_initWithLocalSocket("/tmp/openAX.25")) {
done = 0;
erc = 0;
while((done == 0) && (erc >= 0))
erc = RPCManager_processPendingEvents(rpcd);
RPCManager_dispose(rpcd);
}
}
}
Still, even with this minimal program to turn it into a real daemon, it is still deaf, dumb, and blind. But, it sure plays a mean pinball.
No support for accepting new connections exists just yet; this will be the next feature to be implemented. After that, handling premature and forced disconnections come next. Neither of these changes will affect the above main(). Only after these two are implemented will the actual RPC (un)marshalling and dispatching be implemented. At this point, main() will probably need to call one or two additional RPCManager procedures to register RPC method tables. But, there's no point unless you can gracefully handle clients segfaulting on you first. :)
How is it possible that I am able to construct the server without having a working client in the wings? The answer is to use dependency injection -- in C.
You read that right -- in C.
To make this work, I wrap the BSD sockets functions that I use into an IPC module. So that, socket() becomes IPC_socket(), read() becomes IPC_read(), etc. (Note: uses of read() that are not socket related need not use the wrapped function.) Then, each function checks to see if an override has been provided. If it has, we invoke the override instead of the normal function:
int IPC_socket(int a, int b, int c) {
if(override -> socket != NULL) return override -> socket(a, b, c);
else return socket(a, b, c);
}
Here, override points to a table of function pointers, which not coincidentally, all have the same signatures as the BSD socket functions they map to. In unit tests, I invoke IPC_useOverrides() to set the override pointer. In production code, I would invoke IPC_useBSDSockets(), which just sets a default table which is identity-mapped against the BSD sockets functions that I would normally use. That way, override is always set, and we always do something useful.
Anyway, this allows me to, with relative ease, completely mock-up not only the kernel's sockets implementation, but also any number of clients on the other side too!! I can confirm interface contracts with the sockets API this way, of course, but far more importantly, I can also evolve the very RPC protocol going over the wire. The unit test framework literally becomes the client, using what basically amounts to be shared-memory as the IPC conveyance mechanism.
Because of extensive use of TDD and a near religious observance of the Law of Demeter, I have a chunk of code which is readily applicable in other C-based server environments. It is written entirely in ANSI C, using the new CUT 3.0 pre-release as its unit-testing framework. No amount of code in the link manager's sockets interface depends, at all, upon the remainder of the link manager's business logic. It is not only easier to maintain, but it is substantially easier to re-use in other projects that might need to be converted to a daemon.
By the way, I chose to use if-statements for each wrapped IPC function because it was, at the time, what seemed like the simplest possible way to make overriding an easy task. In retrospect, specifying &read is just as simple as putting NULL in the read-override's slot, so it's really just slightly less than a wash. I'll fix this later, but it's really low priority for me.
You'd think I'd learn this release often, release early stuff. But, for the last few months, I've had a pretty severe developers block. A contributor broke that, thankfully. Kestrel's Forth now has a functioning outer interpreter (even if it is quite slow), colon compiler, etc. However, there are still a lot of missing features. These will come in time, though. You can find more about it here.
I have received a few reports about this site not being viewable or otherwise hard to use in Microsoft web browsers. Notice that I haven't received any particular complaints from users of other web browsers. This is not a coincidence.
This site is compliant with the XHTML 1.0 and CSS 1 nad CSS 2 standards. These standards are openly available for anyone to inspect and use. Neither CSS nor XHTML are new technologies (indeed, Microsoft helped in the standardization process!). Microsoft has had plenty of time to bring their browsers into compliance, but to date, have failed to do so.
Therefore, I reserve the right to refuse to change my site for the benefit of users of Microsoft browsers. These changes have adverse effects for users on non-Microsoft browsers, which is precisely what Microsoft wants. I feel it is incumbent on the Windows users at large, that means you, to demand proper standards compliance from their products.
In the mean time, if you are interested in using a freely available, more standards compliant browser, I would strongly recommend the following browsers: