Wandering Thoughts archives

2011-08-15

A bit about what life was like on Unix before shared libraries

If you look at it right, many MH commands are a relatively thin veneer over a large pool of shared functionality. For example, when you run show to display the current message there is a bunch of infrastructure that turns the concept 'the current message' into a filename for show to open, and of course this infrastructure is common across all MH commands that can work on 'the current message'. Similar bits of infrastructure, large and small, exist across a lot of what MH does (for example, clearly you want each MH command to accept the same arguments for specifying messages to operate on).

MH is written in C. The obvious way to implement all of this shared infrastructure in C is to put it in a library (or several libraries) and then have every MH command link to the infrastructure libraries that it needs (which is usually most of them). Since most of the functionality of MH has been factored out into these libraries, most of its code is library code. All of this is fine and works great on any system with shared libraries; the library code lives in shared libraries and the commands are tiny executables that use the shared libraries.

But Unix did not always have shared libraries, and people have written systems like this on pre-shared-library Unixes (in fact MH itself predates shared libraries). And back in those days, you had a problem; the total size of your system's executables was huge, because each executable was statically linked against these libraries and mostly consisted of duplicated code (wasting both disk and memory space at a time when both were precious).

There was no good solution to this, merely various unpleasant workarounds. One of them was used by the the PBM system (at least as I remember it). Since the executable was the unit of sharing in a pre-shared-library world, PBM could be built so that it merged many of its separate commands into a single executable; the front end code in the executable figured out which command to run by inspecting argv[0]. My memory is that this did not involve refactoring the code, although it did involve contortions in the build process.

(MH itself simply shrugged and used more disk space, perhaps partly because it was already using argv[0] for its own purposes.)

Disclaimer: I may be misremembering which package worked this way. I know that at least one well regarded Unix package did.

unix/BeforeSharedLibraries written at 00:18:43; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.