xref: /freebsd/contrib/sendmail/libsm/index.html (revision ee7b0571c2c18bdec848ed2044223cc88db29bd8)
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>&lt;sm/string.h&gt;</tt> instead of <tt>&lt;string.h&gt;</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-&gt;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>&lt;sm/gen.h&gt;</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