CFL is a library that aims to simplify systems software development under UNIX. The library consists of several groups of functions and macros that simplify such common tasks as memory allocation, string parsing, subprocess execution, filesystem traversal, and so on.
In addition, the library includes efficient implementations of some common data structures, such as linked lists, queues, and hash tables, as well as other less common data structures. Many of these types of tasks involve tricky pointer arithmetic and memory management and are inherently error-prone. Moving this common logic into a library frees the developer from having to recode and debug this functionality each time it is needed.
Finally, the library provides a simple, high-level interface to several UNIX IPC mechanisms, including semaphores, shared memory, and Berkeley sockets.
The following chapters describe all of the datatypes, constants, macros, and functions in the library in detail. Function and datatype indices are provided at the end of the manual.
The CFL library exists in two forms: the multi-threaded version and
the single-threaded version. The single-threaded version is named
libcfl.a or libcfl.so and the multi-threaded version is
named libcfl_mt.a or libcfl_mt.so.
Therefore, to link with the single-threaded version of the CFL library, issue a command such as:
gcc file1.o file2.o -o myprogram -lcfl
And similarly, to link with the multi-threaded version:
gcc file1.o file2.o -o myprogram -lcfl_mt
If your code uses the XML functions, it will also need to be linked with the expat library, e.g.:
gcc file1.o file2.o -o myprogram -lcfl -lexpat
Finally, if your code uses the networking functions, you may need to link with additional libraries. No additional libraries are required under Linux. Under Solaris, the socket and nsl libraries are required, e.g.:
gcc file1.o file2.o -o myprogram -lcfl -lsocket -lnsl
It is extremely important that multi-threaded programs only be linked with the multi-threaded version of the library, and that single-threaded programs only be linked with the single-threaded version. Other combinations will produce undefined behavior in your programs.
All of the definitions in the library can be made available by including
the master header file cfl/cfl.h.
This section describes the naming and calling conventions for constants, macros, datatypes, and functions in the CFL library.
All functions and macros begin with the prefix C_.
All constants begin with the prefix C_, with the following
exception: TRUE, FALSE, NUL, and CRLF.
All datatypes begin with the prefix c_ and end with the suffix
_t, with the following exceptions: uint_t.
Unless their fields are expressly documented, all datatypes which begin
with the prefix c_ should be considered opaque. This means
that pointers to these datatypes serve only as "handles" which are
passed to and returned by the functions which operate on those
datatypes. The caller should never directly modify these datatypes or
the fields of the data structures that they represent. The internal
layout of these data structures may change in future versions of the
library; manipulating them only through API calls will ensure that your
code will continue to compile and function properly.
Most functions which return a pointer will by convention return
NULL on failure.
Functions which return a boolean (c_bool_t) or an integer will by
convention return TRUE or a nonzero value to indicate success and
FALSE or 0 to indicate failure. Note that this is different
from the typical UNIX convention of returning 0 on success and a
nonzero value (typically -1) on failure. Since TRUE is
defined as a nonzero value and FALSE is defined as 0, the
following forms are equivalent:
if(C_system_cdhome() == FALSE)
puts("Failed.");
if(! C_system_cdhome())
puts("Failed.");
With some exceptions (as documented), the functions in the CFL library are reentrant. This means that they can be safely accessed from concurrent threads without the need for explicit synchronization.
However, calls to functions which manipulate data structures (such as linked lists, hash tables, and XML documents) must be synchronized by the caller in such a way that only one thread is modifying the data structure at any given time. For example, an insert into a linked list by one thread with a concurrent insert (or some other operation) on the same linked list by another thread might result in corruption of the data structure.
In most cases, it is necessary to use reader/writer locks to ensure that a reader (a thread that is accessing but not modifying the data structure) does not access the data structure while another thread is modifying it.
This version of the library has been ported to Sun Solaris 2.8, Linux (kernel 2.x), and Mac OS X 10.2.
The dlsym() family of functions are not available on Mac OS X;
however, an add-on library, dlcompat, is available that provides
these functions; it may be obtained at
<http://www.opendarwin.org/projects/dlcompat/>. This add-on library
must be installed in order to use CFL on Mac OS X.
The real-time scheduler is based on the POSIX.4 real-time signal
facility. As of this writing, this facility is only available
on Solaris; it is broken on Linux and is not available at all on OS
X. On the latter platforms, the event loop in the multi-threaded version
of the library is implemented using nanosleep() instead--this
workaround is suboptimal since it produces clock drift over time, which may
result in missed events.
CFL was previously known as pingutil, the PING Utility Library. Unfortunately, this name caused the library to be frequently confused with the ICMP "ping" utility program, with which it has absolutely nothing in common. When the library was renamed, all of the functions, types, and some of the header files were renamed as well.
The final version of pingutil was 2.3, so version 1.0 of CFL is equivalent to what would have been version 2.4 of pingutil. The initial version of CFL constitutes a significant update of the library API over pingutil; therefore it was not feasible to provide compatibility headers to map the old API onto the new one.
This chapter describes convenience types, macros, and constants. These are
defined in the header cfl/defs.h.
The type c_bool_t represents a boolean value that (by convention)
can take on the values TRUE or FALSE; these are macros
defined to be (1) and (0), respectively.
The type c_byte_t represents an unsigned 8-bit value (0 - 255).
The type uint_t represents an unsigned integer.
The following convenience macros are provided:
| C_max (a, b) | Macro |
| C_min (a, b) | Macro |
| C_sgn (a) | Macro |
|
The first two macros correspond to the mathematical max and min
functions. |
| C_bit_set (i, b) | Macro |
| C_bit_clear (i, b) | Macro |
| C_bit_isset (i, b) | Macro |
|
These macros set, clear, and test the b'th bit of i (which is presumably an integer) using bitwise operators. Each evaluates its arguments only once. |
| C_offsetof (type, element) | Macro |
|
This macro returns the offset, in bytes, of the element named
element in the aggregate type type (which is presumably a
struct). It works similarly to the X11 macro |
| C_lengthof (array) | Macro |
|
This macro returns the length of (the number of elements in) the array array, which is assumed to be a stack-allocated array. If array is a pointer, the results are undefined. |
The header file also defines the following constants:
NUL
NULL, the NULL pointer, a constant that is defined in
stdio.h.
CRLF
"\r\n", or carriage return and line feed.
This chapter describes functions involving system facilities such as
I/O, subprocess execution, error handling, and memory management. They
are divided into several groups; the functions in a group share a common
name prefix for that group; e.g., all filesystem-related functions have
names that begin with C_file_. All of the constants, macros, and
functions described in this chapter are defined in the header
cfl/system.h.
The following sections describe each group in detail.
The following functions convert various numeric types between host and network byte order.
| uint16_t C_byteord_htons (uint16_t val) | Function |
| uint16_t C_byteord_ntohs (uint16_t val) | Function |
|
These functions convert an unsigned 16-bit "short" integer val to and from network byte order, respectively. The functions return the converted value. |
| uint32_t C_byteord_htonl (uint32_t val) | Function |
| uint32_t C_byteord_ntohl (uint32_t val) | Function |
|
These functions convert an unsigned 32-bit "long" integer val to and from network byte order, respectively. The functions return the converted value. |
| uint64_t C_byteord_htonll (uint64_t val) | Function |
| uint64_t C_byteord_ntohll (uint64_t val) | Function |
|
These functions convert an unsigned 64-bit "long long" integer val to and from network byte order, respectively. The functions return the converted value. |
| float C_byteord_htonf (float val) | Function |
| float C_byteord_ntohf (float val) | Function |
|
These functions convert an 32-bit floating point value val to and from network byte order, respectively. The functions return the converted value. |
| double C_byteord_htond (double val) | Function |
| double C_byteord_ntohd (double val) | Function |
|
These functions convert an 64-bit double-precision floating point value val to and from network byte order, respectively. The functions return the converted value. |
The following functions are provided to aid in the debugging and tracing of code.
| void C_debug_printf (const char *format, ...) | Function |
|
This function is similar to Debug messages are written to the debugging stream ( If tracing is enabled, the message will be preceded by the source file
name and line number of the |
| void C_debug_set_trace (c_bool_t flag) | Function |
| void C_debug_set_stream (FILE * stream) | Function |
|
These functions alter the behavior of the
|
| void C_debug_set_termattr (c_bool_t flag) | Function |
|
This function enables or disables the use of ANSI color and text style terminal attributes for debug messages. This feature is enabled by default, and causes all debug messages (when written to a tty) to be printed in a bold font, and assertion failure messages in particular to be printed in red. |
| C_assert (expr) | Macro |
|
This macro evaluates an assertion; it is provided as a replacement for
the more rudimentary If the expression expr evaluates to zero ( |
The following functions provide a means to dynamically load and unload
object files at runtime and to obtain pointers to symbols (including
variables and functions) defined in those files. These functions are
based on the dlopen(), dlsym(), and dlclose()
library functions.
The type c_dlobject_t represents a loadable object.
| c_dlobject_t * C_dlobject_create (const char *path) | Function |
| c_bool_t C_dlobject_destroy (c_dlobject_t *obj) | Function |
|
These functions create and destroy loadable objects.
|
| c_bool_t C_dlobject_load (c_dlobject_t *obj, c_bool_t lazy) | Function |
| c_bool_t C_dlobject_unload (c_dlobject_t *obj) | Function |
|
These functions load and unload the loadable object
obj.
The functions return |
| void * C_dlobject_lookup (c_dlobject_t *obj, const char *symbol) | Function |
|
This function looks up the symbol named symbol in the loadable
object obj. It returns a pointer to the symbol on success, or
|
| c_bool_t C_dlobject_isloaded (c_dlobject_t *obj) | Function |
|
This function (which is implemented as a macro) returns |
| const char * C_dlobject_error (c_dlobject_t *obj) | Function |
|
In the case of a failed call to one of the dynamic linker library functions, an error message is stored in obj; this function (which is implemented as a macro) returns that message. |
| const char * C_dlobject_path (c_dlobject_t *obj) | Function |
|
This function (which is implemented as a macro) returns the file path of the loadable object obj. |
The following functions are provided to simplify the reporting of user- and system-level error messages to the console.
| void C_error_init (const char *progname) | Function |
|
A call to this function initializes the error handling routines. The
argument progname is the name of the currently executing program,
which can be obtained from the argument list as |
| void C_error_printf (const char *format, ...) | Function |
|
This function receives arguments in the same manner as the
|
| void C_error_usage (const char *usage) | Function |
|
This function prints the command-line usage information message usage to standard error. It then flushes the standard error stream. |
| void C_error_syserr (void) | Function |
|
This function is a higher-level interface to the |
| int C_error_get_errno (void) | Function |
|
This function returns the error code from the last-executed CFL library
routine. A return value of Calling this routine is equivalent to evaluating Therefore in both single-threaded and multi-threaded code, it is safe to
call |
| void C_error_set_errno (int err) | Function |
|
This function sets the error code for the currently executing CFL library routine to err. This function is provided for use by CFL extension libraries and is not intended for use by user code. In the multi-threaded version of the library, |
The following functions provide subprocess control, including
higher-level interfaces to system calls such as execv(), and
piping.
| int C_exec_run (char **argv, int fdin, int fdout, c_bool_t waitf) | Function |
| int C_exec_run_cwd (char **argv, int fdin, int fdout, c_bool_t waitf, const char *cwd) | Function |
|
If waitf is |
| int C_exec_va_run (int fdin, int fdout, c_bool_t waitf, ... /* , NULL */) | Function |
| int C_exec_va_run_cwd (int fdin, int fdout, c_bool_t waitf, const char *cwd, ... /* , NULL */) | Function |
|
These are variable argument list versions of |
| int C_exec_pipefrom (char **argv, int *fd) | Function |
| int C_exec_pipefrom_cwd (char **argv, int *fd, const char *cwd) | Function |
|
The functions return The following code illustrates the use of int fd, r;
char buf[100], **args;
FILE *fp;
args = C_string_va_makevec(NULL, "/bin/ls", "-al",
"/usr/local/bin", NULL);
r = C_exec_pipefrom(args, &fd);
if(r != -1)
{
fp = fdopen(fd, "r");
while(C_io_gets(fp, buf, sizeof(buf), '\n') != EOF)
printf("Received: %s\n", buf);
fclose(fp);
}
C_free_vec(args);
|
| int C_exec_pipeto (char **argv, int *fd) | Function |
| int C_exec_pipeto_cwd (char **argv, int *fd, const char *cwd) | Function |
|
The functions return |
| int C_exec_va_call (const char *arg, ... /* , NULL */) | Function |
|
This function is intended for use as a replacement for the unsafe
On success, the function returns the exit status from the subprocess. On
failure, it returns |
| int C_exec_wait (pid_t pid) | Function |
|
This function is an interface to the |
The following functions provide for the manipulation of files and directories in the UNIX filesystem.
| c_bool_t C_file_readdir (const char *path, c_dirlist_t *dir, int flags) | Function |
|
This function reads the names of the files in the directory specified by path into the directory list pointed to by dir. The type c_dirlist_t represents a directory file list. Specific directory reading options are specified in the flags argument, which is a bitwise OR of the following macros:
The c_dirlist_t type is a structure that contains the following members:
The function ignores all files which are not regular files or directories, including symbolic links. The function returns |
| c_bool_t C_file_traverse (const char *path, c_bool_t (*examine) (const char *file, const struct stat *fst, uint_t depth, void *hook), void *hook) | Function |
|
This is a general purpose directory tree traversal function. It begins
descending a directory tree rooted at path, recursing on
subdirectories. For each directory or regular file encountered, it calls
the function examine() with its name, its struct stat
information, and the file's depth from the original path. If the
examine() function returns The pointer hook may be used to pass arbitrary context data during the traversal. This pointer will be passed to the examine() function on each invocation. The examine() function should not change the current working directory, as this will confuse the traversal routine. If changing the working directory is unavoidable, the function should save the working directory on entry and restore it before returning. The function returns The following code fragment prints an outline-style list of all of the files and subdirectories beginning at the current working directory. c_bool_t examine(const char *file, const struct stat *fst,
uint_t depth, void *hook)
{
int i;
/* indent and print filename */
for(i = depth * 2; (i--); putchar(' '));
puts(file);
return(TRUE);
}
void outline(void)
{
C_file_traverse(".", examine, NULL);
}
|
| const char * C_file_getcwd (void) | Function |
|
This function is a higher-level interface to the |
| c_bool_t C_file_issymlink (const char *path) | Function |
|
This function returns |
| c_bool_t C_file_mkdirs (const char *path, mode_t mode) | Function |
|
This function creates all intermediate directories specified in
path. Directories will be created with the permissions specified
by mode. The function returns |
| void * C_file_load (const char *path, size_t *len) | Function |
|
This function loads the entire file specified by path into memory. The size of the file (that is, the number of bytes read) is stored at len. On success, the function returns a pointer to the dynamically allocated
buffer containing the data. The buffer will contain the entire contents
of the file, plus a single trailing On failure (for example, if path or len is |
The following functions implement mandatory file locks. Reader/writer
locks and simple filesystem-based semaphores can be implemented using
these functions. These functions lock and unlock entire files; finer
granularity locks may be implemented using the fcntl() system
call.
| c_bool_t C_file_lock (FILE *fp, int type) | Function |
|
This function locks an open file fp. The type of lock is specified
by type and must be one of The function returns |
| c_bool_t C_file_trylock (FILE *fp, int type) | Function |
|
This function is similar to The function returns |
| c_bool_t C_file_unlock (FILE *fp, int type) | Function |
|
This function removes the lock on the file fp. The type of lock is
specified by type, and must match the type value that was
used for the The function returns |
The following functions simplify reading from and writing to files and obtaining input from the console.
| int C_io_getchar (uint_t delay) | Function |
|
This function is meant to be used as a replacement for If the delay expires before a character is typed, the function returns
|
| int C_io_gets (FILE *fp, char *buf, size_t bufsz, char termin) | Function |
|
This function is meant to be used as a replacement for the
The function returns the number of bytes actually read, or If fp or buf is |
| int C_io_getpasswd (const char *prompt, char *buf, size_t bufsz) | Function |
|
This function is a general-purpose password input routine. It writes the
prompt string prompt to standard output, turns off echoing on the
controlling terminal, reads data from standard input into the buffer
buf in the same manner as |
| char * C_io_getline (FILE *fp, char termin, int *len) | Function |
|
This function is a dynamic line input routine. It reads a line of unlimited length from the stream fp, stopping once the terminator character termin is encountered. It allocates memory as needed to store the data being read from the stream. Once the terminator character is encountered, it is discarded and the
string is On success, the function returns a pointer to the dynamically allocated
buffer, which is exactly large enough to hold the |
| char * C_io_getline_buf (FILE *fp, char termin, c_buffer_t *buf) | Function |
|
This function is similar to On success, the function returns the pointer to the data in buf,
as returned by the macro |
| C_getchar () | Macro |
|
This is a convenience macro. It evaluates to an expression involving a
call to |
| C_gets (buf, bufsz) | Macro |
|
This is a convenience macro. It evaluates to an expression involving a
call to |
| C_getline (fp, len) | Macro |
|
This is a convenience macro. It evaluates to an expression involving a
call to |
| int C_io_fprintf (FILE * stream, const char *format, ...) | Function |
|
This is a threadsafe wrapper for the The function returns the value returned by |
| int C_printf (const char *format, ...) | Function |
|
This function (which is implemented as a macro) calls
|
The following functions provide a simple, minimal API for writing log messages to the console and/or a log file.
| void C_log_set_console (c_bool_t flag) | Function |
|
This function enables or disables the writing of log messages to the console (that is, the standard error stream) based on the value of flag. By default, log messages are written to the console. |
| void C_log_set_stream (FILE *stream) | Function |
|
This function specifies the stream for log messages. If
stream is |
| void C_log_set_termattr (c_bool_t flag) | Function |
|
This function enables or disables the use of ANSI color and text style terminal attributes for log messages. This feature is enabled by default, and causes all log messages (when written to a tty) to be printed in a bold font, and to be color coded according to severity. |
| void C_log_info (const char *fmt, ...) | Function |
| void C_log_warning (const char *fmt, ...) | Function |
| void C_log_error (const char *fmt, ...) | Function |
|
These Each message will be prefixed by the current date and time. Messages written to the console (the standard error stream) will be written in a bold font and color-coded to reflect the severity of the error, assuming that the stream is a tty and that terminal attributes are enabled. |
The following functions and macros simplify memory management in
C. These routines provide more convenient interfaces to the standard
malloc() family of library functions.
| void * C_mem_manage (void *p, size_t elemsz, c_bool_t clearf) | Function |
|
This is a general-purpose memory management function. It is a
higher-level interface to the If the memory allocation fails, the allocation error handler (if one has
been installed) will be called. If the error handler returns
The function returns a pointer to the newly allocated memory on success,
or Some of the memory management macros described below evaluate to calls to this function. |
| void C_mem_set_errorfunc (c_bool_t (*func)(void)) | Function |
|
This function allows the user to specify a memory allocation request
failure handler. func will be called each time
If func is |
| void C_mem_set_alloc_hook (void (*func)(const void *p_old, const void *p_new, size_t len)) | Function |
|
This function sets the memory allocation hook function to
func. The allocation hook will be called each time memory is
allocated, reallocated, or freed using the memory functions described in
this section, or by any of the functions in this library which perform
dynamic memory allocation. The allocation hook function may be
uninstalled by passing The meaning of the arguments passed to the allocation hook functions depends on the type of memory operation that was performed, as described below. The hook is always called after the memory operation has been performed.
Never dereference the pointer p_old, as it no longer points to allocated memory. |
| void C_mem_default_alloc_hook (const void *p_old, const void *p_new, size_t len) | Function |
|
This function is a default memory allocation hook function which writes
an informational log message for each memory allocation using
|
| void * C_mem_free (void *p) | Function |
|
This function is simply an interface to the |
| void C_mem_freevec (char **v) | Function |
|
This function frees a |
| uint_t C_mem_va_free (uint_t n, ...) | Function |
|
This function is a variable-argument interface to the The function returns the number of non- |
| size_t C_mem_defrag (void *p size_t elemsz, size_t len, c_bool_t (*isempty)(void *elem)) | Function |
|
This is a general-purpose memory defragmentation routine. It interprets
the memory at p as an array of len elements, each
elemsz bytes in size. isempty is a pointer to a function
which, when passed a pointer to one of the elements in the array,
determines if it is "used" or "empty" and returns The function iterates through the elements in the array, testing each element using isempty(), and moving contiguous blocks of "used" elements toward the beginning of the array until all "free" space has been coalesced at the end. The order of the elements within the array is preserved. The function returns the number of "used" elements in the array. This return value can be used in a subsequent call to one of the memory allocation routines to reduce the size of the defragmented array to allow the unused space to be reclaimed by the system. |
| C_malloc (n, type) | Macro |
| C_calloc (n, type) | Macro |
|
These macros are convenient replacements for the C_malloc(5, char *)
would have a return value of type char **, that is, a pointer to 5 contiguous character pointers.
|
| C_realloc (p, n, type) | Macro |
|
This macro is a convenient replacement for the |
| C_zero (p, type) | Macro |
| C_zeroa (p, n, type) | Macro |
|
These macros zero the specified memory. |
| C_free (p) | Macro |
| C_free_vec (v) | Macro |
| C_va_free (n, ...) | Macro |
|
These are additional convenience macros for freeing
memory.
|
| C_new (type) | Macro |
| C_newa (n, type) | Macro |
| C_newb (n) | Macro |
| C_newstr (n) | Macro |
|
These are additional convenience macros for allocating
memory. These macros all expand to expressions involving the char *s = C_newstr(45);
struct foobar *item = C_new(struct foobar);
int *scores = C_newa(20, int);
|
The following functions provide a high-level interface to memory mapped files. A memory mapped file is a disk file that has been mapped into the calling process's address space; the contents of the file may be manipulated by modifying memory directly. This mechanism is especially useful for very large files, as the operating system takes care of the details of paging portions of the file in and out of memory as needed, and of keeping the contents of the disk file in sync with the data that is in memory.
The type c_memfile_t represents a memory mapped file.
| c_memfile_t * C_memfile_open (const char *file, c_bool_t readonly) | Function |
|
This function opens the specified file and maps it into memory. If
readonly is The function returns a pointer to the new c_memfile_t structure on
success, or |
| c_bool_t C_memfile_close (c_memfile_t *mf) | Function |
|
This function unmaps the memory mapped file mf and closes the file. A sync operation is performed just before the file is unmapped to ensure that any pending updates are persisted to the disk file. The function returns |
| c_bool_t C_memfile_sync (c_memfile_t *mf, c_bool_t async) | Function |
|
The operating system periodically performs a sync operation to keep the
contents of the disk file up to date with the memory-resident image of
the file. This function forces such an update to take place immediately
on the memory mapped file mf. If async is The function returns |
| c_bool_t C_memfile_resize (c_memfile_t *mf, off_t length) | Function |
|
This function resizes the memory mapped file mf to the new size length. The new length must be at least 0. If length is smaller than the current length of the file, the file will be truncated and the excess data will be lost. If length is larger than the current length of the file, the file will grow to the new size, and the extra bytes will be zeroed. The function returns |
| void * C_memfile_base (c_memfile_t *mf) | Function |
|
This function returns a pointer to the beginning of the memory occupied by the memory mapped file mf. It is implemented as a macro. |
| void * C_memfile_pointer (c_memfile_t *mf, off_t offset) | Function |
|
This function returns a pointer to the given offset offset in the memory mapped file mf. It is implemented as a macro. |
| off_t C_memfile_length (c_memfile_t *mf) | Function |
|
This function returns the current length of the memory mapped file mf. It is implemented as a macro. |
The following functions provide various information about the system and about users and groups.
| c_bool_t C_system_ingroup (const char *login, const char *group) | Function |
|
This function determines if the user whose login name is login belongs to the group named group. It can be used for authentication purposes. The function returns |
| c_sysinfo_t * C_system_getinfo (void) | Function |
|
This function obtains various types of information about the system, the current process and user, the terminal line, and the system time. The function stores the information in a static data structure, to which it returns a pointer. The c_sysinfo_t structure has the following members:
The first time the function is called, it fills the static data structure with values retrieved from the system. Subsequent calls immediately return the pointer to this structure. |
| uid_t C_system_get_uid (void) | Function |
| gid_t C_system_get_gid (void) | Function |
| pid_t C_system_get_pid (void) | Function |
| char * C_system_get_login (void) | Function |
| char * C_system_get_fullname (void) | Function |
| char * C_system_get_homedir (void) | Function |
| char * C_system_get_hostname (void) | Function |
| char * C_system_get_term (void) | Function |
|
These are convenience functions that retrieve some of the more interesting values from the static c_sysinfo_t structure. |
| c_bool_t C_system_cdhome (void) | Function |
|
This function attempts to set the current working directory to the
current user's home directory. It obtains the home directory path via a
call to The function returns |
| c_bool_t C_system_passwd_generate (const char *passwd, char *buf, size_t bufsz) | Function |
|
This function generates an encrypted password using the standard UNIX
The function returns |
| c_bool_t C_system_passwd_validate (const char *plaintext, const char *ciphertext) | Function |
|
This function validates a plaintext password against the encrypted form
of the password using the standard UNIX |
This chapter describes various utility functions. They are divided into
several groups; the functions in a group share a common name prefix for
that group; e.g., all string-related functions have names that begin
with C_string_. All of the constants, macros, and functions
described in this chapter are defined in the header
cfl/util.h.
The following sections describe each group in detail.
The following functions provide for the manipulation of bit strings of arbitrary length. Bit strings may be used to efficiently store groups of related boolean (on/off) flags; each 8-bit byte can represent 8 such flags.
The type c_bitstring_t represents a bit string.
| c_bitstring_t * C_bitstring_create (uint_t nbits) | Function |
| c_bool_t C_bitstring_destroy (c_bitstring_t *bs) | Function |
|
These functions create and destroy bit strings.
|
| c_bool_t C_bitstring_set (c_bitstring_t *bs, uint_t bit) | Function |
| c_bool_t C_bitstring_clear (c_bitstring_t *bs, uint_t bit) | Function |
|
These functions set and clear the bit at offset bit in the bit
string bs. The functions return |
| c_bool_t C_bitstring_set_range (c_bitstring_t *bs, uint_t sbit, uint_t ebit) | Function |
| c_bool_t C_bitstring_clear_range (c_bitstring_t *bs, uint_t sbit, uint_t ebit) | Function |
|
These functions set or clear a range of bits in the bit string
bs. The functions return |
| c_bool_t C_bitstring_set_all (c_bitstring_t *bs) | Function |
| c_bool_t C_bitstring_clear_all (c_bitstring_t *bs) | Function |
|
These functions set or clear all of the bits in the bit string
bs. The functions return |
| c_bool_t C_bitstring_isset (c_bitstring_t *bs, uint_t bit) | Function |
| c_bool_t C_bitstring_isclear (c_bitstring_t *bs, uint_t bit) | Function |
|
These functions test bits in the bit string
bs. The functions return |
| c_bool_t C_bitstring_compare (c_bitstring_t *bs1, c_bitstring_t *bs2) | Function |
|
This function compares the bit string bs1 to the bit string
bs2. It returns The function returns |
| uint_t C_bitstring_size (c_bitstring_t *bs) | Function |
|
This function, which is implemented as a macro, returns the size (in bits) of the bit string bs. |
The following functions and macros are provided for the manipulation of dynamically allocated data buffers. The type c_buffer_t represents a data buffer. It contains the following members:
char *buf
| A pointer to the buffer.
|
size_t bufsz
| The size of the buffer.
|
size_t datalen
| The amount of data in the buffer.
|
void *hook
| A hook for associating arbitrary data.
|
The c_buffer_t type can be used as a convenient means of passing
sized buffers. The datalen member can be used to indicate how
much significant data is in a buffer. Arbitrary data can also be
associated with a buffer via the hook pointer.
| c_buffer_t * C_buffer_create (size_t bufsz) | Function |
| void C_buffer_destroy (c_buffer_t *buf) | Function |
|
These functions create and destroy arbitrarily-sized data
buffers.
|
| c_buffer_t * C_buffer_resize (c_buffer_t *buf, size_t newsz) | Function |
|
This function resizes the buffer buf to a new size of newsz.
bytes. The semantics are similar to that of The function returns buf on success. On failure (for example, if newsz is 0), it returns |
| void C_buffer_clear (c_buffer_t *buf) | Function |
|
This function zeroes the buffer buf. |
| C_buffer_data (buf) | Macro |
| C_buffer_size (buf) | Macro |
| C_buffer_datalen (buf) | Macro |
| C_buffer_hook (buf) | Macro |
|
These macros access the corresponding fields in the buffer structure buf. |
The following functions encode data to and decode data from a 7-bit
ASCII hexadecimal representation. Each byte of data is encoded as a
two-character long representation of the hexadecimal value of the byte;
e.g., the value 0x3F will be encoded as the characters
3F. Similarly, an ASCII string consisting of hexadecimal values
encoded in such a representation can be converted to a corresponding
array of bytes. Arbitrary data can be encoded or decoded using these
routines.
| C_hex_isdigit (c) | Macro |
|
This macro evaluates to |
| char C_hex_tonibble (int v) | Function |
| int C_hex_fromnibble (char c) | Function |
|
These routines convert nibbles (values in the range 0 to 15) to and from an ASCII hexadecimal representation.
|
| c_bool_t C_hex_tobyte (char *s, int v) | Function |
| int C_hex_frombyte (char * const s) | Function |
|
These routines convert bytes (values in the range 0 to 255) to and from an ASCII hexadecimal representation.
|
| c_bool_t C_hex_encode (char * const data, size_t len, char * s) | Function |
| c_bool_t C_hex_decode (const char *s, size_t len, char *data) | Function |
|
These routines convert arbitrary data to and from an ASCII hexadecimal representation.
The functions return |
The following functions are provided for the generation of random numbers.
| void C_random_seed (void) | Function |
|
In the single-threaded version of the library, this function seeds the
random number generator (via a call to |
| uint_t C_random (uint_t n) | Function |
|
This function returns a random unsigned integer in the range [0,
n-1] (via a call to |
The following functions parse and manipulate character arrays (strings).
| char * C_string_clean (char *s, char fillc) | Function |
|
This function replaces all non-printable characters in the string s with the fill character fillc. The function returns s on success, or |
| char * C_string_tolower (char *s) | Function |
|
This function converts all uppercase characters in the string s to lowercase. It returns s. |
| char * C_string_toupper (char *s) | Function |
|
This function converts all lowercase characters in the string s to uppercase. It returns s. |
| c_bool_t C_string_isnumeric (const char *s) | Function |
|
This function determines if the string s is composed strictly of numeric characters (0 - 9). The function returns |
| c_bool_t C_string_startswith (const char *s, const char *prefix) | Function |
|
This function determines if the string s begins with the string
prefix. It returns |
| c_bool_t C_string_endswith (const char *s, const char *suffix) | Function |
|
This function determines if the string s ends with the string
suffix. It returns |
| char * C_string_trim (char *s) | Function |
|
This function trims whitespace from both ends of the string s. That is, all whitespace up to the first non-whitespace character in the string and all whitespace after the last non-whitespace character in the string is discarded. The remaining text is moved so that it is flush with the beginning of the string. The function returns s. |
| char ** C_string_split (char *s, const char *sep, uint_t *len) | Function |
|
This function is a higher-level interface to the On success, the number of words parsed is stored at len if it is
non- |
| char * C_string_dup (const char *s) | Function |
|
This function is identical to the |
| char * C_string_dup1 (const char *s, char c) | Function |
|
This function duplicates the string s in memory and appends the
character c to the end of the duplicated
string. It returns a pointer to the new string on success, or
|
| char * C_string_chop (char *s, const char *termin) | Function |
|
This function searches the string s for the first occurrence of
any character in termin and replaces it with The function returns s. |
| c_bool_t C_string_copy (char *buf, size_t bufsz, const char *s) | Function |
|
This function performs a safe string copy. At most bufsz - 1
characters from s are copied to buf; the string buf is
unconditionally The function returns |
| c_bool_t C_string_va_copy (char *buf, size_t bufsz, ... /* , NULL */) | Function |
|
This is a variable argument list version of the The function returns |
| c_bool_t C_string_concat (char *buf, size_t bufsz, const char *s) | Function |
|
This function performs a safe string concatenation. It concatenates as
much of the string s onto the string buf as is possible
without overflowing buf. The resulting string will be at most
bufsz - 1 characters in length, and will be unconditionally
The function returns |
| c_bool_t C_string_va_concat (char *buf, size_t bufsz, ... /* , NULL */) | Function |
|
This is a variable argument list version of the The function returns |
| char ** C_string_sortvec (char **v, size_t len) | Function |
|
This function quicksorts the string vector v. It performs a call
to the The function returns v on success, or |
| char ** C_string_va_makevec (uint_t *len, ... /* , NULL */) | Function |
|
This function accepts a pointer to an integer, len, and a
The function returns the newly created vector on success, or |
| char ** C_string_valist2vec (const char *first, va_list vp, uint_t *slen) | Function |
|
This function converts a variable-argument list pointer vp into a
character string vector. The size of the vector is stored at slen
if it is non- |
| uint_t C_string_hash (const char *s, uint_t modulo) | Function |
|
This function hashes the string s to an unsigned integer in the
range [0, modulo - 1]. The particular algorithm used is one that
combines bitwise operators and addition on the characters in the
string. It was devised by Joe I. Williams. The function returns the hash
value on success, or |
| int C_string_compare (const void *s1, const void *s2) | Function |
|
This function is a wrapper for the This function is passed to the |
The following functions and macros are provided for the manipulation of dynamically allocated string buffers. A string buffer is much like a data buffer, except that it also includes a write pointer; this write pointer is advanced each time text is written to the buffer.
The string stored in a string buffer is always
NUL-terminated. Each of the functions below writes as much of the
requested text as possible to the string buffer, but will never attempt
to write past the end of the buffer.
The type c_strbuffer_t represents a string buffer.
| c_strbuffer_t * C_strbuffer_create (size_t bufsz) | Function |
| c_bool_t C_strbuffer_destroy (c_strbuffer_t *sb) | Function |
|
These functions create and destroy string buffers,
respectively.
|
| c_bool_t C_strbuffer_clear (c_strbuffer_t *sb) | Function |
|
This function clears the string buffer sb. The buffer is reset so
that it contains an empty string. The function returns |
| c_bool_t C_strbuffer_strcpy (c_strbuffer_t *sb, const char *s) | Function |
|
This function copies the string s into the string buffer sb,
replacing any text currently in the buffer. The function returns
|
| c_bool_t C_strbuffer_strcat (c_strbuffer_t *sb, const char *s) | Function |
|
This function concatenates the string s onto the text in the
string buffer sb. The function returns
|
| c_bool_t C_strbuffer_sprintf (c_strbuffer_t *sb, const char *format, ...) | Function |
|
This function appends a formatted string onto the text in the string
buffer sb; the behavior is identical to that of the
|
| c_bool_t C_strbuffer_putc (c_strbuffer_t *sb, char c) | Function |
|
This function appends the single character c onto the text in the
string buffer sb. The function returns |
| size_t C_strbuffer_size (c_strbuffer_t *sb) | Function |
|
This function (which is implemented as a macro) returns the size of the string buffer sb. |
| size_t C_strbuffer_strlen (c_strbuffer_t *sb) | Function |
|
This function returns the length of the string in the string buffer sb. |
| const char * C_strbuffer_string (c_strbuffer_t *sb) | Function |
|
This function (which is implemented as a macro) returns a pointer to the
beginning of the string in the string buffer sb. This string is
guaranteed to be |
The following functions parse and format time values.
| c_bool_t C_time_format (time_t t, char *buf, size_t bufsz, const char *format) | Function |
|
This function is a higher-level interface to the The function returns |
| time_t C_time_parse (const char *s, const char *format) | Function |
|
This function is a higher-level interface to the |
These functions provide CPU benchmarking through the use of timers that can be started and stopped. The type c_timer_t represents a CPU timer.
| c_timer_t * C_timer_create (void) | Function |
|
This function creates a new timer. It returns a pointer to the new timer. |
| void C_timer_destroy (c_timer_t *timer) | Function |
|
This function destroys the specified timer. |
| void C_timer_start (c_timer_t *timer) | Function |
|
This function resets and starts the specified timer. To start a
timer without resetting it, use the |
| void C_timer_stop (c_timer_t *timer) | Function |
|
This function stops the specified timer. A stopped timer can be
resumed with the |
| void C_timer_resume (c_timer_t *timer) | Function |
|
This function resumes the specified timer. Calling this function on a timer that is already running has no effect. |
| void C_timer_reset (c_timer_t *timer) | Function |
|
This function resets the specified timer. |
| float C_timer_user (c_timer_t *timer) | Function |
|
This function (which is implemented as a macro) returns the amount of user time (CPU time spent inside user space by the current thread or process) accumulated by the specified timer in hundredths of seconds. It is not meaningful to call this function with a timer that is not stopped. |
| float C_timer_system (c_timer_t *timer) | Function |
|
This function (which is implemented as a macro) returns the amount of system time (CPU time spent inside kernel space by the current thread or process) accumulated by the specified timer in hundredths of seconds. It is not meaningful to call this function with a timer that is not stopped. |
| long C_timer_elapsed (c_timer_t *timer) | Function |
|
This function (which is implemented as a macro) returns the amount of elapsed (real) time accumulated by the specified timer, in milliseconds. It is not meaningful to call this function with a timer that is not stopped. |
| time_t C_timer_created (c_timer_t *timer) | Function |
|
This function returns the system time at which the specified timer was created. It is implemented as a macro. |
| bool_t C_timer_isrunning (c_timer_t *timer) | Function |
|
This function returns |
The following functions operate on string vectors. The c_vector_t
type is an encapsulation type for NULL-terminated character
string vectors (arrays of pointers to character arrays). Vectors are
commonly used in the UNIX system to pass lists of strings; the
argv vector passed into a program's main() function is
probably the most well-known example. Some system calls, such as the
execv() family of functions, also accept vector arguments.
| c_vector_t * C_vector_start (uint_t resize_rate) | Function |
|
This function creates a new vector. The argument resize_rate is a value that specifies the rate at which memory for the vector backbone will be allocated. A value of 40, for example, specifies that memory is allocated for 40 char * pointers at a time. The smaller the value, the more frequently memory will be reallocated (thus decreasing performance), but the more efficient memory use will be. On success, the function returns a pointer to the new c_vector_t
structure, which can be used as a "handle" in subsequent calls to the
vector manipulation functions. On failure (for example, if
resize_rate is 0), it returns |
| c_bool_t C_vector_store (c_vector_t *v, const char *s) | Function |
|
This function "stores" a new string s in the vector v. If the vector is full, it is automatically resized. Note that the string s is not copied into the vector; only the pointer is stored in the vector backbone. Therefore it is the responsibility of the caller to ensure that the memory that s occupies is not volatile. The function returns |
| char ** C_vector_end (c_vector_t *v, uint_t *len) | Function |
|
This function signifies that no more strings will be stored in the
vector v. The vector is The function returns the vector as a pointer to an array of character
pointers on success, or |
| void C_vector_abort (c_vector_t *v) | Function |
|
This function aborts construction of the vector v, freeing all memory associated with the vector, including the c_vector_t structure and the vector backbone. |
| C_vector_free (v) | Macro |
|
This is a convenience macro. It is identical to |
Since the ultimate purpose of every program is to manipulate data, data
structures are an integral part of any piece of software. The following
functions provide implementations of various data structures, including
linked lists, hash tables, and others. All of the constants, macros, and
functions described in this chapter are defined in the header
cfl/data.h.
The types c_link_t and c_tag_t are used extensively by the linked-list and hashtable functions, but are documented for their possible use in other contexts.
The type c_link_t is a structure that contains the following members:
void *data
| Pointer to link data.
|
c_link_t *prev
| Pointer to previous link.
|
c_link_t *next
| Pointer to next link.
|
The type c_link_t can be used in any context that requires the
chaining of data elements. New links can be created via calls to
C_new().
| C_link_data (link) | Macro |
| C_link_prev (link) | Macro |
| C_link_next (link) | Macro |
|
These three macros access the corresponding fields in the link structure link. The first macro returns a void * pointer and the other two return pointers to c_link_t structures. |
The type c_id_t represents a non-negative integer ID. It is defined as an unsigned long long, a 64-bit unsigned integer.
The type c_datum_t represents a data element with an ID. It is a structure that contains the following members:
c_id_t key
| The key.
|
void * data
| Pointer to data.
|
The type c_datum_t can be used in any context that requires data
elements to be tagged with a numeric key. New data elements can be
created via calls to C_new().
| C_datum_key (datum) | Macro |
| C_datum_value (datum) | Macro |
|
These two macros access the corresponding fields in the datum structure datum. The first macro returns a c_id_t value and the second returns a void * pointer. |
The type c_tag_t is a structure that contains the following members:
char *key
| Pointer to key string.
|
void *data
| Pointer to data.
|
This type can be used in any context that requires the
labelling of a data element with a string. New tags can be created via
calls to C_new().
| C_tag_key (tag) | Macro |
| C_tag_data (tag) | Macro |
|
These two macros access the corresponding fields in the tag structure tag. The first macro returns a void * pointer and the second returns a char * pointer. |
The following functions operate on b-trees. A b-tree is a special type of balanced tree in which each node has at most n data elements and n + 1 children, for some even value of n. The value of n is the order of the b-tree, and is specified at the time the b-tree is created. B-trees are balanced and sorted, to provide for very efficient lookup, even in the case of a b-tree that contains tens of thousands of elements.
The type c_btree_t represents a b-tree.
| c_btree_t * C_btree_create (uint_t order) | Function |
| void C_btree_destroy (c_btree_t *tree) | Function |
|
These functions create and destroy b-trees.
|
| c_bool_t C_btree_set_destructor (c_btree_t *tree, void (*destructor)(void *)) | Function |
|
This function sets the destructor for the b-tree tree. The
function destructor will be called for each element that is
deleted from the b-tree as a result of a call to There is no default destructor; if no destructor is set for the b-tree, user data will not be automatically freed. The function returns |
| c_bool_t C_btree_store (c_btree_t *tree, c_id_t key, const void *data) | Function |
| void * C_btree_restore (c_btree_t *tree, c_id_t key) | Function |
|
These functions store data in and restore data from the b-tree tree.
|
| c_bool_t C_btree_delete (c_btree_t *tree, c_id_t key) | Function |
|
This function deletes the data element with the specified key from
the b-tree tree. It returns |
| c_bool_t C_btree_iterate (c_btree_t *tree, c_bool_t (*consumer)(void *elem, void *hook), void *hook) | Function |
|
This function is a generic iterator for b-trees. It performs a
breadth-first traversal of the b-tree tree. For each node in the
tree, it calls the user-supplied function consumer(), passing to
it a pointer to the element, and the pointer hook (which can be
used to pass around state information). The consumer() function is
expected to return |
| uint_t C_btree_order (c_btree_t *tree) | Function |
|
This function returns the order of the b-tree tree. It is implemented as a macro. |
The following functions operate on linked lists, which are constructed from c_link_t structures. A linked list is a chain of elements in which each element has a link to the element before it and the element after it. These functions do not store actual data; they merely organize pointers to data into a linked list structure. It is up to the caller to allocate and manage memory for the data.
A link pointer is associated with each linked list. The link pointer is like a bookmark in the list--it points to one of the links in the list, and can be moved around within the list. The link pointer simplifies the task of list traversal. This link pointer is stored inside the linked list data structure itself.
In some cases, data corruption may result if two threads simultaneously
call functions that adjust the link pointer in a list, or if a function
that is traversing a list calls another function that, as a side effect,
moves the link pointer of that list. In these cases, use the reentrant
forms of the functions below, which end in an _r suffix. Rather
than using the link pointer within the list itself, these functions use
a link pointer supplied by the caller.
Linked lists are useful in a very wide variety of contexts--too many, indeed, to list here.
The type c_linklist_t represents a linked list.
| c_linklist_t * C_linklist_create (void) | Function |
| void C_linklist_destroy (c_linklist_t *l) | Function |
|
These functions create and destroy linked lists.
|
| c_bool_t C_linklist_set_destructor (c_linklist_t *l, void (*destructor)(void *)) | Function |
|
This function sets the destructor for the linked list l. The
function destructor will be called for each element that is
deleted from the linked list as a result of a call to
There is no default destructor; if no destructor is set for the linked list, user data will not be automatically freed. The function returns |
| c_bool_t C_linklist_store (c_linklist_t *l, const void *data) | Function |
| void * C_linklist_restore (c_linklist_t *l) | Function |
|
These functions store data in and restore data from the linked list l.
|
| c_bool_t C_linklist_store_r (c_linklist_t *l, const void *data, c_link_t **p) | Function |
| void * C_linklist_restore_r (c_linklist_t *l, c_link_t **p) | Function |
|
These are reentrant versions of the functions |
| c_bool_t C_linklist_delete (c_linklist_t *l) | Function |
|
This function deletes the link at the linked list l's link
pointer. It returns |
| c_bool_t C_linklist_delete_r (c_linklist_t *l, c_link_t **p) | Function |
|
This is the reentrant version of the function |
| c_bool_t C_linklist_search (c_linklist_t *l, const void *data) | Function |
|
This function searches the linked list l from beginning to end for
a link whose data member is data. (Comparison is done by comparing
the data pointers only.) If the item is found, the link pointer is left
pointing to the matched link and the function returns
|
| c_bool_t C_linklist_search_r (c_linklist_t *l, c_link_t **p) | Function |
|
This is the reentrant version of the function |
| c_bool_t C_linklist_move (c_linklist_t *l, int where) | Function |
| c_bool_t C_linklist_move_head (c_linklist_t *l) | Function |
| c_bool_t C_linklist_move_tail (c_linklist_t *l) | Function |
| c_bool_t C_linklist_move_next (c_linklist_t *l) | Function |
| c_bool_t C_linklist_move_prev (c_linklist_t *l) | Function |
|
These functions move the linked list l's link pointer. The link pointer affects where data will be stored in the list and whence data will be restored from the list.
The link pointer may become The four convenience functions The following example illustrates a c_linklist_t *list;
void *data;
for(C_linklist_move_head(list);
(data = C_linklist_restore(list)) != NULL;
C_linklist_move_next(list))
{
printf("Data: %s\n", (char *)data);
}
|
| c_bool_t C_linklist_move_r (c_linklist_t *l, int where, c_link_t **p) | Function |
| c_bool_t C_linklist_move_head_r (c_linklist_t *l, c_link_t **p) | Function |
| c_bool_t C_linklist_move_tail_r (c_linklist_t *l, c_link_t **p) | Function |
| c_bool_t C_linklist_move_next_r (c_linklist_t *l, c_link_t **p) | Function |
| c_bool_t C_linklist_move_prev_r (c_linklist_t *l, c_link_t **p) | Function |
|
These are the reentrant versions of the |
| c_bool_t C_linklist_ishead (c_linklist_t *l) | Function |
| c_bool_t C_linklist_istail (c_linklist_t *l) | Function |
|
These functions (which are implemented as macros) test the linked list
l's link pointer to determine if it is at the head or tail of the
list. They return |
| c_bool_t C_linklist_ishead_r (c_linklist_t *l, c_link_t **p) | Function |
| c_bool_t C_linklist_istail_r (c_linklist_t *l, c_link_t **p) | Function |
|
These are the reentrant versions of the functions
|
| c_link_t * C_linklist_head (c_linklist_t *l) | Function |
| c_link_t * C_linklist_tail (c_linklist_t *l) | Function |
|
These functions (which are implemented as macros) return the head and
tail link, respectively, of the linked list l. A return value of
|
| size_t C_linklist_length (c_linklist_t *l) | Function |
|
This function (which is implemented as a macro) returns the length of the linked list l, that is, the number of links in the list. |
A queue is a FIFO (first in, first out) data structure with a beginning and an end. Items are enqueued onto the end of the list and dequeued from the beginning. These functions do not store actual data; they merely organize pointers to data into a linked list structure. It is up to the caller to allocate and manage memory for the data.
Queues are useful in producer/consumer contexts, where data items must be processed in the order that they are received, and where new items may potentially arrive more quickly than they can be processed.
The type c_queue_t represents a queue.
| c_queue_t * C_queue_create (void) | Function |
| void C_queue_destroy (c_queue_t *q) | Function |
|
These functions create and destroy queues.
|
| c_bool_t C_queue_set_destructor (c_queue_t *q, void (*destructor)(void *)) | Function |
|
This function sets the destructor for the queue q. The function
destructor will be called for each element that is deleted from
the queue as a result of a call to There is no default destructor; if no destructor is set for the queue, user data will not be automatically freed. The function returns |
| c_bool_t C_queue_enqueue (c_queue_t *q, const void *data) | Function |
| void * C_queue_dequeue (c_queue_t *q) | Function |
|
These functions enqueue data onto and dequeue data from the queue
q.
|
| size_t C_queue_length (c_queue_t *q) | Function |
|
This function (which is implemented as a macro) returns the length of the queue q, that is, the number of items in the queue. |
The following functions operate on stacks. A stack is a LIFO (last in, first out) data structure with a top and a bottom. Items are pushed onto or popped off the top of the stack. These functions do not store actual data; they merely organize pointers to data into a stack structure. It is up to the caller to allocate and manage memory for the data.
Stacks are useful in a variety of contexts, most typically in parsers and interpreters.
The type c_stack_t represents a stack.
| c_stack_t * C_stack_create (void) | Function |
| void C_stack_destroy (c_stack_t *s) | Function |
|
These functions create and destroy stacks.
|
| c_bool_t C_stack_set_destructor (c_stack_t *s, void (*destructor)(void *)) | Function |
|
This function sets the destructor for the stack s. The function
destructor will be called for each element that is deleted from the
stack as a result of a call to There is no default destructor; if no destructor is set for the stack, user data will not be automatically freed. The function returns |
| c_bool_t C_stack_push (c_stack_t *s, const void *data) | Function |
| void * C_stack_pop (c_stack_t *s) | Function |
|
These functions push data onto and pop data off the stack s.
|
| void * C_stack_peek (c_stack_t *s) | Function |
|
This function returns the topmost item on the stack s, without
removing the item from the stack as does |
| size_t C_stack_depth (c_stack_t *s) | Function |
|
This function (which is implemented as a macro) returns the depth of the stack s, that is, the number of items on the stack. |
The following functions operate on hashtables. A hashtable is implemented as an array of n linked lists of tags, where n is the number of buckets in the hashtable. These functions do not store actual data; they merely organize pointers to data into a hashtable structure. It is up to the user to allocate and manage memory for the data.
Hashtables are typically used as data dictionaries; a data item is tagged with a unique string and then stored in the hashtable. This unique string, or key, is subsequently used to retrieve that data item.
Items are stored in a hashtable as follows. First, a hashing algorithm is used to convert the item's key to an integer between 0 and n - 1, where n is the number of buckets in the hashtable. The item is then placed in the appropriate bucket. Each bucket is implemented as a linked list of items.
An item lookup consists of hashing the desired key to an integer, selecting the appropriate bucket, and then doing a linear search through the items in that bucket, comparing keys until the desired item is found.
Item lookup in a hashtable is faster than in a linked list or other similar data structure. The maximum number of comparisons required to find an item in a hashtable is equal to the number of items in the longest linked list in the hashtable. Increasing the number of buckets will decrease the number of collisions in the hashtable; that is, the likelihood that any two keys will hash to the same value (and fall into the same bucket) will be reduced. This will result in less items in each bucket and hence shorter linked lists to search through.
The type c_hashtable_t represents a hashtable.
| c_hashtable_t * C_hashtable_create (uint_t buckets) | Function |
| void C_hashtable_destroy (c_hashtable_t *h) | Function |
|
These functions create and destroy hashtables, respectively.
|
| c_bool_t C_hashtable_set_destructor (c_hashtable_t *h, void (*destructor)(void *)) | Function |
|
This function sets the destructor for the hashtable h. The
function destructor will be called for each element that is
deleted from the hashtable as a result of a call to
There is no default destructor; if no destructor is set for the hashtable, user data will not be automatically freed. The function returns |
| c_bool_t C_hashtable_store (c_hashtable_t *h, const char *key, const void *data) | Function |
| void * C_hashtable_restore (c_hashtable_t *h, const char *key) | Function |
|
These functions store data in and restore data from the hashtable h.
|
| c_bool_t C_hashtable_delete (c_hashtable_t *h, const char *key) | Function |
|
This function searches for a tag whose key matches key in the same
manner as The function returns |
| char ** C_hashtable_keys (c_hashtable_t *h, uint_t *len) | Function |
|
This function returns all of the keys in the hashtable h as a
string vector. If len is not |
| c_bool_t C_hashtable_set_hashfunc (uint_t (*func)(const char *s, uint_t modulo)) | Function |
|
This function allows the user to specify an alternate hashing function
func. The default hashing function is
|
| size_t C_hashtable_size (c_hashtable_t *h) | Function |
|
This function (which is implemented as a macro) returns the size of the hashtable h; that is, the number of elements stored in the table. |
The following functions manipulate dynamic arrays. A dynamic array is like a regular array: it is a contiguous segment of memory that stores a series of equally-sized elements. Unlike with regular arrays, the user does not have control over where in the array an element will be stored. A new element is stored in the first free slot available, and the index of this slot is returned to the caller. This index is used to restore the element from the array. Memory management for dynamic arrays is done automatically; as an array begins to fill up, it is resized to accommodate more elements.
As elements are deleted from the array, the array does not shrink
because to periodically defragment an array while maintaining the
relative order of elements within it is inefficient. Instead, a deleted
element is marked as an empty slot in the array, and is filled by a
subsequent store operation. If an array becomes heavily fragmented, it
may be defragmented via a call to C_darray_defragment().
Dynamic arrays have the interesting property that they can be quickly written to and read from a file. Since no pointers are used, the data in the array is easily relocatable.
Dynamic arrays are intended for use in applications which generate a database that grows steadily in size over time--a database in which deletions are much less frequent than inserts.
The type c_darray_t represents a dynamic array.
| c_darray_t * C_darray_create (uint_t resize_rate, size_t elemsz) | Function |
| void C_darray_destroy (c_darray_t *a) | Function |
|
These functions create and destroy dynamic arrays.
|
| void * C_darray_store (c_darray_t *a, const void *data, uint_t *index) | Function |
| void * C_darray_restore (c_darray_t *a, uint_t index) | Function |
|
These functions store data in and restore data from the dynamic array a.
|
| c_bool_t C_darray_delete (c_darray_t *a, uint_t index) | Function |
|
This function marks as "empty" the element whose index is index
in the array a, effectively deleting it from the array. Subsequent
calls to |
| c_darray_t * C_darray_load (const char *path) | Function |
| c_bool_t C_darray_save (c_darray_t *a, const char *path) | Function |
|
These functions read dynamic arrays from and write dynamic arrays to the file specified by path.
The format of the file is binary; it consists of an image of the c_darray_t structure, followed by a free-list bitstream, followed by a contiguous block of elements. A dynamic array file should not be modified directly. |
| c_darray_t * C_darray_defragment (c_darray_t *a) | Function |
|
This function defragments the dynamic array a while preserving the
relative order of the elements within the array. This is done by
creating a new dynamic array, copying all non-deleted elements from
a to the new array, and then destroying the old array. The
function returns a pointer to the new array on success. On failure,
|
| c_bool_t C_darray_iterate (c_darray_t *a, c_bool_t (*iter)(void *elem, uint_t index, void *hook), uint_t index, void *hook) | Function |
|
This function is a generic iterator for dynamic arrays. For each
non-deleted element in the array a beginning at the index
index, it calls the user-supplied function iter(), passing
to it a pointer to the beginning of the element, the |
| size_t C_darray_size (c_darray_t *a) | Function |
|
This function (which is implemented as a macro) returns the size of the dynamic array a, that is, the number of non-deleted elements in the array. |
Dynamic strings inherit many of the semantics of random-access files. A dynamic string is a segment of memory which can be written to and read from as if it were a normal ASCII file. The string is resized automatically when data is written past the end of the string or when the string is truncated to a specific length. A dynamic string has a seek pointer that can be moved back and forth, much like the seek pointer in a file. Like dynamic arrays, dynamic strings can be written to and read from disk.
The type c_dstring_t represents a dynamic string.
| c_dstring_t * C_dstring_create (uint_t blocksz) | Function |
| char * C_dstring_destroy (c_dstring_t *d) | Function |
|
These functions create and destroy dynamic strings.
|
| c_bool_t C_dstring_putc (c_dstring_t *d, char c) | Function |
| c_bool_t C_dstring_puts (c_dstring_t *d, const char *s) | Function |
| c_bool_t C_dstring_puts_len (c_dstring_t *d, const char *s, size_t len) | Function |
|
These functions write data to the dynamic string d at the current
location of the string's seek pointer. The functions return |
| char C_dstring_getc (c_dstring_t *d) | Function |
| char * C_dstring_gets (c_dstring_t *d, char *s, size_t len, char termin) | Function |
|
These functions read data from the dynamic string d starting at the current location of the seek pointer.
|
| c_bool_t C_dstring_seek (c_dstring_t *d, unsigned long where, int whence) | Function |
| c_bool_t C_dstring_ungetc (c_dstring_t *d) | Function |
| c_bool_t C_dstring_rewind (c_dstring_t *d) | Function |
| c_bool_t C_dstring_append (c_dstring_t *d) | Function |
|
|
| c_bool_t C_dstring_trunc (c_dstring_t *d, off_t length) | Function |
|
This function truncates the dynamic string d to a length of size characters. The new size must be less than or equal to the current size; a dynamic string cannot be lengthened using this function. The function also moves the seek pointer to the end of the dynamic string after the truncation is performed. The function returns |
| c_dstring_t * C_dstring_load (const char *path, uint_t blocksz) | Function |
| c_bool_t C_dstring_save (c_dstring_t *d, const char *path) | Function |
|
These functions read dynamic strings from and write dynamic strings to the file specified by path.
The format of a dynamic string file is plain ASCII. It is simply a file containing the string. It is safe to modify dynamic string files directly. This implies that plain ASCII files can be created with a text editor and then read in as dynamic strings. |
| off_t C_dstring_length (c_dstring_t *d) | Function |
|
This function returns the length (in characters) of the dynamic string d. It is implemented as a macro. |
This chapter describes a simple, minimal API for manipulating XML
data. These routines rely on the expat XML Parser Toolkit written by
James Clark. See <http://sourceforge.net/projects/expat> for more
information. Note that applications that use these functions must also
link with the expat library.
All of the functions described in this chapter are defined in the header
cfl/xml.h.
The type c_xml_document_t represents an XML document, and the type c_xml_element_t represents an XML element.
| c_xml_document_t * C_xml_document_create (const char *encoding) | Function |
| c_bool_t C_xml_document_destroy (c_xml_document_t *doc) | Function |
|
These functions create and destroy XML documents.
|
| c_xml_element_t * C_xml_element_create (const char *name) | Function |
| c_bool_t C_xml_element_destroy (c_xml_element_t *elem) | Function |
| c_bool_t C_xml_element_destroy_recursive (c_xml_element_t *elem) | Function |
These methods create and destroy XML elements.
C_xml_element_create() creates a new element with the specified
name. It returns a pointer to the newly created
c_xml_element_t structure.
C_xml_element_destroy() destroys the specified element
elem, deallocating all memory associated with that
element. C_xml_element_destroy_recursive() is similar, but it
additionally recursively destroys all child elements of
elem. These functions return TRUE on success or
FALSE on failure (for example, if elem is NULL).
| c_bool_t C_xml_document_set_root (c_xml_document_t *doc, c_xml_element_t *root) | Function |
| c_xml_element_t * C_xml_document_get_root (c_xml_document_t *doc) | Function |
|
These functions set and get the root element of the XML document doc.
If the document had an existing root element, the tree of elements
rooted at that root element becomes orphaned; therefore, it is necessary
in this case to call
|
| c_bool_t C_xml_element_set_content (c_xml_element_t *elem, const char *content) | Function |
| char * C_xml_element_get_content (c_xml_element_t *elem) | Function |
|
These functions set and get the content for the XML element elem.
|
| c_bool_t C_xml_element_set_param (c_xml_element_t *elem, const char *param, const char *value) | Function |
| char * C_xml_element_get_param (c_xml_element_t *elem, const char *param) | Function |
|
These functions set and get parameters for the XML element elem.
|
| c_bool_t C_xml_element_delete_param (c_xml_element_t *elem, const char *param) | Function |
| c_bool_t C_xml_element_delete_params (c_xml_element_t *elem) | Function |
|
These functions delete parameters from the XML element elem.
These functions return |
| c_xml_element_t ** C_xml_element_get_children (c_xml_element_t *parent) | Function |
| c_xml_element_t ** C_xml_element_get_children_named (c_xml_element_t *parent, const char *name) | Function |
|
These functions return a list of child elements of the specified XML element parent.
On success, the functions return a dynamically allocated, possibly
empty, |
| c_xml_element_t * C_xml_element_get_first_child (c_xml_element_t *parent) | Function |
|
This function returns the first child element of the element
parent, or |
| c_bool_t C_xml_element_add_child (c_xml_element_t *parent, c_xml_element_t *elem) | Function |
|
This function adds a new child element to the XML element
parent. Child elements can only be added to a parent element that
does not have any content. An element cannot be added as a child of
itself. The function returns |
| c_bool_t C_xml_element_remove_child (c_xml_element_t *parent, c_xml_element_t *elem) | Function |
|
This function removes the specified element elem from the parent
element parent. The element tree rooted at elem is
destroyed. The function returns |
| c_bool_t C_xml_element_remove_children (c_xml_element_t *parent) | Function |
| c_bool_t C_xml_element_remove_children_named (c_xml_element_t *parent, const char *name) | Function |
|
These functions remove multiple child elements from the parent element parent. The element tree rooted at each removed child element is destroyed.
These functions return |
| c_bool_t C_xml_document_read (c_xml_document_t *doc, FILE *fp) | Function |
| c_bool_t C_xml_document_write (c_xml_document_t *doc, FILE *fp) | Function |
|
These functions read and write XML documents to and from files.
|
This chapter describes an implementation of a real-time scheduler whose functionality is very similiar to that of the UNIX cron daemon.
The scheduler allows events to be scheduled in real time. As with cron, events can be scheduled for specific dates and times. An event can be scheduled to fire only once or repetitively depending on a date and time specification.
Date and time specifications are made in the same manner as in crontab files. A specification consists of five fields separated by whitespace or colons (:). These fields specify integer patterns for matching minute, hour, day of month, month of year, and day of week, in that order. Each of the patterns may be either an asterisk (*), which denotes a wildcard that matches all acceptable values, or a list of elements separated by commas (,), where each element is either a single integer value or a range of values denoted by a pair of integers separated by a dash (-).
Values for minute must range from 0-59, for hour from 0-23, for day of month from 1-31, for month of year from 1-12, and for day of week from 0-6 with 0 denoting Sunday.
Following are some example specifications and their meanings:
0 0 5,15 * 1-5
Midnight on the 5th and 15th of every month, but never on a Saturday or Sunday.
15 3 * * 0-4,6
3:15 am every day except Fridays.
0 * * 1 *
Every hour, on the hour, in January.
When a scheduled event fires, the user-supplied handler function is invoked; it receives a pointer to the event structure as an argument. This callback mechanism allows arbitrary code to be executed at specific dates and times.
All of the functions described in this chapter are defined in the header
cfl/sched.h.
The following functions control the event scheduler. Due to idiosyncrasies inherent in UNIX signal handling, the scheduler can only be used on a per-process basis, and hence these functions are not threadsafe. When used in a multithreaded application, calls to these functions should be protected by a mutex lock.
| c_bool_t C_sched_init (void) | Function |
| c_bool_t C_sched_shutdown (void) | Function |
|
These functions initialize and shut down the real-time scheduler.
|
| void C_sched_poll (void) | Function |
|
With the single-threaded version of the library, a program must periodically poll the scheduler to allow events to be fired at their scheduled times. This function is provided for that purpose. It enumerates all of the registered events and fires any that are due at the time of the call. Since the scheduling granularity is one minute, this function must be called exactly once per minute to ensure proper scheduler behavior. In the multi-threaded version of the library, the scheduler runs in a dedicated thread, hence this function is a no-op and should not be used. |
The following functions manipulate scheduler events, which are represented by the type c_schedevt_t.
| c_schedevt_t * C_sched_event_create (const char *timespec, c_bool_t once, void *hook, void (*handler)(c_schedevt_t *, time_t), void (*destructor)(c_schedevt_t *), uint_t id) | Function |
| c_bool_t C_sched_event_destroy (c_schedevt_t *e) | Function |
|
These functions create and destroy scheduler
events. The function returns a pointer to the newly created event structure on
success, or
|
| c_bool_t C_sched_event_activate (c_schedevt_t *e) | Function |
| c_bool_t C_sched_event_deactivate (c_schedevt_t *e) | Function |
|
These functions activate and deactive the scheduler event e.
|
| c_schedevt_t * C_sched_event_find (uint_t id) | Function |
|
This function searches for a scheduler event with ID id in the
scheduler's event list. It returns a pointer to the matching event
structure on success, or |
| void * C_sched_event_data (c_schedevt_t *e) | Function |
|
This function (which is implemented as a macro) returns the user-data for the scheduler event e. |
| uint_t C_sched_event_id (c_schedevt_t *e) | Function |
|
This function (which is implemented as a macro) returns the ID for the scheduler event e. |
"IPC" refers to Inter-Process Communications, a set of mechanisms provided by UNIX to facilitate collaboration between processes. Shared memory, semaphores, signals, and pseudoterminals are some of the most commonly used IPC mechanisms.
All of the constants, macros, and functions described in this chapter
are defined in the header cfl/ipc.h.
The following functions provide a means of passing file descriptors between unrelated processes. File descriptors (and other types of descriptors, depending on the system) may be passed over stream pipes. A "stream pipe" refers to a STREAMS-based full duplex pipe or, more commonly, a UNIX-domain socket.
| c_bool_t C_fd_send (int sd, int fd) | Function |
|
This function sends the file descriptor fd over the stream pipe
sd. It returns |
| c_bool_t C_fd_recv (int sd, int *fd) | Function |
|
This function receives a file descriptor over the stream pipe sd,
storing the received descriptor at fd. It returns |
The following functions provide a simple API to POSIX semaphores, which are counting semaphores. A counting semaphore is a simple synchronization mechanism that can be used to coordinate the actions of multiple processes or threads. A process or thread waits for a semaphore, acquires the semaphore, performs some task, and then posts the semaphore, thereby releasing it.
The initial value of the semaphore, which is a positive integer, specifies how many instances of a resource are being guarded. For example, if the initial value is 2, then at most two threads or processes can lock the semaphore at a time. A semaphore created with an initial value of 1 is called a binary semaphore and is essentially the same as a mutex--it can be used to guard a single instance of a resource or to protect critical sections of code.
The type c_sem_t represents a counting semaphore.
| c_sem_t * C_sem_create (const char *name, mode_t mode, uint_t value) | Function |
| void C_sem_destroy (c_sem_t *sem) | Function |
|
These functions create and destroy semaphores. If the underlying POSIX semaphore object with the specified name did not already exist, it is created. This new object is created with world, group, and owner access permission as specified by the mode parameter. The function returns a pointer to the new semaphore on success, or
|
| c_bool_t C_sem_wait (c_sem_t *sem) | Function |
| c_bool_t C_sem_trywait (c_sem_t *sem) | Function |
|
These functions wait on the semaphore sem. Both functions return |
| c_bool_t C_sem_post (c_sem_t *sem) | Function |
|
This function posts the semaphore sem. It returns |
| const char * C_sem_name (c_sem_t *sem) | Function |
|
This function (which is implemented as a macro) returns the symbolic name of the semaphore sem. |
| int C_sem_value (c_sem_t *sem) | Function |
|
This function returns the "current" value of the semaphore sem. The returned value may or may not be the actual semaphore value at the time that the function returns; it is only guaranteed to have been current at some point during the call. On success, the function returns the current value of the semaphore. On failure, it returns -1. |
| uint_t C_sem_initial_value (c_sem_t *sem) | Function |
|
This function (which is implemented as a macro) returns the initial value with which the semaphore sem was created. |
The following functions provide a simple API to POSIX shared memory objects. A shared memory segment is simply an arbitrary block of memory that is mapped into more than one process's address space; data written to the shared memory by one process is immediately visible to all other processes that have mapped that segment. It is the fastest and most flexible form of IPC.
The type c_shmem_t represents a shared memory segment.
| c_shmem_t * C_shmem_create (const char *name, size_t size, mode_t mode) | Function |
|
This function creates a new shared memory segment with the specified
symbolic name and size in bytes, size. The POSIX standard
specifies that name must begin with a slash character (` If the underlying POSIX shared memory object with the specified name did not already exist, it is created, and the memory in the segment is zeroed. The new object is created with world, group, and owner access permission as specified by the mode parameter. The function returns a pointer to the new c_shmem_t structure on
success, or |
| void C_shmem_destroy (c_shmem_t *mem) | Function |
|
This function destroys the shared memory segment mem. The memory is unmapped from the calling process's address space. If no other processes have this segment mapped, the underlying POSIX shared memory object is destroyed. Finally, the mem structure itself is deallocated. |
| void * C_shmem_base (c_shmem_t *mem) | Function |
|
This function (which is implemented as a macro) returns a pointer to the base of the shared memory segment mem. |
| size_t C_shmem_size (c_shmem_t *mem) | Function |
|
This function (which is implemented as a macro) returns the size, in bytes, of the shared memory segment mem. |
| c_bool_t C_shmem_resize (c_shmem_t *mem, size_t size) | Function |
|
This function resizes the shared memory segment mem to a new size
of size. The requested size will be rounded up to the nearest
system page size as reported by The function returns |
| const char * C_shmem_name (c_shmem_t *mem) | Function |
|
This function (which is implemented as a macro) returns the symbolic name of the shared memory segment mem. |
The following function converts signal IDs to names.
| const char * C_signal_name (int sig) | Function |
|
This function returns a string representation of the signal specified by
sig, or |
The following functions operate on terminals and pseudoterminals. Interactive programs such as mail readers and editors run on terminals, but sometimes it is useful to control an interactive program with another program. An IPC mechanism known as a pseudoterminal can be used for this purpose. A pseudoterminal appears to be a normal terminal to the slave process, and as a FIFO pipe to the master process. The master process feeds input to and receives input from the slave process through the pipe, and the slave process reads from and writes to its terminal as it would normally.
These functions are not reentrant.
The following functions operate on UNIX file descriptors which are assumed to refer to terminal (tty) lines.
| c_bool_t C_tty_raw (int fd) | Function |
|
This function puts the terminal associated with the file descriptor
fd into raw mode. Once in this mode, the terminal driver does
not do any buffering or processing of input or output. The current
terminal settings for fd are stored in a static buffer inside the
library, and may be restored via a call to The function returns
|
| c_bool_t C_tty_unraw (int fd) | Function |
|
This function undoes the changes to the attributes of the terminal
associated with the file descriptor fd that resulted from the
latest call to The function returns
|
| c_bool_t C_tty_store (int fd) | Function |
|
This function stores the current attributes of the terminal associated
with the file descriptor fd in a static buffer inside the
library. These attributes can later be restored via a call to
The function returns
|
| c_bool_t C_tty_restore (int fd) | Function |
|
This function restores the terminal attributes saved with the latest
call to The function returns
|
| c_bool_t C_tty_sane (int fd) | Function |
|
This function sets the attributes on the terminal associated with the
file descriptor fd to sane (default) values. Specifically, the
input flag word is set to The function returns
|
The following functions provide an interface to System V or BSD pseudoterminals. A pseudoterminal consists of a master and a slave; the child process reads from and writes to the slave device as if it were a "real" terminal, and the parent process reads from and writes to the child through the master device.
The type c_pty_t represents a pseudoterminal device pair.
| c_pty_t * C_pty_create (void) | Function |
|
This function allocates a pseudoterminal from the system. On success, it
returns a pointer to the new c_pty_t structure. The functions
|
| c_bool_t C_pty_destroy (c_pty_t *pty) | Function |
|
This function closes the master and slave devices for the pseudoterminal
pty and deallocates the data structure at pty. The function
returns |
| int C_pty_master_fd (c_pty_t *pty) | Function |
| int C_pty_slave_fd (c_pty_t *pty) | Function |
|
These functions (which are implemented as macros) return the file descriptors for the master and slave device, respectively, of the pseudoterminal pty. |
| const char * C_pty_slave_name (c_pty_t *pty) | Function |
|
This function (which is implemented as a macro) returns the path of the device file for the slave device associated with the pseudoterminal pty. |
This chapter describes a high-level, abstracted interface to the Berkeley socket IPC mechanism. A socket is similar to a pipe, but the two endpoints of a socket may exist on different hosts. This means that sockets can be used to transfer data between two networked machines, whether they are both on the same local area network, or connected to the Internet from opposite sides of the globe.
Sockets are generally employed as a communications medium in client/server systems. Generally, a server process creates a master or listening socket, binds the socket to a specific port number, and listens for connections on that socket. Clients that know the IP address or DNS name of the host and the port number on which the server is listening can connect to that server. Once a connection is established, data can be easily exchanged between the server and the client.
In the traditional model, a server typically forks a subprocess to handle each incoming connection; otherwise the server would only be able to service one client at a time. The subprocess communicates with the client and exits when the connection is closed. Meanwhile, the main server process continues to listen for new connections.
Since all of the networking functions in this library are reentrant, they can be used to write a multithreaded server, in which one thread is tasked with listening for new connections and spawning (or assigning) a worker thread for each incoming connection.
As anyone who has written network code in UNIX knows, the socket functions provide a very low-level and cumbersome networking API. The complexity of the API is inherent in its flexibility, but in general only a subset of the available functions and flags are used. Furthermore, networking code is very similar across many servers. This library greatly simplifies the development of networked applications by hiding most of this complexity.
All of the constants, macros, and functions described in this chapter
are defined in the header cfl/net.h.
Most of the functions described below return boolean or integer
values. On failure, they return FALSE or -1, respectively, and
set the global variable c_errno to reflect the type of error. The
error codes are defined in the header file cfl/cerrno.h. Some of the
error codes indicate that a system call or socket library function
failed; in this case, the errno variable can be examined to get
the system-defined error code.
Note that in the threaded version of the library, c_errno is
defined as a macro that returns a thread-specific error value.
The following functions can be used to obtain information about network
services (namely, those listed in the /etc/services file), and to
resolve IP addresses into DNS names.
| in_port_t C_net_get_svcport (const char *name, uint_t *type) | Function |
|
This function looks up the port number for the service named
name. The value at type specifies which type of service to
search for. It can be one of On success, the function returns the port number of the named
service. On failure, it returns
|
| c_bool_t C_net_get_svcname (in_port_t port, uint_t *type, char *buf, size_t bufsz) | Function |
|
This function is the inverse of The function returns
|
| c_bool_t C_net_resolve (const char *ipaddr, char *buf, size_t bufsz) | Function |
|
This function attempts to resolve the dot-separated IP address at
ipaddr into a valid DNS name. Up to bufsz - 1 bytes of the
resolved name are written at buf. The buffer is unconditionally
The function returns
|
| c_bool_t C_net_resolve_local (char *addr, char *ipaddr, size_t bufsz, in_addr_t *ip) | Function |
|
This function obtains the address of the local host in one or more
formats. If addr is not The function returns
|
The following routines provide control functions, such as connecting and disconnecting sockets, setting socket options, and obtaining socket addresses.
The type c_socket_t represents a socket.
| c_socket_t * C_socket_create (int type) | Function |
| c_bool_t C_socket_destroy (c_socket_t *s) | Function |
|
These two functions create and destroy sockets.
|
| c_bool_t C_socket_create_s (c_socket_t *s, int type) | Function |
| c_bool_t C_socket_destroy_s (c_socket_t *s) | Function |
|
These functions are static variants of
|
| c_bool_t C_socket_listen (c_socket_t *s, in_port_t port) | Function |
|
This function binds the socket s to a local address and, if the
socket is a TCP socket, initiates listening on the specified TCP
port. It is typically used by a server process to prepare for
incoming connection requests which are subsequently accepted using
|
| c_socket_t * C_socket_accept (c_socket_t *s) | Function |
|
This function accepts a pending connection request on the socket
s, returning a new socket which may be used to communicate with
the client process. If s is in a non-blocking state and no
connection is pending, the function returns immediately with a value of
The function returns the newly created socket on success. On failure, it
returns
|
| c_bool_t C_socket_accept_s (c_socket_t *s, c_socket_t *ms) | Function |
|
This function is a static variant of
|
| c_bool_t C_socket_connect (c_socket_t *s, const char *host, in_port_t port) | Function |
|
This function connects the socket s to a port on a remote host. The argument host is the address of the remote host; it may be either a dot-separated IP address or a valid DNS name. The argument port specifies which TCP or UDP port to connect to on the remote host. This function is normally used by a client process that wishes to connect to a server. TCP sockets must be connected before they can be used to transfer data, while UDP sockets may be used in either a connected or unconnected state. Connecting a UDP socket binds it to a specific address, which means that the destination address need not be specified for each datagram sent. Connecting a UDP socket also allows higher-level I/O routines in this library to be used with the socket. The function returns
|
| c_bool_t C_socket_shutdown (c_socket_t *s, uint_t how) | Function |
|
This function shuts down reading, writing, or reading and writing on the
socket s. The socket must be in a connected state in order to be
shut down, and it cannot be destroyed until it is in a shut down
state. The argument how specifies how the socket is to be shut
down: The function returns
|
| c_bool_t C_socket_get_peeraddr (c_socket_t *s, char *buf, size_t bufsz) | Function |
|
This function obtains the address of the peer of the socket s,
that is, the name of the host on the remote end of the connection. At
most bufsz - 1 bytes of the host name are written to buf,
and the buffer is unconditionally The function returns
|
| in_addr_t C_socket_get_ipaddr (c_socket_t *s) | Function |
| in_addr_t C_socket_get_peeripaddr (c_socket_t *s) | Function |
|
These functions obtain the packed IP address of each end of the socket
s. These functions are implemented as macros. |
| c_bool_t C_socket_fopen (c_socket_t *s, int buffering) | Function |
|
This function opens a stream for the socket s that can be used
with the stdio library functions. The pointer to this stream may be
obtained with the The function returns
|
| c_bool_t C_socket_fclose (c_socket_t *s) | Function |
|
This function closes the stdio stream associated with the socket
s, if one has been opened via a call to The function returns
|
| c_socket_t * C_socket_reopen (int sd) | Function |
|
This function creates a socket structure for the socket whose descriptor is sd. On success, the function returns the newly created c_socket_t
structure. On failure, it returns
|
| c_bool_t C_socket_reopen_s (c_socket_t *s, int sd) | Function |
|
This function is a static variant of
|
| c_bool_t C_socket_set_option (c_socket_t *s, uint_t option, c_bool_t flag, uint_t value) | Function |
|
This function sets the option option on the socket s. Valid options are as follows:
This function returns
|
| c_bool_t C_socket_get_option (c_socket_t *s, uint_t option, c_bool_t *flag, uint_t *value) | Function |
|
This function gets the current settings for the option option on
the socket s. The arguments flag and value are used to
store the settings for the given option; which of these arguments is
used depends on the type of option. See This function returns
|
| c_bool_t C_socket_block (c_socket_t *s) | Function |
| c_bool_t C_socket_unblock (c_socket_t *s) | Function |
| c_bool_t C_socket_isblocked (c_socket_t *s) | Function |
|
These convenience functions change and test the blocking state on the
socket s; they are implemented as macros which evaluate to the
appropriate calls to
|
| int C_socket_get_fd (c_socket_t *s) | Function |
| FILE * C_socket_get_fp (c_socket_t *s) | Function |
|
These functions (which are implemented as macros) return the socket
descriptor and file stream pointer, respectively, for the socket
s. |
| int C_socket_get_type (c_socket_t *s) | Function |
|
This function returns the type of the socket s, either
|
| void C_socket_set_timeout (c_socket_t *s, int sec) | Function |
| int C_socket_get_timeout (c_socket_t *s) | Function |
|
These functions set and get the I/O timeout for the socket s. They are implemented as macros.
|
| void C_socket_set_userdata (c_socket_t *s, void *data) | Function |
| void * C_socket_get_userdata (socket_t *s) | Function |
|
These functions set and get the "user data" field of the socket s. This field is simply a pointer which can be used to attach arbitrary data to a socket. The functions are implemented as macros. |
These functions provide UDP multicast functionality. Multicast addresses range from 224.0.0.0 through 239.255.255.255. A UDP datagram sent to a multicast address is delivered to all hosts on the network which have joined the multicast group specified by that address. Multicasting is described in detail in chapter 19 of UNIX Network Programming Volume 1 by W. Richard Stevens.
| c_bool_t C_socket_mcast_join (c_socket_t *s, const char *addr) | Function |
| c_bool_t C_socket_mcast_leave (c_socket_t *s, const char *addr) | Function |
|
These functions provide a means for joining and leaving a multicast
group. These functions return
|
| c_bool_t C_socket_mcast_set_ttl (c_socket_t *s, c_byte_t ttl) | Function |
|
This function sets the time-to-live value on the socket s to
ttl. It returns
|
| c_bool_t C_socket_mcast_set_loop (c_socket_t *s, c_bool_t loop) | Function |
|
This function enables or disables the loopback function for the UDP
socket s. If loopback is enabled (loop is The function returns
|
The following functions are high-level routines for reading data from and writing data to TCP and UDP sockets.
| int C_socket_recv (c_socket_t *s, char *buf, size_t bufsz, c_bool_t oobf) | Function |
| int C_socket_send (c_socket_t *s, const char *buf, size_t bufsz, c_bool_t oobf) | Function |
|
These functions read data from and write data to the socket
s. They may be used with TCP sockets or with connected UDP
sockets. If s is a TCP socket and oobf is
If an error or timeout occurs after n bytes of data have been read
or written, these functions return -n. If all of the data is read or
written successfully, the functions return the number of bytes read or
written (normally equal to bufsz). The functions return
|
| int C_socket_sendto (c_socket_t *s, const char *buf, size_t bufsz, const char *addr, in_port_t port) | Function |
| int C_socket_recvfrom (c_socket_t *s, char *buf, size_t bufsz, char *addr, size_t addrsz) | Function |
|
These functions send and receive datagrams over the unconnected UDP socket s.
These functions return the number of bytes written or read upon success,
0 if the socket is marked as blocking and the operation would
block, or
|
| int C_socket_sendreply (c_socket_t *s, const char *buf, size_t bufsz) | Function |
| int C_socket_recvreply (c_socket_t *s, char *buf, size_t bufsz) | Function |
|
These functions are similar to On success, the functions return the number of bytes sent or
received. On failure, they return
|
| int C_socket_sendline (c_socket_t *s, const char *buf) | Function |
| int C_socket_recvline (c_socket_t *s, char *buf, size_t bufsz) | Function |
|
These functions read and write "lines" to and from the TCP socket s. The socket must be in blocking mode for use with these functions.
If an error or timeout occurs after n bytes of data have been read
or written, these functions return -n. If all of the data was
written successfully, the functions return the number of bytes read or
written. The functions return
|
| int C_socket_writeline (c_socket_t *s, const char *buf, const char *termin, uint_t slen, uint_t snum) | Function |
| int C_socket_readline (c_socket_t *s, char *buf, size_t bufsz, char termin, uint_t slen, uint_t snum) | Function |
| int C_socket_rl (c_socket_t *s, char *buf, size_t bufsz, char termin) | Function |
| int C_socket_wl (c_socket_t *s, const char *buf, const char *termin) | Function |
|
These interfaces are deprecated, and are emulated by macros for backward
compatibility. They evaluate to calls to the |
This chapter discusses some miscellaneous functions.
The functions described in this section provide a simple API to UNIX
fortune databases. A fortune database consists of a text file
containing segments of text ("fortunes") demarcated by lines
containing only a percent (%) character, and a binary index file
containing the offsets of consecutive fortunes in the text file, each
offset being a 4-byte unsigned integer in network byte order.
All of the functions described in this chapter are defined in the header
cfl/fortune.h.
The type c_fortune_db_t represents a fortune database.
| c_bool_t C_fortune_indexdb (const char *basename) | Function |
|
This function rebuilds the index file for the fortune file
basename. The index file will be created in the same directory as
the source file, with the same name as the source file plus an
The function returns |
| c_fortune_db_t * C_fortune_opendb (const char *basename) | Function |
| c_bool_t C_fortune_closedb (c_fortune_db_t *db) | Function |
|
These functions open and close fortune databases.
|
| const char * C_fortune_select (c_fortune_db_t *db) | Function |
|
This function selects a fortune at random from the fortune database
db. The fortune is returned in a dynamically allocated buffer
which must be freed by the caller. On failure (for example, if db
is |
The following functions provide a very basic HTTP server implementation. This implementation currently only supports the "GET" method. This API is still evolving and should be considered "experimental."
The type c_httpsrv_t represents an HTTP server instance. Multiple instances can coexist in the same process, but each must be listening on a different port.
The type c_httpsrv_handler_t represents an HTTP request handler. It has the following prototype:
| void http_handler (c_socket_t *socket, const char *uri, c_hashtable_t *params) | Function |
|
The socket represents the connection to the client, uri is
the URI for the request, and params is the set of HTTP parameters
parsed from the query string following the URI (if any); params
may be Before sending data through the socket, the handler should call the
functions |
The type c_http_param_t represents an HTTP parameter. An HTTP parameter may have one value or an array of two or more values.
| c_httpsrv_t * C_httpsrv_create (in_port_t port, int max_workers, int timeout) | Function |
|
This function creates a new HTTP server. The server will listen for connections on the given TCP port. The argument max_workers specifies the number of worker threads to spawn (in the threaded version of the library) to handle incoming connections. The timeout for socket I/O, in seconds, is specified as timeout. The function returns the newly created c_httpsrv_t object on success, or |
| void C_httpsrv_destroy (c_httpsrv_t *srv) | Function |
|
This function destroys the HTTP server srv. It shuts down the server and deallocates all memory associated with it. |
| void C_httpsrv_add_handler (c_httpsrv_t *srv, const char *uri, c_httpsrv_handler_t handler) | Function |
| void C_httpsrv_remove_handler (c_httpsrv_t *srv, const char *uri) | Function |
|
These functions add and remove request handlers for the HTTP server srv.
|
| void C_httpsrv_set_default_handler (c_httpsrv_t *srv, c_httpsrv_handler_t handler) | Function |
|
This functions sets the default request handler for the HTTP
server srv. This handler will be invoked for any URI that is not
associated with any other handler. Passing |
| c_bool_t C_httpsrv_accept (c_httpsrv_t *srv) | Function |
|
This function accepts the next pending connection for the HTTP server
srv and processes the request. It returns |
| c_bool_t C_httpsrv_send_status (c_socket_t s, int status, c_bool_t errmsg) | Function |
| c_bool_t C_httpsrv_send_headers (c_socket_t *s, const char *mime_type, long content_length) | Function |
|
These functions send an HTTP response status and headers to the client connected on the socket s. They are meant to be used from within a request handler function, and should be called before any data is sent back to the client over the socket.
If errmsg is
Both functions return |
| c_http_param_t * C_http_param_get (c_hashtable_t *params, const char *key) | Function |
|
This function retrieves the HTTP parameter named key from the
parameter list params. It returns the parameter on success, or
|
| c_bool_t C_http_param_isarray (c_http_param_t *param) | Function |
| const char * C_http_param_value (c_http_param_t *param) | Function |
| c_linklist_t * C_http_param_values (c_http_param_t *param) | Function |
|
These functions are implemented as macros. |
The following functions provide runtime information about the CFL
library itself. All of the functions described in this chapter are
defined in the header cfl/version.h.
| const char * C_library_version (void) | Function |
|
This function returns a string containing the version number of the library. This version number corresponds to the version of the package. |
| const char * C_library_info (void) | Function |
|
This function returns a string containing information about the library, including the package name and version, the author, bug report email address, and copyright. |
| const char ** C_library_options (void) | Function |
|
This function returns a |
The following books proved to be indispensable during the implementation
of this library.
The CFL library is distributed under the terms of the LGPL. The complete
text of the license appears below.
Copyright © 1991, 1999 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence the
version number 2.1.]
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software-to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some specially designated software packages-typically libraries-of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of running
a program using the Library is not restricted, and output from such a
program is covered only if its contents constitute a work based on the
Library (independent of the use of the Library in a tool for writing
it). Whether that is true depends on what the Library does and what the
program that uses the Library does.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of a
storage or distribution medium does not bring the other work under the
scope of this License.
Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the
Library into a program that is not a library.
If distribution of object code is made by offering access to copy from a
designated place, then offering equivalent access to copy the source
code from the same place satisfies the requirement to distribute the
source code, even though third parties are not compelled to copy the
source along with the object code.
However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6, whether
or not they are linked directly with the Library itself.
You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
It may happen that this requirement contradicts the license restrictions
of other proprietary libraries that do not normally accompany the
operating system. Such a contradiction means you cannot use both them
and the Library together in an executable that you distribute.
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed to be
a consequence of the rest of this License.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a license
version number, you may choose any version ever published by the Free
Software Foundation.
To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. <signature of Ty Coon>, 1 April 1990 Ty Coon, President of Vice
That's all there is to it!
C_assert: Debugging and Tracing Functions
C_bit_clear: Convenience Macros
C_bit_isset: Convenience Macros
C_bit_set: Convenience Macros
C_bitstring_clear: Bitstring Functions
C_bitstring_clear_all: Bitstring Functions
C_bitstring_clear_range: Bitstring Functions
C_bitstring_compare: Bitstring Functions
C_bitstring_create: Bitstring Functions
C_bitstring_destroy: Bitstring Functions
C_bitstring_isclear: Bitstring Functions
C_bitstring_isset: Bitstring Functions
C_bitstring_set: Bitstring Functions
C_bitstring_set_all: Bitstring Functions
C_bitstring_set_range: Bitstring Functions
C_bitstring_size: Bitstring Functions
C_btree_create: B-Trees
C_btree_delete: B-Trees
C_btree_destroy: B-Trees
C_btree_iterate: B-Trees
C_btree_order: B-Trees
C_btree_restore: B-Trees
C_btree_set_destructor: B-Trees
C_btree_store: B-Trees
C_buffer_clear: Data Buffer Functions
C_buffer_create: Data Buffer Functions
C_buffer_data: Data Buffer Functions
C_buffer_datalen: Data Buffer Functions
C_buffer_destroy: Data Buffer Functions
C_buffer_hook: Data Buffer Functions
C_buffer_resize: Data Buffer Functions
C_buffer_size: Data Buffer Functions
C_byteord_htond: Byte Order Conversion Functions
C_byteord_htonf: Byte Order Conversion Functions
C_byteord_htonl: Byte Order Conversion Functions
C_byteord_htonll: Byte Order Conversion Functions
C_byteord_htons: Byte Order Conversion Functions
C_byteord_ntohd: Byte Order Conversion Functions
C_byteord_ntohf: Byte Order Conversion Functions
C_byteord_ntohl: Byte Order Conversion Functions
C_byteord_ntohll: Byte Order Conversion Functions
C_byteord_ntohs: Byte Order Conversion Functions
C_calloc: Memory Management Functions
C_darray_create: Dynamic Arrays
C_darray_defragment: Dynamic Arrays
C_darray_delete: Dynamic Arrays
C_darray_destroy: Dynamic Arrays
C_darray_iterate: Dynamic Arrays
C_darray_load: Dynamic Arrays
C_darray_restore: Dynamic Arrays
C_darray_save: Dynamic Arrays
C_darray_size: Dynamic Arrays
C_darray_store: Dynamic Arrays
C_datum_key: Data Elements
C_datum_value: Data Elements
C_debug_printf: Debugging and Tracing Functions
C_debug_set_stream: Debugging and Tracing Functions
C_debug_set_termattr: Debugging and Tracing Functions
C_debug_set_trace: Debugging and Tracing Functions
C_dlobject_create: Dynamic Linker Functions
C_dlobject_destroy: Dynamic Linker Functions
C_dlobject_error: Dynamic Linker Functions
C_dlobject_isloaded: Dynamic Linker Functions
C_dlobject_load: Dynamic Linker Functions
C_dlobject_lookup: Dynamic Linker Functions
C_dlobject_path: Dynamic Linker Functions
C_dlobject_unload: Dynamic Linker Functions
C_dstring_append: Dynamic Strings
C_dstring_create: Dynamic Strings
C_dstring_destroy: Dynamic Strings
C_dstring_getc: Dynamic Strings
C_dstring_gets: Dynamic Strings
C_dstring_length: Dynamic Strings
C_dstring_load: Dynamic Strings
C_dstring_putc: Dynamic Strings
C_dstring_puts: Dynamic Strings
C_dstring_puts_len: Dynamic Strings
C_dstring_rewind: Dynamic Strings
C_dstring_save: Dynamic Strings
C_dstring_seek: Dynamic Strings
C_dstring_trunc: Dynamic Strings
C_dstring_ungetc: Dynamic Strings
C_error_get_errno: Error Handling Functions
C_error_init: Error Handling Functions
C_error_printf: Error Handling Functions
C_error_set_errno: Error Handling Functions
C_error_syserr: Error Handling Functions
C_error_usage: Error Handling Functions
C_exec_pipefrom: Process Control Functions
C_exec_pipefrom_cwd: Process Control Functions
C_exec_pipeto: Process Control Functions
C_exec_pipeto_cwd: Process Control Functions
C_exec_run: Process Control Functions
C_exec_run_cwd: Process Control Functions
C_exec_va_call: Process Control Functions
C_exec_va_run: Process Control Functions
C_exec_va_run_cwd: Process Control Functions
C_exec_wait: Process Control Functions
C_fd_recv: File Descriptor Passing Functions
C_fd_send: File Descriptor Passing Functions
C_file_getcwd: Filesystem Functions
C_file_issymlink: Filesystem Functions
C_file_load: Filesystem Functions
C_file_lock: Mandatory File Locking Functions
C_file_mkdirs: Filesystem Functions
C_file_readdir: Filesystem Functions
C_file_traverse: Filesystem Functions
C_file_trylock: Mandatory File Locking Functions
C_file_unlock: Mandatory File Locking Functions
C_fortune_closedb: Fortune Database Functions
C_fortune_indexdb: Fortune Database Functions
C_fortune_opendb: Fortune Database Functions
C_fortune_select: Fortune Database Functions
C_free: Memory Management Functions
C_free_vec: Memory Management Functions
C_getchar: I/O Functions
C_getline: I/O Functions
C_gets: I/O Functions
C_hashtable_create: Hashtables
C_hashtable_delete: Hashtables
C_hashtable_destroy: Hashtables
C_hashtable_keys: Hashtables
C_hashtable_restore: Hashtables
C_hashtable_set_destructor: Hashtables
C_hashtable_set_hashfunc: Hashtables
C_hashtable_size: Hashtables
C_hashtable_store: Hashtables
C_hex_decode: Hexadecimal Encoding Functions
C_hex_encode: Hexadecimal Encoding Functions
C_hex_frombyte: Hexadecimal Encoding Functions
C_hex_fromnibble: Hexadecimal Encoding Functions
C_hex_isdigit: Hexadecimal Encoding Functions
C_hex_tobyte: Hexadecimal Encoding Functions
C_hex_tonibble: Hexadecimal Encoding Functions
C_http_param_get: HTTP Functions
C_http_param_isarray: HTTP Functions
C_http_param_value: HTTP Functions
C_http_param_values: HTTP Functions
C_httpsrv_accept: HTTP Functions
C_httpsrv_add_handler: HTTP Functions
C_httpsrv_create: HTTP Functions
C_httpsrv_destroy: HTTP Functions
C_httpsrv_remove_handler: HTTP Functions
C_httpsrv_send_headers: HTTP Functions
C_httpsrv_send_status: HTTP Functions
C_httpsrv_set_default_handler: HTTP Functions
C_io_fprintf: I/O Functions
C_io_getchar: I/O Functions
C_io_getline: I/O Functions
C_io_getline_buf: I/O Functions
C_io_getpasswd: I/O Functions
C_io_gets: I/O Functions
C_lengthof: Convenience Macros
C_library_info: Library Information Functions
C_library_options: Library Information Functions
C_library_version: Library Information Functions
C_link_data: Links
C_link_next: Links
C_link_prev: Links
C_linklist_create: Linked Lists
C_linklist_delete: Linked Lists
C_linklist_delete_r: Linked Lists
C_linklist_destroy: Linked Lists
C_linklist_head: Linked Lists
C_linklist_ishead: Linked Lists
C_linklist_ishead_r: Linked Lists
C_linklist_istail: Linked Lists
C_linklist_istail_r: Linked Lists
C_linklist_length: Linked Lists
C_linklist_move: Linked Lists
C_linklist_move_head: Linked Lists
C_linklist_move_head_r: Linked Lists
C_linklist_move_next: Linked Lists
C_linklist_move_next_r: Linked Lists
C_linklist_move_prev: Linked Lists
C_linklist_move_prev_r: Linked Lists
C_linklist_move_r: Linked Lists
C_linklist_move_tail: Linked Lists
C_linklist_move_tail_r: Linked Lists
C_linklist_restore: Linked Lists
C_linklist_restore_r: Linked Lists
C_linklist_search: Linked Lists
C_linklist_search_r: Linked Lists
C_linklist_set_destructor: Linked Lists
C_linklist_store: Linked Lists
C_linklist_store_r: Linked Lists
C_linklist_tail: Linked Lists
C_log_error: Logging Functions
C_log_info: Logging Functions
C_log_set_console: Logging Functions
C_log_set_stream: Logging Functions
C_log_set_termattr: Logging Functions
C_log_warning: Logging Functions
C_malloc: Memory Management Functions
C_max: Convenience Macros
C_mem_default_alloc_hook: Memory Management Functions
C_mem_defrag: Memory Management Functions
C_mem_free: Memory Management Functions
C_mem_freevec: Memory Management Functions
C_mem_manage: Memory Management Functions
C_mem_set_alloc_hook: Memory Management Functions
C_mem_set_errorfunc: Memory Management Functions
C_mem_va_free: Memory Management Functions
C_memfile_base: Memory Mapped Files
C_memfile_close: Memory Mapped Files
C_memfile_length: Memory Mapped Files
C_memfile_open: Memory Mapped Files
C_memfile_pointer: Memory Mapped Files
C_memfile_resize: Memory Mapped Files
C_memfile_sync: Memory Mapped Files
C_min: Convenience Macros
C_net_get_svcname: Network Information Functions
C_net_get_svcport: Network Information Functions
C_net_resolve: Network Information Functions
C_net_resolve_local: Network Information Functions
C_new: Memory Management Functions
C_newa: Memory Management Functions
C_newb: Memory Management Functions
C_newstr: Memory Management Functions
C_offsetof: Convenience Macros
C_printf: I/O Functions
C_pty_create: Pseudoterminal Control Functions
C_pty_destroy: Pseudoterminal Control Functions
C_pty_master_fd: Pseudoterminal Control Functions
C_pty_slave_fd: Pseudoterminal Control Functions
C_pty_slave_name: Pseudoterminal Control Functions
C_queue_create: Queues
C_queue_dequeue: Queues
C_queue_destroy: Queues
C_queue_enqueue: Queues
C_queue_length: Queues
C_queue_set_destructor: Queues
C_random: Random Number Functions
C_random_seed: Random Number Functions
C_realloc: Memory Management Functions
C_sched_event_activate: Event Scheduling Functions
C_sched_event_create: Event Scheduling Functions
C_sched_event_data: Event Scheduling Functions
C_sched_event_deactivate: Event Scheduling Functions
C_sched_event_destroy: Event Scheduling Functions
C_sched_event_find: Event Scheduling Functions
C_sched_event_id: Event Scheduling Functions
C_sched_init: Scheduler Control Functions
C_sched_poll: Scheduler Control Functions
C_sched_shutdown: Scheduler Control Functions
C_sem_create: Semaphore Functions
C_sem_destroy: Semaphore Functions
C_sem_initial_value: Semaphore Functions
C_sem_name: Semaphore Functions
C_sem_post: Semaphore Functions
C_sem_trywait: Semaphore Functions
C_sem_value: Semaphore Functions
C_sem_wait: Semaphore Functions
C_sgn: Convenience Macros
C_shmem_base: Shared Memory Functions
C_shmem_create: Shared Memory Functions
C_shmem_destroy: Shared Memory Functions
C_shmem_name: Shared Memory Functions
C_shmem_resize: Shared Memory Functions
C_shmem_size: Shared Memory Functions
C_signal_name: Signal Handling Functions
C_socket_accept: Socket Control Functions
C_socket_accept_s: Socket Control Functions
C_socket_block: Socket Control Functions
C_socket_connect: Socket Control Functions
C_socket_create: Socket Control Functions
C_socket_create_s: Socket Control Functions
C_socket_destroy: Socket Control Functions
C_socket_destroy_s: Socket Control Functions
C_socket_fclose: Socket Control Functions
C_socket_fopen: Socket Control Functions
C_socket_get_fd: Socket Control Functions
C_socket_get_fp: Socket Control Functions
C_socket_get_ipaddr: Socket Control Functions
C_socket_get_option: Socket Control Functions
C_socket_get_peeraddr: Socket Control Functions
C_socket_get_peeripaddr: Socket Control Functions
C_socket_get_timeout: Socket Control Functions
C_socket_get_type: Socket Control Functions
C_socket_get_userdata: Socket Control Functions
C_socket_isblocked: Socket Control Functions
C_socket_listen: Socket Control Functions
C_socket_mcast_join: Socket Multicast Functions
C_socket_mcast_leave: Socket Multicast Functions
C_socket_mcast_set_loop: Socket Multicast Functions
C_socket_mcast_set_ttl: Socket Multicast Functions
C_socket_readline: Socket I/O Functions
C_socket_recv: Socket I/O Functions
C_socket_recvfrom: Socket I/O Functions
C_socket_recvline: Socket I/O Functions
C_socket_recvreply: Socket I/O Functions
C_socket_reopen: Socket Control Functions
C_socket_reopen_s: Socket Control Functions
C_socket_rl: Socket I/O Functions
C_socket_send: Socket I/O Functions
C_socket_sendline: Socket I/O Functions
C_socket_sendreply: Socket I/O Functions
C_socket_sendto: Socket I/O Functions
C_socket_set_option: Socket Control Functions
C_socket_set_timeout: Socket Control Functions
C_socket_set_userdata: Socket Control Functions
C_socket_shutdown: Socket Control Functions
C_socket_unblock: Socket Control Functions
C_socket_wl: Socket I/O Functions
C_socket_writeline: Socket I/O Functions
C_stack_create: Stacks
C_stack_depth: Stacks
C_stack_destroy: Stacks
C_stack_peek: Stacks
C_stack_pop: Stacks
C_stack_push: Stacks
C_stack_set_destructor: Stacks
C_strbuffer_clear: String Buffer Functions
C_strbuffer_create: String Buffer Functions
C_strbuffer_destroy: String Buffer Functions
C_strbuffer_putc: String Buffer Functions
C_strbuffer_size: String Buffer Functions
C_strbuffer_sprintf: String Buffer Functions
C_strbuffer_strcat: String Buffer Functions
C_strbuffer_strcpy: String Buffer Functions
C_strbuffer_string: String Buffer Functions
C_strbuffer_strlen: String Buffer Functions
C_string_chop: String Manipulation and Parsing Functions
C_string_clean: String Manipulation and Parsing Functions
C_string_compare: String Manipulation and Parsing Functions
C_string_concat: String Manipulation and Parsing Functions
C_string_copy: String Manipulation and Parsing Functions
C_string_dup: String Manipulation and Parsing Functions
C_string_dup1: String Manipulation and Parsing Functions
C_string_endswith: String Manipulation and Parsing Functions
C_string_hash: String Manipulation and Parsing Functions
C_string_isnumeric: String Manipulation and Parsing Functions
C_string_sortvec: String Manipulation and Parsing Functions
C_string_split: String Manipulation and Parsing Functions
C_string_startswith: String Manipulation and Parsing Functions
C_string_tolower: String Manipulation and Parsing Functions
C_string_toupper: String Manipulation and Parsing Functions
C_string_trim: String Manipulation and Parsing Functions
C_string_va_concat: String Manipulation and Parsing Functions
C_string_va_copy: String Manipulation and Parsing Functions
C_string_va_makevec: String Manipulation and Parsing Functions
C_string_valist2vec: String Manipulation and Parsing Functions
C_system_cdhome: System Information Functions
C_system_get_fullname: System Information Functions
C_system_get_gid: System Information Functions
C_system_get_homedir: System Information Functions
C_system_get_hostname: System Information Functions
C_system_get_login: System Information Functions
C_system_get_pid: System Information Functions
C_system_get_term: System Information Functions
C_system_get_uid: System Information Functions
C_system_getinfo: System Information Functions
C_system_ingroup: System Information Functions
C_system_passwd_generate: System Information Functions
C_system_passwd_validate: System Information Functions
C_tag_data: Tags
C_tag_key: Tags
C_time_format: Time Functions
C_time_parse: Time Functions
C_timer_create: CPU Timer Functions
C_timer_created: CPU Timer Functions
C_timer_destroy: CPU Timer Functions
C_timer_elapsed: CPU Timer Functions
C_timer_isrunning: CPU Timer Functions
C_timer_reset: CPU Timer Functions
C_timer_resume: CPU Timer Functions
C_timer_start: CPU Timer Functions
C_timer_stop: CPU Timer Functions
C_timer_system: CPU Timer Functions
C_timer_user: CPU Timer Functions
C_tty_raw: Terminal Control Functions
C_tty_restore: Terminal Control Functions
C_tty_sane: Terminal Control Functions
C_tty_store: Terminal Control Functions
C_tty_unraw: Terminal Control Functions
C_va_free: Memory Management Functions
C_vector_abort: String Vector Functions
C_vector_end: String Vector Functions
C_vector_free: String Vector Functions
C_vector_start: String Vector Functions
C_vector_store: String Vector Functions
C_xml_document_create: XML Data Manipulation Functions
C_xml_document_destroy: XML Data Manipulation Functions
C_xml_document_get_root: XML Data Manipulation Functions
C_xml_document_read: XML Data Manipulation Functions
C_xml_document_set_root: XML Data Manipulation Functions
C_xml_document_write: XML Data Manipulation Functions
C_xml_element_add_child: XML Data Manipulation Functions
C_xml_element_create: XML Data Manipulation Functions
C_xml_element_delete_param: XML Data Manipulation Functions
C_xml_element_delete_params: XML Data Manipulation Functions
C_xml_element_destroy: XML Data Manipulation Functions
C_xml_element_destroy_recursive: XML Data Manipulation Functions
C_xml_element_get_children: XML Data Manipulation Functions
C_xml_element_get_children_named: XML Data Manipulation Functions
C_xml_element_get_content: XML Data Manipulation Functions
C_xml_element_get_first_child: XML Data Manipulation Functions
C_xml_element_get_param: XML Data Manipulation Functions
C_xml_element_remove_child: XML Data Manipulation Functions
C_xml_element_remove_children: XML Data Manipulation Functions
C_xml_element_remove_children_named: XML Data Manipulation Functions
C_xml_element_set_content: XML Data Manipulation Functions
C_xml_element_set_param: XML Data Manipulation Functions
C_zero: Memory Management Functions
C_zeroa: Memory Management Functions
http_handler: HTTP Functions
c_bitstring_t: Bitstring Functions
c_bool_t: Basic Types
c_btree_t: B-Trees
c_buffer_t: Data Buffer Functions
c_byte_t: Basic Types
c_darray_t: Dynamic Arrays
c_datum_t: Data Elements
c_dirlist_t: Filesystem Functions
c_dlobject_t: Dynamic Linker Functions
c_dstring_t: Dynamic Strings
c_fortune_db_t: Fortune Database Functions
c_hashtable_t: Hashtables
c_http_param_t: HTTP Functions
c_httpsrv_handler_t: HTTP Functions
c_httpsrv_t: HTTP Functions
c_id_t: IDs
c_link_t: Basic Data Types
c_linklist_t: Linked Lists
c_memfile_t: Memory Mapped Files
c_pty_t: Pseudoterminal Control Functions
c_queue_t: Queues
c_schedevt_t: Event Scheduling Functions
c_sem_t: Semaphore Functions
c_shmem_t: Shared Memory Functions
c_socket_t: Socket Control Functions
c_stack_t: Stacks
c_strbuffer_t: String Buffer Functions
c_sysinfo_t: System Information Functions
c_tag_t: Basic Data Types
c_timer_t: CPU Timer Functions
c_vector_t: String Vector Functions
c_xml_document_t: XML Data Manipulation Functions
c_xml_element_t: XML Data Manipulation Functions
uint_t: Basic Types
C_DARRAY_MAX_RESIZE: Dynamic Arrays
C_DSTRING_MIN_BLOCKSZ: Dynamic Strings
C_DSTRING_SEEK_ABS: Dynamic Strings
C_DSTRING_SEEK_END: Dynamic Strings
C_DSTRING_SEEK_REL: Dynamic Strings
C_EACCEPT: Socket Control Functions
C_EADDRINFO: Socket I/O Functions, Socket Control Functions, Network Information Functions, Socket Multicast Functions, Network Information Functions
C_EBADSTATE: Socket I/O Functions, Socket Control Functions, Socket I/O Functions, Socket Control Functions, Socket I/O Functions, Socket Control Functions, Socket I/O Functions
C_EBADTYPE: Socket Multicast Functions, Socket I/O Functions, Socket Control Functions, Socket I/O Functions, Socket Control Functions, Socket I/O Functions
C_EBIND: Socket Control Functions
C_EBLOCKED: Socket Control Functions, Socket I/O Functions
C_ECONNECT: Socket Control Functions
C_EFCNTL: Socket Control Functions
C_EFDOPEN: Socket Control Functions
C_EGETPTY: Pseudoterminal Control Functions
C_EINVAL: Socket Control Functions, Network Information Functions, Socket Control Functions, Socket I/O Functions, Socket Multicast Functions, Terminal Control Functions, Socket Multicast Functions, Socket Control Functions, Network Information Functions
C_EIOCTL: Pseudoterminal Control Functions
C_ELISTEN: Socket Control Functions
C_ELOSTCONN: Socket I/O Functions
C_EMSG2BIG: Socket I/O Functions
C_ENOCONN: Socket Control Functions
C_ENOTTY: Terminal Control Functions
C_EOPEN: Pseudoterminal Control Functions
C_ERECV: Socket I/O Functions
C_ERECVFROM: Socket I/O Functions
C_ESEND: Socket I/O Functions
C_ESENDTO: Socket I/O Functions
C_ESOCKET: Socket Control Functions
C_ESOCKINFO: Socket Control Functions, Socket Multicast Functions, Socket Control Functions
C_ESVCINFO: Network Information Functions
C_ETCATTR: Terminal Control Functions
C_ETIMEOUT: Socket I/O Functions, Socket Control Functions
C_FILE_ADDSLASH: Filesystem Functions
C_FILE_GETCHAR_DELAY: I/O Functions
C_FILE_READ_LOCK: Mandatory File Locking Functions
C_FILE_SEPARATE: Filesystem Functions
C_FILE_SKIP2DOT: Filesystem Functions
C_FILE_SKIPDIRS: Filesystem Functions
C_FILE_SKIPDOT: Filesystem Functions
C_FILE_SKIPFILES: Filesystem Functions
C_FILE_SKIPHIDDEN: Filesystem Functions
C_FILE_SORT: Filesystem Functions
C_FILE_WRITE_LOCK: Mandatory File Locking Functions
C_LINKLIST_HEAD: Linked Lists
C_LINKLIST_NEXT: Linked Lists
C_LINKLIST_PREV: Linked Lists
C_LINKLIST_TAIL: Linked Lists
C_NET_BUFFERING_FULL: Socket Control Functions
C_NET_BUFFERING_LINE: Socket Control Functions
C_NET_BUFFERING_NONE: Socket Control Functions
C_NET_OPT_BLOCK: Socket Control Functions
C_NET_OPT_KEEPALIVE: Socket Control Functions
C_NET_OPT_LINGER: Socket Control Functions
C_NET_OPT_OOBINLINE: Socket Control Functions
C_NET_OPT_RECVBUF: Socket Control Functions
C_NET_OPT_REUSEADDR: Socket Control Functions
C_NET_OPT_SENDBUF: Socket Control Functions
C_NET_OTHER: Network Information Functions
C_NET_SHUTALL: Socket Control Functions
C_NET_SHUTRD: Socket Control Functions
C_NET_SHUTWR: Socket Control Functions
C_NET_TCP: Network Information Functions
C_NET_UDP: Network Information Functions
C_NET_UNKNOWN: Network Information Functions
C_SEM_MAX_VALUE: Semaphore Functions
CRLF: Miscellaneous Constants
DEBUG: Debugging and Tracing Functions
FALSE: API Conventions
NUL: Miscellaneous Constants
TRUE: API Conventions