190792Sgshapiro<html>
290792Sgshapiro<head>
390792Sgshapiro    <title>libsm Overview</title>
490792Sgshapiro</head>
590792Sgshapiro<body>
690792Sgshapiro
790792Sgshapiro<center>
890792Sgshapiro    <h1> libsm Overview </h1>
9266527Sgshapiro    <br> $Id: index.html,v 1.14 2001-02-13 21:21:25 gshapiro Exp $
1090792Sgshapiro</center>
1190792Sgshapiro
1290792Sgshapiro<h2> Introduction </h2>
1390792Sgshapiro
1490792SgshapiroLibsm is a library of generally useful C abstractions.
1590792SgshapiroLibsm stands alone; it depends on no other sendmail libraries,
1690792Sgshapiroand the only sendmail header files it depends on are its own,
1790792Sgshapirowhich reside in <tt>../include/sm</tt>.
1890792Sgshapiro
1990792Sgshapiro<h2> Contents </h2>
2090792Sgshapiro
2190792SgshapiroHere is the current set of packages:
2290792Sgshapiro<blockquote>
2390792Sgshapiro    <a href="gen.html"> gen: general definitions </a><br>
2490792Sgshapiro    <a href="debug.html"> debug: debugging and tracing </a><br>
2590792Sgshapiro    <a href="assert.html"> assert: assertion handling and aborts </a><br>
2690792Sgshapiro    <a href="heap.html"> heap: memory allocation </a><br>
2790792Sgshapiro    <a href="exc.html"> exc: exception handling </a><br>
2890792Sgshapiro    <a href="rpool.html"> rpool: resource pools </a><br>
2990792Sgshapiro    <a href="cdefs.html"> cdefs: C language portability macros </a><br>
3090792Sgshapiro    <a href="io.html"> io: buffered i/o </a><br>
3190792Sgshapiro</blockquote>
3290792Sgshapiro
3390792Sgshapiro<h2> Naming Conventions </h2>
3490792Sgshapiro
3590792Sgshapiro    Some of the symbols defined by libsm
3690792Sgshapiro    come from widely used defacto or dejure standards.
3790792Sgshapiro    Examples include <tt>size_t</tt> (from the C 89 standard),
3890792Sgshapiro    <tt>bool</tt> (from the C 99 standard),
3990792Sgshapiro    <tt>strerror</tt> (from Posix),
4090792Sgshapiro    and <tt>__P</tt> (from BSD and Linux).
4190792Sgshapiro    In these cases, we use the standard name rather than
4290792Sgshapiro    inventing a new name.
4390792Sgshapiro    We import the name from the appropriate header file when possible,
4490792Sgshapiro    or define it ourselves when necessary.
4590792Sgshapiro    When you are using one of these abstractions, you must include
4690792Sgshapiro    the appropriate libsm header file.
4790792Sgshapiro    For example, when you are using <tt>strerror</tt>, you must
4890792Sgshapiro    include <tt>&lt;sm/string.h&gt;</tt> instead of <tt>&lt;string.h&gt;</tt>.
4990792Sgshapiro
5090792Sgshapiro    <p>
5190792Sgshapiro    When we aren't implementing a standard interface,
5290792Sgshapiro    we use a naming convention that attempts to maximize portability
5390792Sgshapiro    across platforms, and minimize conflicts with other libraries.
5490792Sgshapiro    Except for a few seemingly benign exceptions,
5590792Sgshapiro    all names begin with <tt>SM_</tt>, <tt>Sm</tt> or <tt>sm_</tt>.
5690792Sgshapiro
5790792Sgshapiro    <p>
5890792Sgshapiro    The ISO C, Posix and Unix standards forbid applications
5990792Sgshapiro    from using names beginning with <tt>__</tt> or <tt>_[A-Z]</tt>,
6090792Sgshapiro    and place restrictions on what sorts of names can begin
6190792Sgshapiro    with <tt>_[a-z]</tt>.  Such names are reserved for the compiler and
6290792Sgshapiro    the standard libraries.
6390792Sgshapiro    For this reason, we avoid defining any names that begin
6490792Sgshapiro    with <tt>_</tt>.
6590792Sgshapiro    For example, all libsm header file idempotency macros have the form
6690792Sgshapiro    <tt>SM_FOO_H</tt> (no leading <tt>_</tt>).
6790792Sgshapiro
6890792Sgshapiro    <p>
6990792Sgshapiro    Type names begin with <tt>SM_</tt> and end with <tt>_T</tt>.
7090792Sgshapiro    Note that the Posix standard reserves all identifiers ending
7190792Sgshapiro    with <tt>_t</tt>.
7290792Sgshapiro
7390792Sgshapiro    <p>
7490792Sgshapiro    All functions that are capable of raising an exception
7590792Sgshapiro    have names ending in <tt>_x</tt>, and developers are
7690792Sgshapiro    encouraged to use this convention when writing new code.
7790792Sgshapiro    This naming convention may seem unnecessary at first,
7890792Sgshapiro    but it becomes extremely useful during maintenance,
7990792Sgshapiro    when you are attempting to reason about the correctness
8090792Sgshapiro    of a block of code,
8190792Sgshapiro    and when you are trying to track down exception-related bugs
8290792Sgshapiro    in existing code.
8390792Sgshapiro
8490792Sgshapiro<h2> Coding Conventions </h2>
8590792Sgshapiro
8690792SgshapiroThe official style for function prototypes in libsm header files is
8790792Sgshapiro
8890792Sgshapiro<blockquote><pre>
8990792Sgshapiroextern int
9090792Sgshapirofoo __P((
9190792Sgshapiro	int _firstarg,
9290792Sgshapiro	int _secondarg));
9390792Sgshapiro</pre></blockquote>
9490792Sgshapiro
9590792SgshapiroThe <tt>extern</tt> is useless, but required for stylistic reasons.
9690792SgshapiroThe parameter names are optional; if present they are lowercase
9790792Sgshapiroand begin with _ to avoid namespace conflicts.
9890792SgshapiroEach parameter is written on its own line to avoid very long lines.
9990792Sgshapiro
10090792Sgshapiro<p>
10190792SgshapiroFor each structure <tt>struct sm_foo</tt> defined by libsm,
10290792Sgshapirothere is a typedef:
10390792Sgshapiro
10490792Sgshapiro<blockquote><pre>
10590792Sgshapirotypedef struct sm_foo SM_FOO_T;
10690792Sgshapiro</pre></blockquote>
10790792Sgshapiro
10890792Sgshapiroand there is a global variable which is defined as follows:
10990792Sgshapiro
11090792Sgshapiro<blockquote><pre>
11190792Sgshapiroconst char SmFooMagic[] = "sm_foo";
11290792Sgshapiro</pre></blockquote>
11390792Sgshapiro
11490792SgshapiroThe first member of each structure defined by libsm is
11590792Sgshapiro
11690792Sgshapiro<blockquote><pre>
11790792Sgshapiroconst char *sm_magic;
11890792Sgshapiro</pre></blockquote>
11990792Sgshapiro
12090792SgshapiroFor all instances of <tt>struct sm_foo</tt>,
12190792Sgshapiro<tt>sm_magic</tt> contains <tt>SmFooMagic</tt>,
12290792Sgshapirowhich points to a unique character string naming the type.
12390792SgshapiroIt is used for debugging and run time type checking.
12490792Sgshapiro
12590792Sgshapiro<p>
12690792SgshapiroEach function with a parameter declared <tt>SM_FOO_T *foo</tt>
12790792Sgshapirocontains the following assertion:
12890792Sgshapiro
12990792Sgshapiro<blockquote><pre>
13090792SgshapiroSM_REQUIRE_ISA(foo, SmFooMagic);
13190792Sgshapiro</pre></blockquote>
13290792Sgshapiro
13390792Sgshapirowhich is equivalent to
13490792Sgshapiro
13590792Sgshapiro<blockquote><pre>
13690792SgshapiroSM_REQUIRE(foo != NULL && foo-&gt;sm_magic == SmFooMagic);
13790792Sgshapiro</pre></blockquote>
13890792Sgshapiro
13990792SgshapiroWhen an object of type <tt>SM_FOO_T</tt> is deallocated,
14090792Sgshapirothe member <tt>sm_magic</tt> is set to <tt>NULL</tt>.
14190792SgshapiroThat will cause the above assertion to fail if a dangling pointer is used.
14290792Sgshapiro
14390792Sgshapiro<h2> Additional Design Goals </h2>
14490792Sgshapiro
14590792SgshapiroHere are some of my design goals:
14690792Sgshapiro<ul>
14790792Sgshapiro    <p>
14890792Sgshapiro<li>The sm library is self contained; it does not depend on any other
14990792Sgshapiro    sendmail libraries or header files.
15090792Sgshapiro    <p>
15190792Sgshapiro<li>The sm library must be compatible with shared libraries,
15290792Sgshapiro    even on platforms with weird implementation restrictions.
15390792Sgshapiro    I assume that a shared library can export global variables;
15490792Sgshapiro    the debug package relies on this assumption.
15590792Sgshapiro    I do not assume that if an application redefines a function defined
15690792Sgshapiro    in a shared library, the shared library will use the version of the
15790792Sgshapiro    function defined in the application in preference to the version
15890792Sgshapiro    that it defines.
15990792Sgshapiro    For this reason, I provide interfaces for registering handler functions
16090792Sgshapiro    in cases where an application might need to override standard behaviour.
16190792Sgshapiro    <p>
16290792Sgshapiro<li>The sm library must be compatible with threads.
16390792Sgshapiro    The debug package presents a small problem: I don't want
16490792Sgshapiro    sm_debug_active to acquire and release a lock.
16590792Sgshapiro    So I assume that
16690792Sgshapiro    there exists an integral type <tt>SM_ATOMIC_INT_T</tt>
16790792Sgshapiro    (see <a href="gen.html"><tt>&lt;sm/gen.h&gt;</tt></a>)
16890792Sgshapiro    that can be accessed and updated atomically.
16990792Sgshapiro    I assume that locking must be used to guard updates and accesses to
17090792Sgshapiro    any other type, and I have designed the interfaces accordingly.
17190792Sgshapiro</ul>
17290792Sgshapiro
17390792Sgshapiro</body>
17490792Sgshapiro</html>
175