140266059SGregory Neil Shapiro<html> 240266059SGregory Neil Shapiro<head> 340266059SGregory Neil Shapiro <title>libsm Overview</title> 440266059SGregory Neil Shapiro</head> 540266059SGregory Neil Shapiro<body> 640266059SGregory Neil Shapiro 740266059SGregory Neil Shapiro<center> 840266059SGregory Neil Shapiro <h1> libsm Overview </h1> 9*4313cc83SGregory Neil Shapiro <br> $Id: index.html,v 1.14 2001-02-13 21:21:25 gshapiro Exp $ 1040266059SGregory Neil Shapiro</center> 1140266059SGregory Neil Shapiro 1240266059SGregory Neil Shapiro<h2> Introduction </h2> 1340266059SGregory Neil Shapiro 1440266059SGregory Neil ShapiroLibsm is a library of generally useful C abstractions. 1540266059SGregory Neil ShapiroLibsm stands alone; it depends on no other sendmail libraries, 1640266059SGregory Neil Shapiroand the only sendmail header files it depends on are its own, 1740266059SGregory Neil Shapirowhich reside in <tt>../include/sm</tt>. 1840266059SGregory Neil Shapiro 1940266059SGregory Neil Shapiro<h2> Contents </h2> 2040266059SGregory Neil Shapiro 2140266059SGregory Neil ShapiroHere is the current set of packages: 2240266059SGregory Neil Shapiro<blockquote> 2340266059SGregory Neil Shapiro <a href="gen.html"> gen: general definitions </a><br> 2440266059SGregory Neil Shapiro <a href="debug.html"> debug: debugging and tracing </a><br> 2540266059SGregory Neil Shapiro <a href="assert.html"> assert: assertion handling and aborts </a><br> 2640266059SGregory Neil Shapiro <a href="heap.html"> heap: memory allocation </a><br> 2740266059SGregory Neil Shapiro <a href="exc.html"> exc: exception handling </a><br> 2840266059SGregory Neil Shapiro <a href="rpool.html"> rpool: resource pools </a><br> 2940266059SGregory Neil Shapiro <a href="cdefs.html"> cdefs: C language portability macros </a><br> 3040266059SGregory Neil Shapiro <a href="io.html"> io: buffered i/o </a><br> 3140266059SGregory Neil Shapiro</blockquote> 3240266059SGregory Neil Shapiro 3340266059SGregory Neil Shapiro<h2> Naming Conventions </h2> 3440266059SGregory Neil Shapiro 3540266059SGregory Neil Shapiro Some of the symbols defined by libsm 3640266059SGregory Neil Shapiro come from widely used defacto or dejure standards. 3740266059SGregory Neil Shapiro Examples include <tt>size_t</tt> (from the C 89 standard), 3840266059SGregory Neil Shapiro <tt>bool</tt> (from the C 99 standard), 3940266059SGregory Neil Shapiro <tt>strerror</tt> (from Posix), 4040266059SGregory Neil Shapiro and <tt>__P</tt> (from BSD and Linux). 4140266059SGregory Neil Shapiro In these cases, we use the standard name rather than 4240266059SGregory Neil Shapiro inventing a new name. 4340266059SGregory Neil Shapiro We import the name from the appropriate header file when possible, 4440266059SGregory Neil Shapiro or define it ourselves when necessary. 4540266059SGregory Neil Shapiro When you are using one of these abstractions, you must include 4640266059SGregory Neil Shapiro the appropriate libsm header file. 4740266059SGregory Neil Shapiro For example, when you are using <tt>strerror</tt>, you must 4840266059SGregory Neil Shapiro include <tt><sm/string.h></tt> instead of <tt><string.h></tt>. 4940266059SGregory Neil Shapiro 5040266059SGregory Neil Shapiro <p> 5140266059SGregory Neil Shapiro When we aren't implementing a standard interface, 5240266059SGregory Neil Shapiro we use a naming convention that attempts to maximize portability 5340266059SGregory Neil Shapiro across platforms, and minimize conflicts with other libraries. 5440266059SGregory Neil Shapiro Except for a few seemingly benign exceptions, 5540266059SGregory Neil Shapiro all names begin with <tt>SM_</tt>, <tt>Sm</tt> or <tt>sm_</tt>. 5640266059SGregory Neil Shapiro 5740266059SGregory Neil Shapiro <p> 5840266059SGregory Neil Shapiro The ISO C, Posix and Unix standards forbid applications 5940266059SGregory Neil Shapiro from using names beginning with <tt>__</tt> or <tt>_[A-Z]</tt>, 6040266059SGregory Neil Shapiro and place restrictions on what sorts of names can begin 6140266059SGregory Neil Shapiro with <tt>_[a-z]</tt>. Such names are reserved for the compiler and 6240266059SGregory Neil Shapiro the standard libraries. 6340266059SGregory Neil Shapiro For this reason, we avoid defining any names that begin 6440266059SGregory Neil Shapiro with <tt>_</tt>. 6540266059SGregory Neil Shapiro For example, all libsm header file idempotency macros have the form 6640266059SGregory Neil Shapiro <tt>SM_FOO_H</tt> (no leading <tt>_</tt>). 6740266059SGregory Neil Shapiro 6840266059SGregory Neil Shapiro <p> 6940266059SGregory Neil Shapiro Type names begin with <tt>SM_</tt> and end with <tt>_T</tt>. 7040266059SGregory Neil Shapiro Note that the Posix standard reserves all identifiers ending 7140266059SGregory Neil Shapiro with <tt>_t</tt>. 7240266059SGregory Neil Shapiro 7340266059SGregory Neil Shapiro <p> 7440266059SGregory Neil Shapiro All functions that are capable of raising an exception 7540266059SGregory Neil Shapiro have names ending in <tt>_x</tt>, and developers are 7640266059SGregory Neil Shapiro encouraged to use this convention when writing new code. 7740266059SGregory Neil Shapiro This naming convention may seem unnecessary at first, 7840266059SGregory Neil Shapiro but it becomes extremely useful during maintenance, 7940266059SGregory Neil Shapiro when you are attempting to reason about the correctness 8040266059SGregory Neil Shapiro of a block of code, 8140266059SGregory Neil Shapiro and when you are trying to track down exception-related bugs 8240266059SGregory Neil Shapiro in existing code. 8340266059SGregory Neil Shapiro 8440266059SGregory Neil Shapiro<h2> Coding Conventions </h2> 8540266059SGregory Neil Shapiro 8640266059SGregory Neil ShapiroThe official style for function prototypes in libsm header files is 8740266059SGregory Neil Shapiro 8840266059SGregory Neil Shapiro<blockquote><pre> 8940266059SGregory Neil Shapiroextern int 9040266059SGregory Neil Shapirofoo __P(( 9140266059SGregory Neil Shapiro int _firstarg, 9240266059SGregory Neil Shapiro int _secondarg)); 9340266059SGregory Neil Shapiro</pre></blockquote> 9440266059SGregory Neil Shapiro 9540266059SGregory Neil ShapiroThe <tt>extern</tt> is useless, but required for stylistic reasons. 9640266059SGregory Neil ShapiroThe parameter names are optional; if present they are lowercase 9740266059SGregory Neil Shapiroand begin with _ to avoid namespace conflicts. 9840266059SGregory Neil ShapiroEach parameter is written on its own line to avoid very long lines. 9940266059SGregory Neil Shapiro 10040266059SGregory Neil Shapiro<p> 10140266059SGregory Neil ShapiroFor each structure <tt>struct sm_foo</tt> defined by libsm, 10240266059SGregory Neil Shapirothere is a typedef: 10340266059SGregory Neil Shapiro 10440266059SGregory Neil Shapiro<blockquote><pre> 10540266059SGregory Neil Shapirotypedef struct sm_foo SM_FOO_T; 10640266059SGregory Neil Shapiro</pre></blockquote> 10740266059SGregory Neil Shapiro 10840266059SGregory Neil Shapiroand there is a global variable which is defined as follows: 10940266059SGregory Neil Shapiro 11040266059SGregory Neil Shapiro<blockquote><pre> 11140266059SGregory Neil Shapiroconst char SmFooMagic[] = "sm_foo"; 11240266059SGregory Neil Shapiro</pre></blockquote> 11340266059SGregory Neil Shapiro 11440266059SGregory Neil ShapiroThe first member of each structure defined by libsm is 11540266059SGregory Neil Shapiro 11640266059SGregory Neil Shapiro<blockquote><pre> 11740266059SGregory Neil Shapiroconst char *sm_magic; 11840266059SGregory Neil Shapiro</pre></blockquote> 11940266059SGregory Neil Shapiro 12040266059SGregory Neil ShapiroFor all instances of <tt>struct sm_foo</tt>, 12140266059SGregory Neil Shapiro<tt>sm_magic</tt> contains <tt>SmFooMagic</tt>, 12240266059SGregory Neil Shapirowhich points to a unique character string naming the type. 12340266059SGregory Neil ShapiroIt is used for debugging and run time type checking. 12440266059SGregory Neil Shapiro 12540266059SGregory Neil Shapiro<p> 12640266059SGregory Neil ShapiroEach function with a parameter declared <tt>SM_FOO_T *foo</tt> 12740266059SGregory Neil Shapirocontains the following assertion: 12840266059SGregory Neil Shapiro 12940266059SGregory Neil Shapiro<blockquote><pre> 13040266059SGregory Neil ShapiroSM_REQUIRE_ISA(foo, SmFooMagic); 13140266059SGregory Neil Shapiro</pre></blockquote> 13240266059SGregory Neil Shapiro 13340266059SGregory Neil Shapirowhich is equivalent to 13440266059SGregory Neil Shapiro 13540266059SGregory Neil Shapiro<blockquote><pre> 13640266059SGregory Neil ShapiroSM_REQUIRE(foo != NULL && foo->sm_magic == SmFooMagic); 13740266059SGregory Neil Shapiro</pre></blockquote> 13840266059SGregory Neil Shapiro 13940266059SGregory Neil ShapiroWhen an object of type <tt>SM_FOO_T</tt> is deallocated, 14040266059SGregory Neil Shapirothe member <tt>sm_magic</tt> is set to <tt>NULL</tt>. 14140266059SGregory Neil ShapiroThat will cause the above assertion to fail if a dangling pointer is used. 14240266059SGregory Neil Shapiro 14340266059SGregory Neil Shapiro<h2> Additional Design Goals </h2> 14440266059SGregory Neil Shapiro 14540266059SGregory Neil ShapiroHere are some of my design goals: 14640266059SGregory Neil Shapiro<ul> 14740266059SGregory Neil Shapiro <p> 14840266059SGregory Neil Shapiro<li>The sm library is self contained; it does not depend on any other 14940266059SGregory Neil Shapiro sendmail libraries or header files. 15040266059SGregory Neil Shapiro <p> 15140266059SGregory Neil Shapiro<li>The sm library must be compatible with shared libraries, 15240266059SGregory Neil Shapiro even on platforms with weird implementation restrictions. 15340266059SGregory Neil Shapiro I assume that a shared library can export global variables; 15440266059SGregory Neil Shapiro the debug package relies on this assumption. 15540266059SGregory Neil Shapiro I do not assume that if an application redefines a function defined 15640266059SGregory Neil Shapiro in a shared library, the shared library will use the version of the 15740266059SGregory Neil Shapiro function defined in the application in preference to the version 15840266059SGregory Neil Shapiro that it defines. 15940266059SGregory Neil Shapiro For this reason, I provide interfaces for registering handler functions 16040266059SGregory Neil Shapiro in cases where an application might need to override standard behaviour. 16140266059SGregory Neil Shapiro <p> 16240266059SGregory Neil Shapiro<li>The sm library must be compatible with threads. 16340266059SGregory Neil Shapiro The debug package presents a small problem: I don't want 16440266059SGregory Neil Shapiro sm_debug_active to acquire and release a lock. 16540266059SGregory Neil Shapiro So I assume that 16640266059SGregory Neil Shapiro there exists an integral type <tt>SM_ATOMIC_INT_T</tt> 16740266059SGregory Neil Shapiro (see <a href="gen.html"><tt><sm/gen.h></tt></a>) 16840266059SGregory Neil Shapiro that can be accessed and updated atomically. 16940266059SGregory Neil Shapiro I assume that locking must be used to guard updates and accesses to 17040266059SGregory Neil Shapiro any other type, and I have designed the interfaces accordingly. 17140266059SGregory Neil Shapiro</ul> 17240266059SGregory Neil Shapiro 17340266059SGregory Neil Shapiro</body> 17440266059SGregory Neil Shapiro</html> 175