Cbase 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 cbase library exists in two configurations (the multi-threaded configuration and the non-threaded configuration) and two forms (a static library and a shared library), for a total of four versions. The single-threaded versions are named libcbaes.a and libcbase.so, and the multi-threaded versions are named libcbase_mt.a and libcbase_mt.so.
Therefore, to link with the single-threaded version of the cbase library, issue a command such as:
gcc file1.o file2.o -o myprogram -lcbase
And similarly, to link with the multi-threaded version:
gcc file1.o file2.o -o myprogram -lcbase_mt
If your program uses the XML functions, it will also need to be linked with the expat library, e.g.:
gcc file1.o file2.o -o myprogram -lcbase -lexpat
If your program 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 -lcbase -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 non-threaded version. Other combinations will produce undefined behavior in your programs.
On some systems, if both shared and static versions of a given library are present (as they are with cbase), the linker selects the shared library by default, producing a dynamically linked executable. When a program is linked in this way, all library dependencies must be specified at link time, so that the linker can generate all of the necessary library stubs in the executable. Since the cbase library contains references to functions that are typically defined in various system libraries, those libraries must be explicitly linked into your program. This list varies by operating system, but typically includes crypt (the crypto library), rt (the POSIX real-time library), and dl (the dynamic runtime linker library).
It is possible to force the linker to link against static libraries, producing a statically linked executable. The appropriate switches vary across linkers and operating systems. If you're using gcc, you can use the -static switch to accomplish this. For example:
gcc -static file1.o file2.o -o myprogram -lcbase
You can simplify the compiling and linking process, particularly for static linking, by using the pkg-config utility (version 0.20 or newer) to produce the appropriate preprocessor and linker flags for cbase. Make sure the environment variable `PKG_CONFIG_PATH' is defined to include the absolute path to the lib/pkgconfig directory beneath the cbase installation directory. Then, you can compile a program that uses cbase as follows:
gcc -static file1.c file2.c -o myprogram \ `pkg-config --cflags --libs --static libcbase`
Substitute `libcbase_mt' for `libcbase' above when linking with the multithreaded version of the library. Omit the `-static' and `--static' switches if dynamic linking is desired. The backquoted expression will evaluate to a list of all necessary preprocessor and linker flags, including flags for any additional system libraries that are required.
All of the definitions in the library can be made available in your source code by including the master header file cbase/cbase.h.
This section describes the naming and calling conventions for constants, macros, datatypes, and functions in the cbase library.
All functions and macros begin with the prefix `C_'.
All constants begin with the prefix `C_', with the following
exceptions: TRUE
, FALSE
, NUL
, and CRLF
.
All datatypes begin with the prefix `c_' and end with the suffix `_t', with the following exception: 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 cbase 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 cbase 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.
Cbase was previously known as CFL. Prior to that, it was known as pingutil, the PING Utility Library. These earlier names caused the library to be frequently confused with other projects. The final version of CFL was 1.2.9, and the first version of cbase is 1.3. With the exception of the names of the header files, the cbase API is identical to that of CFL.
This chapter describes convenience types, macros, and constants. These are defined in the header cbase/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:
The first two macros correspond to the mathematical max and min functions.
C_max()
returns a if a > b and b otherwise.C_min()
returns a if a < b and b otherwise. The third macro corresponds to the mathematical sgn function. It returns-1
if a < 0,1
if a > 0, or0
if a == 0. Note that these macros may evaluate their arguments more than once, so they should not be applied to expressions that have side-effects (e.g., “b++
”).
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.
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
XtOffsetOf()
.
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 cbase/system.h.
The following sections describe each group in detail.
The following functions convert various numeric types between host and network byte order.
These functions convert an unsigned 16-bit “short” integer val to and from network byte order, respectively. The functions return the converted value.
These functions convert an unsigned 32-bit “long” integer val to and from network byte order, respectively. The functions return the converted value.
These functions convert an unsigned 64-bit “long long” integer val to and from network byte order, respectively. The functions return the converted value.
These functions convert an 32-bit floating point value val to and from network byte order, respectively. The functions return the converted value.
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.
This function is similar to
printf()
, and is intended for use in generating debug output. The function is actually implemented as a macro which evaluates to a call to an internal library function if theDEBUG
macro is defined; otherwise, it is defined as a no-op, which essentially prevents the debug call from being compiled into the calling code.Debug messages are written to the debugging stream (
stderr
by default). The stream is explicitly flushed after the message is written.If tracing is enabled, the message will be preceded by the source file name and line number of the
C_debug_printf()
call. In the multi-threaded version of the library, the message will be preceded by the calling thread's ID as well.
These functions alter the behavior of the
C_debug_printf()
function described above.
C_debug_set_trace()
enables or disables tracing based on the value of flag. If tracing is enabled, the filename and line number of theC_debug_printf()
call will be prepended to each line of debug output.
C_debug_set_stream()
sets the output stream for debug messages to stream; the default stream isstderr
.
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.
This macro evaluates an assertion; it is provided as a replacement for the more rudimentary
assert()
C library function. The macro works as follows.If the expression expr evaluates to zero (
0
), the assertion fails. A message that indicates the failure and contains the text of the expression itself is written to the debugging stream in the same manner as withC_debug_printf()
, and then the process is aborted via a call to theabort()
C library function. For all other (non-zero) values, the macro behaves as a no-op.
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.
These functions create and destroy loadable objects.
C_dlobject_create()
creates a new loadable object for the object file specifed by path. The object will be created in a non-loaded state. The function returns a pointer to the new loadable object structure on success, orNULL
on failure.
C_dlobject_destroy()
destroys the loadable object obj, if it is not currently loaded. It returnsTRUE
on success andFALSE
on failure.
These functions load and unload the loadable object obj.
C_dlobject_load()
loads the object obj into memory. The flag lazy specifies whether symbols will be resolved as they are accessed (lazy relocation), or all at once when the object is loaded. The function will fail if obj is already loaded.
C_dlobject_unload()
unloads the loadable object obj. The function will fail if obj is not currently loaded.The functions return
TRUE
on success andFALSE
on failure. In the event of a load/unload failure, a linker-specific error is stored in obj and may be accessed viaC_dlobject_error()
, which is described below.
This function looks up the symbol named symbol in the loadable object obj. It returns a pointer to the symbol on success, or
NULL
on failure. In the event of a lookup failure, a linker-specific error is stored in obj and may be accessed viaC_dlobject_error()
, which is described below.
This function (which is implemented as a macro) returns
TRUE
if the loadable object obj is currently loaded, andFALSE
otherwise.
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.
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.
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
argv[0]
. The function internally stores a copy of this pointer.
This function receives arguments in the same manner as the
printf()
library function. It writes the program name to standard error, then passes its arguments to thevfprintf()
library function for formatted output to standard error. It then flushes the standard error stream.
This function prints the command-line usage information message usage to standard error. It then flushes the standard error stream.
This function is a higher-level interface to the
strerror()
library function. It obtains the error code from the latest system call executed, formats it as a string, and writes it to standard error. All other functionality is identical toC_error_printf()
above.
This function returns a textual error message for the error code from the last-executed cbase library routine.
This function returns the error code from the last-executed cbase library routine. A return value of
0
by convention denotes that the last call executed successfully (no error); note however, that most library routines do not modify the error code at all if they complete successfully. In the multi-threaded version of the library, this function returns a thread-specific error value. In the single-threaded version, it simply returns the value ofc_errno
.Calling this routine is equivalent to evaluating
c_errno
, which is defined as a macro that evaluates to a call toC_error_get_errno()
.Therefore in both single-threaded and multi-threaded code, it is safe to call
C_error_get_errno()
or to evaluatec_errno
as if it were a global variable; either approach will correctly return the error code for the current thread or process. Note that sincec_errno
evaluates to a function call, it cannot be used as an lvalue; that is, it is not possible to assign values to it.
This function sets the error code for the currently executing cbase library routine to err. This function is provided for use by cbase extension libraries and is not intended for use by user code.
In the multi-threaded version of the library,
C_error_set_errno
is defined as a function that sets a thread-specific error value. Otherwise, it is defined as a function that simply assigns err to the global int variablec_errno
.
The following functions provide subprocess control, including
higher-level interfaces to system calls such as execv()
, and
piping.
C_exec_run()
is a higher-level interface to theexecv()
system call. It executes the command specified by argv as a subprocess, connecting its standard input stream to the fdin file descriptor (or to /dev/null if fdin is negative) and its standard output and standard error streams to the fdout file descriptor (or to /dev/null if fdout is negative). If waitf isTRUE
, the function additionally performs awaitpid()
system call to wait for the subprocess to finish executing.
C_exec_run_cwd()
is identical toC_exec_run()
, except that the additional argument cwd specifies a new working directory for the spawned subprocess. If this path does not exist or is not readable, the working directory of the subprocess will remain unchanged.If waitf is
TRUE
, the functions return the exit value from the subprocess. Otherwise, they return0
on success or-1
on failure.
These are variable argument list versions of
C_exec_run()
andC_exec_run_cwd()
. The command name and arguments are passed as aNULL
-terminated list of char * arguments rather than as a string vector. The other arguments have the same meaning as inC_exec_run()
andC_exec_run_cwd()
, and the functionality is identical.
C_exec_pipefrom()
executes the command specified by argv as a subprocess, redirecting its standard input stream to /dev/null, and connecting its standard output and standard error streams to a new file descriptor whose value is stored at fd. It returns immediately after forking the subprocess. Subsequent reads from the file descriptor at fd will effect a piping of output from the subprocess into the caller.
C_exec_pipefrom_cwd()
is identical toC_exec_pipefrom()
, except that the additional argument cwd specifies a new working directory for the spawned subprocess. If this path does not exist or is not readable, the working directory of the subprocess will remain unchanged.The functions return
0
on success, or-1
on failure.The following code illustrates the use of
C_exec_pipefrom()
to process the output from an execution of thels
program.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);
C_exec_pipeto()
executes the command specified by argv as a subprocess, redirecting its standard output and standard error streams to /dev/null, and connecting its standard input stream to a new file descriptor whose value is stored at fd. It returns immediately after forking the subprocess. Subsequent writes to the file descriptor at fd will effect a piping of input into the subprocess from the caller.
C_exec_pipeto_cwd()
is identical toC_exec_pipeto()
, except that the additional argument cwd specifies a new working directory for the spawned subprocess. If this path does not exist or is not readable, the working directory of the subprocess will remain unchanged.The functions return
0
on success, or-1
on failure.
This function is intended for use as a replacement for the unsafe
system()
library function. It executes in a subprocess the command specified by theNULL
-terminated variable argument list, waits for the subprocess to finish, and returns the exit value returned by the subprocess. No stream redirection takes place: the subprocess reads from and writes to the parent's standard I/O streams. This function is implemented using a call toC_exec_run()
, which calls theexecvp()
system call.On success, the function returns the exit status from the subprocess. On failure, it returns
-1
.
This function is an interface to the
waitpid()
system call. It waits for the process with process ID of pid to complete, and returns its exit status.
The following functions provide for the manipulation of files and directories in the UNIX filesystem.
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:
C_FILE_SKIPDOT
- Specifies that the . entry (referring to the current directory) not be included in the list.
C_FILE_SKIP2DOT
- Specifies that the .. entry (referring to the parent directory) not be included in the list.
C_FILE_SKIPHIDDEN
- Specifies that hidden files (those beginning with .) not be included in the list.
C_FILE_ADDSLASH
- Specifies that a slash (/) be appended to directory names.
C_FILE_SKIPDIRS
- Specifies that directories not be included in the list.
C_FILE_SKIPFILES
- Specifies that ordinary files not be included in the list.
C_FILE_SEPARATE
- Specifies that directory names and file names be separated into two separate lists.
C_FILE_SORT
- Specifies that the resulting list(s) of names be sorted alphabetically.
The c_dirlist_t type is a structure that contains the following members:
char **files
A vector of file names (or all names, if C_FILE_SEPARATE
was not specified).char **dirs
A vector of directory names (or NULL
, ifC_FILE_SEPARATE
was not specified).uint_t nfiles
The number of regular file names read. uint_t ndirs
The number of directory names read. The function ignores all files which are not regular files or directories, including symbolic links.
The function returns
TRUE
on success, orFALSE
on failure (for example, if path isNULL
or invalid).
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
TRUE
, the traversal continues. Otherwise, if it returnsFALSE
,C_file_traverse()
sets the working directory back to path and returns immediately.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
TRUE
if the tree traversal completed successfully. It returnsFALSE
if any of the arguments were invalid, if it could not set the working directory to path, or if examine() returnedFALSE
during the traversal.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); }
This function is a higher-level interface to the
getcwd()
system call. It callsgetcwd()
with an initial path buffer, and if the buffer is too small to hold the entire path, it resizes the buffer and tries again, ad infinitum. The function returns a dynamically allocated string containing the current path on success, orNULL
on failure. The returned string must eventually be freed by the caller.
This function returns
TRUE
if the file specified by path is a symbolic link, andFALSE
otherwise.
This function creates all intermediate directories specified in path. Directories will be created with the permissions specified by mode. The function returns
TRUE
on success orFALSE
on failure.
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
NUL
byte; this allows the data to be interpreted as a string if the source was a text file.On failure (for example, if path or len is
NULL
, or if the file does not exist or cannot be read) the function returnsNULL
.
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.
This function locks an open file fp. The type of lock is specified by type and must be one of
C_FILE_READ_LOCK
(for a read lock) orC_FILE_WRITE_LOCK
(for a write lock); these constants are defined in cbase/util.h. If the file referred to by fp is currently locked by another thread or process, this function blocks until that lock is released.The function returns
TRUE
if the lock operation succeeds, andFALSE
if it fails.
This function is similar to
C_file_lock()
above, except that if the lock cannot be obtained, the function returns immediately with a value ofFALSE
.The function returns
TRUE
if the lock operation succeeds, andFALSE
if it fails.
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
C_file_lock()
orC_file_trylock()
call that established this lock.The function returns
TRUE
if the unlock operation succeeds, andFALSE
if it fails.
The following functions simplify reading from and writing to files and obtaining input from the console.
This function is meant to be used as a replacement for
getchar()
in interactive contexts. It accepts a single character of input from the user by disabling all buffering and character processing on the controlling terminal. Any character can be entered, including those that have special meaning to the shell. The argument delay specifies how many seconds to wait for a character to be entered.If the delay expires before a character is typed, the function returns
EOF
. Otherwise, it returns the ASCII value of the character. The value of delay may be 0 to effect a poll of the keyboard.
This function is meant to be used as a replacement for the
fgets()
library function. It reads data from the stream fp into the buffer buf until bufsz - 1 bytes have been read or the terminator character termin is encountered. Once either condition has occurred, the input buffer is terminated with aNUL
character. The terminator character is discarded.The function returns the number of bytes actually read, or
EOF
if no more characters are available. A return value of0
means that the terminator character was the first character encountered; it does not signify an end-of-file condition.If fp or buf is
NULL
, the function returnsEOF
immediately.
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
C_io_gets()
above, and then turns echoing back on. The input buffer is terminated with aNUL
character. The newline terminator character is discarded.
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
NUL
-terminated. The number of characters read (not including the terminator) is stored at len if it is non-NULL
.On success, the function returns a pointer to the dynamically allocated buffer, which is exactly large enough to hold the
NUL
-terminated string. On failure (for example, on end-of-file), it returnsNULL
.
This function is similar to
C_io_getline()
above, except that the buffer specified by buf is used to store the data. This buffer will be resized as necessary to accommodate the data read. The number of characters read (not including the terminator) is stored in thedatalen
field of the buffer buf, and may be obtained by using the macroC_buffer_datalen()
.On success, the function returns the pointer to the data in buf, as returned by the macro
C_buffer_data()
. On failure (for example, on end-of-file), it returnsNULL
.
This is a convenience macro. It evaluates to an expression involving a call to
C_io_getchar()
, passingC_IO_GETCHAR_DELAY
as an argument.
This is a convenience macro. It evaluates to an expression involving a call to
C_io_gets()
, passingstdin
as the stream and `\n
' (newline) as the terminator character. It may be used as a direct replacement for thegets()
library function.
This is a convenience macro. It evaluates to an expression involving a call to
C_io_getline()
, passing `\n' (newline) as the terminator character.
This is a threadsafe wrapper for the
fprintf()
library function. It locks stream via a call toflockfile()
before proceeding to callfprintf()
, and then unlocks the stream after that function completes. This ensures that only one thread at a time can write to the stream.The function returns the value returned by
fprintf()
. In the single-threaded version of the library, this function simply invokesfprintf()
.
This function (which is implemented as a macro) calls
C_io_fprintf()
, described above, passingstdout
as the stream.
The following functions provide a simple, minimal API for writing log messages to the console and/or a log file.
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.
This function specifies the stream for log messages. If stream is
NULL
, logging to a stream will be disabled.
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.
These
printf()
-style functions write informational, warning, and error messages, respectively, to the console and/or the logging stream.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.
This is a general-purpose memory management function. It is a higher-level interface to the
realloc()
library function. The argument p is a pointer to the memory to be managed in the case of a reallocation request, orNULL
for an initial allocation request. The new or initial size of the memory, in bytes, is specified by elemsz. If clearf isTRUE
, the newly allocated memory is zeroed; if this is a reallocation request that increases the size of a memory segment, the existing data is preserved and only the additional memory is zeroed.If the memory allocation fails, the allocation error handler (if one has been installed) will be called. If the error handler returns
TRUE
, another attempt will be made to allocate the requested memory; otherwise, it will be assumed that the allocation request cannot be satisfied.The function returns a pointer to the newly allocated memory on success, or
NULL
on failure.Some of the memory management macros described below evaluate to calls to this function.
This function allows the user to specify a memory allocation request failure handler. func will be called each time
C_mem_manage()
fails to allocate memory. This function may returnTRUE
to indicate that another attempt should be made to allocate the memory, orFALSE
to indicate that no additional memory can be made available.If func is
NULL
, any currently-installed handler is removed. SeeC_mem_manage()
for a description of the conditions under which func will be called.
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
NULL
for func. By default, there is no allocation hook installed.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.
- When a memory segment is being initially allocated, p_old will be
NULL
, p_new will be a pointer to the new segment, and len will be the length of the new segment.- When an existing memory segment is resized (reallocated), p_old will be the pointer to the original segment, p_new will be a pointer to the resized segment, and len will be the new length of the segment.
- When a memory segment is being freed, p_old will be a pointer to the segment that was freed, p_new will be
NULL
, and len will be 0.Never dereference the pointer p_old, as it no longer points to allocated memory.
This function is a default memory allocation hook function which writes an informational log message for each memory allocation using
C_log_info()
.
This function is simply an interface to the
free()
library function. If p is notNULL
, it is passed tofree()
. The function always returnsNULL
.
This function frees a
NULL
-terminated character string vector v, by first dereferencing and freeing each character array in turn, and then freeing the character pointer array itself.
This function is a variable-argument interface to the
free()
library function. The argument n specifies how many pointers (which must be of type void *) are being passed. Each subsequent non-NULL
argument is passed tofree()
.The function returns the number of non-
NULL
arguments that were processed.
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
FALSE
orTRUE
, respectively.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.
These macros are convenient replacements for the
malloc()
andcalloc()
library functions. They take as arguments the number of elements to allocate n, and the element's type (such as int or struct foobar). They return a properly cast pointer to the memory. Hence, the call:C_malloc(5, char *)would have a return value of type char **, that is, a pointer to 5 contiguous character pointers.
C_calloc()
is similar, except that it additionally zeroes the newly allocated memory. Both macros evaluate to expressions involving calls toC_mem_manage()
.
This macro is a convenient replacement for the
realloc()
library function. It takes as arguments a pointer p (of any type), the number of elements to allocate n (which is presumed to be of type size_t), and the element's type (such as int or struct foobar). It reallocates the memory beginning at p to the new size, returning a properly cast pointer to the resized memory. The macro evaluates to an expression involving a call toC_mem_manage()
.
These macros zero the specified memory.
C_zero()
zeroes the element of type type at location p.C_zeroa()
zeroes the n-element array of type type at location p.
These are additional convenience macros for freeing memory.
C_free()
frees the memory at p, which can be a pointer of any type. The macro is for use in place of calls to thefree()
library function. It evaluates to an expression involving a call toC_mem_free()
.
C_free_vec()
andC_va_free()
are identical toC_mem_free_vec()
andC_mem_va_free()
, respectively.
These are additional convenience macros for allocating memory.
C_new()
allocates space for one element of the specified type.C_newa()
allocates space for an array of n elements of the specified type. (These are reminiscent ofnew
andnew[]
in C++.)C_newb()
allocates space for an n-byte segment.C_newstr()
allocates space for a character array of length n. The variable n is assumed to be of type size_t.These macros all expand to expressions involving the
C_calloc()
macro, hence the returned memory will always be zeroed. All of these macros return properly-cast pointers to the newly allocated memory, so an explicit cast is not necessary. For example:char *s = C_newstr(45); struct foobar *item = C_new(struct foobar); int *scores = C_newa(20, int);
The following functions provide a simple memory pool mechanism. A memory pool is a block of memory allocated on the heap. The application may allocate smaller segments of memory from this pool. When these segments are no longer needed, they are all released at once by deallocating the pool.
The type c_mempool_t represents a memory pool.
These functions create and destroy memory pools.
C_mempool_create()
creates a new memory pool of the given size, returning a pointer to the newly created pool on success, orNULL
on failure (for example, if size is less than 1, or if the memory allocation failed). The memory in the pool is always initially zeroed.
C_mempool_destroy()
destroys the memory pool pool. All segments allocated from the pool should no longer be accessed, as they refer to memory that has been released.
This function allocates a memory segment size bytes in length from the memory pool pool. It returns a pointer to the segment on success, or
NULL
on failure (for example, if there is not enough unused memory in the pool to satisfy the request). The returned pointer will always be word-aligned, and the size of the segment returned will be rounded up to the next multiple of the word size.
This function returns the number of bytes available to be allocated from the memory pool pool.
These are convenience macros for allocating memory from a memory pool.
C_palloc1()
allocates space for one element of the given type.C_palloc()
allocates space for an array of n elements of the given type.C_pallocstr()
allocates space for a string of length n - 1. The variable n is assumed to be of type size_t.All of these macros return properly-cast pointers to the newly allocated memory, so an explicit cast is not necessary.
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.
This function opens the specified file and maps it into memory. If readonly is
TRUE
, the file will be mapped as read-only; otherwise both reading and writing will be allowed.The function returns a pointer to the new c_memfile_t structure on success, or
NULL
on failure. The functionC_memfile_base()
may be used to obtain a pointer to the beginning of the file in memory.
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
TRUE
on success, orFALSE
on failure.
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
TRUE
, the update is performed asynchronously, and the function returns immediately. Otherwise, it is performed synchronously and the function returns when the update is complete.The function returns
TRUE
on success, orFALSE
on failure.
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
TRUE
on success, orFALSE
on failure.
This function returns a pointer to the beginning of the memory occupied by the memory mapped file mf. It is implemented as a macro.
This function returns a pointer to the given offset offset in the memory mapped file mf. It is implemented as a macro.
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.
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
TRUE
if the user is a member of the named group, orFALSE
if not or upon failure (for example, if either argument isNULL
or an empty string).
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:
char *login
The current user's login name. char *fullname
The current user's full name. char *homedir
The current user's home directory. char *shell
The current user's login shell. uid_t uid
The process's real user ID. gid_t gid
The process's real group ID. uid_t euid
The process's effective user ID. gid_t egid
The process's effective group ID. char *hostname
The hostname. char *osname
The operating system name. char *osver
The OS version. char *osrel
The OS release. char *arch
The system's architecture type. pid_t pid
The process ID. pid_t ppid
The parent process ID. time_t stime
The system time at which this function was first called. char *term
The terminal line for the current process. 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.
These are convenience functions that retrieve some of the more interesting values from the static c_sysinfo_t structure.
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
C_system_get_homedir()
.The function returns
TRUE
on success, orFALSE
on failure.
This function generates an encrypted password using the standard UNIX
crypt()
function. The string passwd is encrypted using a randomly generated salt, and up to bufsz - 1 bytes of the resulting ciphertext (the first two bytes of which are the salt) are written to the buffer buf, which is unconditionallyNUL
-terminated.The function returns
TRUE
on success. On failure (for example, if passwd or buf isNULL
, or if bufsz is 0) the function returnsFALSE
.
This function validates a plaintext password against the encrypted form of the password using the standard UNIX
crypt()
routine. The string plaintext is encrypted using the first two bytes of ciphertext as the salt. If the resulting ciphertext matches ciphertext, the function returnsTRUE
. If the ciphertext strings do not match, or upon failure (for example, if either of the arguments isNULL
) it returnsFALSE
.
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 cbase/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.
These functions create and destroy bit strings.
C_bitstring_create
creates a new bit string nbits in length. The function returns a pointer to the newly created bit string on success. On failure, it returnsNULL
(for example, if nbits < 1).
C_bitstring_destroy()
destroys the bit string bs, freeing all memory associated with the bit string. It returnsTRUE
on success, orFALSE
on failure (for example, if bs isNULL
.)
These functions set and clear the bit at offset bit in the bit string bs.
C_bitstring_set()
sets the specified bit, andC_bitstring_clear()
clears it.The functions return
TRUE
on success, orFALSE
on failure (for example, if bs isNULL
or bit is out of range).
These functions set or clear a range of bits in the bit string bs.
C_bitstring_set_range()
sets all of the bits from offsets sbit to ebit, inclusive.C_bitstring_clear_range()
clears all of the bits from offsets sbit to ebit, inclusive.The functions return
TRUE
on success, orFALSE
on failure (for example, if bs isNULL
, if sbit or ebit is out of range, or if ebit < sbit).
These functions set or clear all of the bits in the bit string bs.
C_bitstring_set_all()
sets all bits in the bit string, andC_bitstring_clear_all()
clears all bits.The functions return
TRUE
on success, orFALSE
on failure (for example, if bs isNULL
).
These functions test bits in the bit string bs.
C_bitstring_isset()
determines if the bit at offset bit is set, returningTRUE
if so andFALSE
otherwise.C_bitstring_isclear()
determines if the bit at offset bit is cleared, returningTRUE
if so andFALSE
otherwise.The functions return
FALSE
upon failure (for example, if bs isNULL
or if bit is out of range).
This function compares the bit string bs1 to the bit string bs2. It returns
TRUE
if all of the bits that are set in bs1 are also set in bs2, andFALSE
otherwise.The function returns
FALSE
on failure (for example, if bs1 or bs2 isNULL
).
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.
These functions create and destroy arbitrarily-sized data buffers.
C_buffer_create()
creates a new data buffer bufsz bytes in length; the buffer's memory is initially zeroed. The function returns a pointer to the newly allocated buffer.
C_buffer_destroy()
destroys the buffer buf, freeing both the buffer memory and the c_buffer_t data structure itself.
This function resizes the buffer buf to a new size of newsz. bytes. The semantics are similar to that of
C_realloc()
: if the new size is larger than the previous size, the additional bytes are zeroed.The function returns buf on success. On failure (for example, if newsz is 0), it returns
NULL
.
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.
This macro evaluates to
TRUE
if c is a valid hexadecimal character (0 - 9, A - F, or a - f), orFALSE
otherwise.
These routines convert nibbles (values in the range 0 to 15) to and from an ASCII hexadecimal representation.
C_hex_tonibble()
converts the value v to a corresponding hexadecimal character: 0 - 9 or A - F. If the value of v is outside the acceptable range for a nibble, the function returnsNUL
.
C_hex_fromnibble()
converts the hexadecimal character c to a corresponding integer value between 0 and 15. If c is not a hexadecimal digit character (as determined by the application ofC_hex_isdigit()
), the function returns-1
.
These routines convert bytes (values in the range 0 to 255) to and from an ASCII hexadecimal representation.
C_hex_tobyte()
stores the two-character ASCII representation of the byte v at s. If the value of v is outside the acceptable range for a byte, the function returnsFALSE
; otherwise it returnsTRUE
.
C_hex_frombyte()
returns the numeric value of the byte whose ASCII representation is stored at s. If the two characters at s are not hexadecimal characters, the function returns-1
.
These routines convert arbitrary data to and from an ASCII hexadecimal representation.
C_hex_encode()
encodes len bytes beginning at data into the corresponding hexadecimal representation. The encoding is stored beginning at s, which must point to a buffer of at least len * 2 bytes.
C_hex_decode()
decodes len bytes of hexadecimal representation beginning at s The decoded data is stored beginning at data, which must point to a buffer of at least len / 2 bytes. Note that len must be a multiple of 2.The functions return
TRUE
on success, orFALSE
if passed invalid arguments or data.
The following functions are provided for the generation of random numbers.
In the single-threaded version of the library, this function seeds the random number generator (via a call to
srand()
) with the sum of the current value of the system clock and the current process ID. In the multi-threaded version of the library, this function is a no-op since the sequence is seeded automatically, as described below.
This function returns a random unsigned integer in the range [0, n-1] (via a call to
rand()
). In the multi-threaded version of the library, this function maintains a different random number sequence for each calling thread; the first call to this function by a thread seeds the random number sequence for that thread with the sum of the current value of the system clock and the thread ID of the calling thread.
The following functions parse and manipulate character arrays (strings).
This function replaces all non-printable characters in the string s with the fill character fillc.
The function returns s on success, or
NULL
on failure (for example, if s isNULL
or fillc isNUL
).
This function converts all uppercase characters in the string s to lowercase. It returns s.
This function converts all lowercase characters in the string s to uppercase. It returns s.
This function determines if the string s is composed strictly of numeric characters (0 - 9).
The function returns
TRUE
if s is numeric andFALSE
otherwise.
This function determines if the string s begins with the string prefix. It returns
TRUE
if prefix is a prefix of s andFALSE
otherwise.
This function determines if the string s ends with the string suffix. It returns
TRUE
if suffix is a suffix of s andFALSE
otherwise.
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.
This function is a higher-level interface to the
strtok_r()
library function. It splits the string s into a series of “words,” breaking words on any combination of characters from the string sep, as does thestrtok_r()
function.On success, the number of words parsed is stored at len if it is non-
NULL
, and the words are returned as aNULL
-terminated string vector, which is dynamically allocated and must eventually be freed by the caller. On failure,NULL
is returned.
This function is identical to the
strdup()
library function. It duplicates the string s in memory and returns a pointer to the new copy. It is provided becausestrdup()
is not specified by the POSIX.1 standard, and thus may not be available on all systems. This function should be used in place ofstrdup()
as it allocates memory usingC_newstr()
rather than by callingmalloc()
directly.
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
NULL
on failure.
This function searches the string s for the first occurrence of any character in termin and replaces it with
NUL
. If no terminator character is found, the string is left unmodified. The function may be used to “chop” unneeded text from the end of a string (such as a CR+LF pair at the end of a line read from a socket or DOS file).The function returns s.
This function is a non-destructive string tokenizer; it differs from
strtok_r()
in that the source string is not modified. The function searches for the next token in s that does not consist of any characters in delim. The argument ctx is used to store the tokenizer context. If s isNULL
, tokenization resumes from the last character analyzed; otherwise, it starts at the beginning of s.The function stores the length of the token at len and returns a pointer to the beginning of the token. If no token is found, or on error (for example, if delim, ctx, or len is
NULL
) the function returnsNULL
.The following code snippet extracts words from a sentence:
const char *text = "How now, brown cow?"; const char *ctx, *word; uint_t len; for(word = C_string_tokenize(text, " .,?!", &ctx, &len); word; word = C_string_tokenize(NULL, " .,?!", &ctx, &len)) { printf("Word found: %.*s\n", len, word); }
This function performs a safe string copy. At most bufsz - 1 characters from s are copied to buf; the string buf is unconditionally
NUL
-terminated.The function returns
TRUE
if the entire string s was copied to buf; otherwise it returnsFALSE
.
This is a variable argument list version of the
C_string_copy()
function. It copies the first string into buf, and then concatenates all of the remaining strings (if any) onto the text already in buf. At most bufsz - 1 total bytes are copied to buf; the string buf is unconditionallyNUL
-terminated.The function returns
TRUE
if all of the strings were completely copied to buf; otherwise it returnsFALSE
.
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
NUL
-terminated.The function returns
TRUE
if the entire string s was concatenated onto buf; otherwise it returnsFALSE
.
This is a variable argument list version of the
C_string_concat()
function. It concatenates each string onto the text that is already in buf, without overflowing buf. The resulting string will be at most bufsz - 1 characters in length, and will be unconditionallyNUL
-terminated.The function returns
TRUE
if all of the strings were completely copied to buf; otherwise it returnsFALSE
.
This function quicksorts the string vector v. It performs a call to the
qsort()
library function to accomplish the alphabetical sorting. The argument len specifies the number of elements in v.The function returns v on success, or
NULL
on failure.
This function accepts a pointer to an integer, len, and a
NULL
-terminated list of char * arguments. It creates a string vector from its arguments, storing the number of strings in the vector at len if it is non-NULL
.The function returns the newly created vector on success, or
NULL
on failure.
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-
NULL
. The function returns the newly created vector on success, orNULL
on failure.
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
0
on failure (for example, if s isNULL
or empty, or if modulo is 0).
This function is a wrapper for the
strcmp()
library function. It typecasts s1 and s2 to char * and passes them tostrcmp()
, returning that function's return value.This function is passed to the
qsort()
library function by routines which use that function to sort strings. It is provided here for that purpose.
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.
These functions create and destroy string buffers, respectively.
C_strbuffer_create()
creates a new, empty string buffer that is bufsz bytes in size. It returns a pointer to the newly created string buffer on success, orNULL
on failure (for example, if bufsz is less than 1).
C_strbuffer_destroy()
destroys the string buffer sb, deallocating all memory associated with the buffer. It returnsTRUE
on success, orFALSE
on failure (for example, if sb isNULL
).
This function clears the string buffer sb. The buffer is reset so that it contains an empty string. The function returns
TRUE
on success andFALSE
on failure (for example, if sb isNULL
).
This function copies the string s into the string buffer sb, replacing any text currently in the buffer. The function returns
TRUE
on success. If the buffer could not accommodate the entire string, or upon failure (if sb or s isNULL
) the function returnsFALSE
.
This function concatenates the string s onto the text in the string buffer sb. The function returns
TRUE
on success. If the buffer could not accommodate the entire string, or upon failure (if sb or s isNULL
) the function returnsFALSE
.
This function appends a formatted string onto the text in the string buffer sb; the behavior is identical to that of the
sprintf()
library function. The function returnsTRUE
if the entire formatted string was successfully written. If the buffer could not accommodate the entire string, or upon failure (for example, if sb or format isNULL
) the function returnsFALSE
.
This function appends the single character c onto the text in the string buffer sb. The function returns
TRUE
if the character was successfully written, orFALSE
if the buffer is already full or upon failure (for example, if sb isNULL
or c isNUL
).
This function (which is implemented as a macro) returns the size of the string buffer sb.
This function returns the length of the string in the string buffer sb.
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
NUL
-terminated.
The following functions parse and format time values.
This function is a higher-level interface to the
strftime()
library function. It formats the given time t (or the current time, if t is 0) according to the format string format. Up to bufsz bytes of the formatted text are written to the string buf.The function returns
TRUE
on success orFALSE
on failure.
This function is a higher-level interface to the
strptime()
library function. It parses a string representation s of a date/time that is expected to be in the specified format. It returns the parsed time as a time_t value on success, or(time_t)0
on failure.
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.
This function creates a new timer. It returns a pointer to the new timer.
This function resets and starts the specified timer. To start a timer without resetting it, use the
C_timer_resume()
function. Calling this function on a timer that is already running has no effect.
This function stops the specified timer. A stopped timer can be resumed with the
C_timer_resume()
function. Calling this function on a timer that is not running has no effect.
This function resumes the specified timer. Calling this function on a timer that is already running has no effect.
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.
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.
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.
This function returns the system time at which the specified timer was created. It is implemented as a macro.
This function returns
TRUE
if timer is currently running, andFALSE
otherwise. It is implemented as a macro.
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.
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
NULL
.
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
TRUE
on success, orFALSE
on failure (for example, if v or s isNULL
).
This function signifies that no more strings will be stored in the vector v. The vector is
NULL
-terminated, the length of the vector is stored at len if it is notNULL
, and all memory associated with the vector other than the backbone itself, including the c_vector_t structure, is deallocated.The function returns the vector as a pointer to an array of character pointers on success, or
NULL
upon failure (for example, if v isNULL
).
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.
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 cbase/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()
.
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()
.
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()
.
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.
These functions create and destroy b-trees.
C_btree_create()
creates a new, empty b-tree of order order (which must be at least 2) and returns a pointer to the new tree on success, orNULL
on failure.
C_btree_destroy()
frees all memory associated with the b-tree tree. If a destructor has been specified for the b-tree, all user data is destroyed as well using that destructor.
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
C_btree_delete()
orC_btree_destroy()
; a pointer to the data element being destroyed will be passed to the destructor. A value ofNULL
may be passed to remove a previously installed destructor.There is no default destructor; if no destructor is set for the b-tree, user data will not be automatically freed.
The function returns
TRUE
on success, orFALSE
on failure (for example, if tree isNULL
).
These functions store data in and restore data from the b-tree tree.
C_btree_store()
stores a new datum with the specified key and data value data in the b-tree. The function returnsTRUE
on success orFALSE
on failure (for example, if tree or data isNULL
, or if the b-tree already contains a datum with the specified key).
C_btree_restore()
returns a pointer to the data value of the datum whose key is key in the b-tree. If an element with the specified key does not exist in the tree, or upon failure (for example, if key is0
or tree isNULL
), the function returnsNULL
.
This function deletes the data element with the specified key from the b-tree tree. It returns
TRUE
on success orFALSE
on failure (for example, if tree isNULL
, if key is0
, or if an element with the specified key does not exist in the b-tree).
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
TRUE
as long as traversal should continue; if it returnsFALSE
, or when the entire tree has been traversed, this function exits, returningFALSE
in the former case, orTRUE
in the latter.
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.
These functions create and destroy linked lists.
C_linklist_create()
allocates memory for a new, empty linked list and returns a pointer to the new list on success, orNULL
on failure.
C_linklist_destroy()
frees all memory associated with the linked list l. If a destructor has been specified for the list, all user data is destroyed as well using that destructor.
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
C_linklist_delete()
,C_linklist_delete_r()
, orC_linklist_destroy()
; a pointer to the data element being destroyed will be passed to the destructor. A value ofNULL
may be passed to remove a previously installed destructor.There is no default destructor; if no destructor is set for the linked list, user data will not be automatically freed.
The function returns
TRUE
on success, orFALSE
on failure (for example, if l isNULL
).
These functions store data in and restore data from the linked list l.
C_linklist_store()
creates a new link which points to data and stores it in the linked list l at the current position of the list's link pointer (seeC_linklist_move()
). Note that the data at data is not duplicated; only the pointer is copied into the linked list. The new link is always inserted before the link that the link pointer points to. If the link pointer is set toNULL
, then the new link is inserted after the tail of the list, and hence becomes the new tail. The function returnsTRUE
on success orFALSE
on failure (for example, if l or data isNULL
).
C_linklist_restore()
returns a pointer to the data element of the link at the current position of l's link pointer. On failure (for example, if l isNULL
, or if the link pointer is pointing past the end of the list) the function returnsNULL
.
These are reentrant versions of the functions
C_linklist_store()
andC_linklist_restore()
described above. They both accept an additional argument, p, which is the address of the link pointer to be used.
This function deletes the link at the linked list l's link pointer. It returns
TRUE
on success orFALSE
on failure (for example, if l isNULL
or if the link pointer points past the end of the list). The link pointer is adjusted to point to the link following the link that was deleted (or toNULL
if the tail was deleted).
This is the reentrant version of the function
C_linklist_delete()
described above. It accepts an additional argument, p, which is the address of the link pointer to be used.
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
TRUE
. Otherwise, it returnsFALSE
.
This is the reentrant version of the function
C_linklist_search()
described above. It accepts an additional argument, p, which is the address of the link pointer to be used.
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.
C_linklist_move()
moves l's link pointer to the location specified by where, which can have one of the following values:C_LINKLIST_HEAD
,C_LINKLIST_TAIL
,C_LINKLIST_NEXT
,C_LINKLIST_PREV
. These values move the link pointer to the head, tail, next link, or previous link in the list, respectively. Calls to move to the head or to the tail always succeed, returningTRUE
(unless l isNULL
). Calls to move to the next or previous link returnTRUE
if a link exists in the specified direction, orFALSE
if such movement would move the pointer off either end of the list (or if l isNULL
).The link pointer may become
NULL
as a result of this call; this signifies that it is pointing just past the end of the linked list, and therefore subsequent calls toC_linklist_restore()
will returnNULL
. This is useful for traversing lists.The four convenience functions
C_linklist_move_head()
,C_linklist_move_tail()
,C_linklist_move_next()
, andC_linklist_move_prev()
automatically pass the appropriate values for where toC_linklist_move()
. They are implemented as macros.The following example illustrates a
for
loop that iterates through a linked list of strings: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);
These are the reentrant versions of the
C_linklist_move()
family of functions described above. They each accept an additional argument, p, which is the address of the link pointer to be used.
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
TRUE
if it is andFALSE
otherwise.
These are the reentrant versions of the functions
C_linklist_ishead()
andC_linklist_istail()
described above. They each accept an additional argument, p, which is the address of the link pointer to be used.
These functions (which are implemented as macros) return the head and tail link, respectively, of the linked list l. A return value of
NULL
indicates that the list is empty.
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.
These functions create and destroy queues.
C_queue_create()
allocates memory for a new, empty queue and returns a pointer to the new queue on success, orNULL
on failure.
C_queue_destroy()
frees all memory associated with the queue q. If a destructor has been specified for the queue, all user data is destroyed as well using that destructor.
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
C_queue_destroy()
; a pointer to the data element being destroyed will be passed to the destructor. A value ofNULL
may be passed to remove a previously installed destructor.There is no default destructor; if no destructor is set for the queue, user data will not be automatically freed.
The function returns
TRUE
on success, orFALSE
on failure (for example, if q isNULL
).
These functions enqueue data onto and dequeue data from the queue q.
C_queue_enqueue()
enqueues data as a new item at the end of the queue. It returnsTRUE
on success, orFALSE
on failure (for example, if q or data isNULL
).
C_queue_dequeue()
dequeues an item from the beginning of the queue, returning a pointer to the dequeued data on success, orNULL
on failure (for example, if q isNULL
or empty).
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.
These functions create and destroy stacks.
C_stack_create()
allocates memory for a new, empty stack and returns a pointer to the new stack on success, orNULL
on failure.
C_stack_destroy()
frees all memory associated with the stack s. If a destructor has been specified for the stack, all user data is destroyed as well using that destructor.
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
C_stack_destroy()
; a pointer to the data element being destroyed will be passed to the destructor. A value ofNULL
may be passed to remove a previously installed destructor.There is no default destructor; if no destructor is set for the stack, user data will not be automatically freed.
The function returns
TRUE
on success, orFALSE
on failure (for example, if s isNULL
).
These functions push data onto and pop data off the stack s.
C_stack_push()
pushes data onto the top of the stack. It returnsTRUE
on success, orFALSE
on failure (for example, if s or data isNULL
).
C_stack_pop()
pops the topmost item off the stack. It returns the popped data on success, orNULL
on failure (for example, if s isNULL
or empty).
This function returns the topmost item on the stack s, without removing the item from the stack as does
C_stack_pop()
. A return value ofNULL
indicates that the stack is empty.
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.
These functions create and destroy hashtables, respectively.
C_hashtable_create()
creates a new, empty hashtable with the specified number of buckets. It returns a pointer to the new hashtable structure on success, orNULL
on failure (for example, if buckets is 0). The larger the value for buckets, the more efficient a table lookup will be; values less than 10 are generally not useful.
C_hashtable_destroy()
frees all memory associated with the hashtable h. If a destructor has been specified for the hash table, all user data is destroyed as well using that destructor.
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
C_hashtable_delete()
orC_hashtable_destroy()
; a pointer to the data element being destroyed will be passed to the destructor. A value ofNULL
may be passed to remove a previously installed destructor.There is no default destructor; if no destructor is set for the hashtable, user data will not be automatically freed.
The function returns
TRUE
on success, orFALSE
on failure (for example, if h isNULL
).
These functions store data in and restore data from the hashtable h.
C_hashtable_store()
creates a new tag with the given key and data, hashes key, and uses the hash value as an index into the array of linked lists in the hashtable. It then inserts the tag at the head of the appropriate linked list. Note that this function does not actually copy data into the hashtable; it only stores the pointer data in the appropriate linked list in the hashtable. The function returnsTRUE
on success, orFALSE
on failure (for example, if h or key isNULL
).
C_hashtable_restore()
searches the hashtable for a tag whose key matches key. It does this by hashing key, selecting the appropriate linked list in the hashtable, and then doing a linear search in that linked list to find the desired element. The function returns a pointer to the matching tag's data field if a match is found, orNULL
if no match was found or if h or key isNULL
.
This function searches for a tag whose key matches key in the same manner as
C_hashtable_restore()
, and removes the matching tag from the table.The function returns
TRUE
on success, orFALSE
if no match was found or if h or key isNULL
.
This function returns all of the keys in the hashtable h as a string vector. If len is not
NULL
, the length of the vector is stored at len. If h isNULL
, the function returnsNULL
. The returned vector is dynamically allocated and must eventually be freed by the caller.
This function allows the user to specify an alternate hashing function func. The default hashing function is
C_string_hash()
. func() must accept a string and a modulo value and return an unsigned integer in the range [0,modulo
- 1]. This function stores the pointer func() in a static area within the library for use in subsequent calls to the hashtable functions. The function returnsTRUE
on success, orFALSE
if func() isNULL
.
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.
These functions create and destroy dynamic arrays.
C_darray_create()
creates a new dynamic array for elements of size elemsz bytes. The argument resize_rate specifies the rate at which the array will be resized. Specifically, when space in the dynamic array is exhausted, it will be resized to make space for resize_rate * 8 more elements. Larger values for resize_rate will increase performance (since memory reallocation will be less frequent), but will decrease the efficiency with which memory is used. The function returns a pointer to the new dynamic array on success, orNULL
on failure (for example, if elemsz is 0 or if resize_rate is less than 1 or greater thanC_DARRAY_MAX_RESIZE
.
C_darray_destroy()
frees all memory associated with the dynamic array a. This includes memory occupied by data stored in the array.
These functions store data in and restore data from the dynamic array a.
C_darray_store()
copies the element pointed to by data (which is assumed to be of the correct size for this dynamic array) into the array a, resizing the array if necessary. The caller will have to typecast data to void * before passing it to this function. The index into the array at which the element was stored is stored at index if it is notNULL
. The function returns a pointer to the beginning of the element within the array on success, orNULL
on failure (for example, if a or data isNULL
). The caller will have to typecast this return value back to the correct type before accessing its contents. If the caller does not need to modify the element immediately after it is stored, it may choose to ignore the return value and only remember the value at index for future retrievals.
C_darray_restore()
locates the element at the index index within the array a, returning a pointer to the beginning of the element on success, orNULL
on failure (for example, if the specified index points to an “empty” element, if index is out of range, or if a isNULL
).
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_restore()
using this index will returnNULL
until the free slot is refilled.
These functions read dynamic arrays from and write dynamic arrays to the file specified by path.
C_darray_load()
reads a dynamic array from a file, and returns a pointer to the loaded array on success, orNULL
if the load failed (for example, if path does not exist or is not readable).
C_darray_save()
writes the dynamic array a to a file, returningTRUE
on success, orFALSE
on failure (for example, if a isNULL
or path could not be opened for writing). If the write fails, a partially-written file may exist as a result of this call.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.
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,
NULL
is returned (for example, if a isNULL
). If there are no deleted elements in a, the function returns a unmodified. Note that defragmentation of the array results in a shifting of elements within it; therefore references to particular elements via void * pointers or index offsets may become invalidated.
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
index
of the element within the dynamic array, and the pointer hook (which can be used to pass around state information). The iter() function is expected to returnTRUE
as long as traversal should continue; if it returnsFALSE
, or when the entire array has been traversed, this function exits, returningFALSE
in the former case, orTRUE
in the latter.
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.
These functions create and destroy dynamic strings.
C_dstring_create()
creates a new dynamic string with the specified block size blocksz. The block size determines the rate at which memory will be reallocated as the string grows and shrinks. The larger the block size, the less frequently memory reallocation will take place, but the more inefficient memory use will be. The function returns a pointer to the new dynamic string on success, orNULL
on failure (for example, if blocksz is less thanC_DSTRING_MIN_BLOCKSZ
). Specifically, memory will be allocated and deallocated in increments of blocksz bytes. Therefore, if frequent writes of long strings are anticipated, blocksz should be sufficiently large, and if infrequent writes of long strings or frequent writes of short strings are anticipated, blocksz should be smaller.
C_dstring_destroy()
deallocates all memory associated with the dynamic string d, not including the string itself. This string isNUL
terminated and the function returns a pointer to it. On failure,NULL
is returned (for example, if d isNULL
).
These functions write data to the dynamic string d at the current location of the string's seek pointer.
C_dstring_putc()
writes the single character c (which cannot beNUL
),C_dstring_puts()
writes the string s, andC_dstring_puts_len()
writes exactly len characters from the string s. All three functions update the seek pointer to point immediately past the last character written. If the data to be written would go past the end of the string, the string is automatically resized to accommodate it.The functions return
TRUE
on success, orFALSE
on failure (for example, if d or s isNULL
, if len is less than 1, or if c isNUL
).
These functions read data from the dynamic string d starting at the current location of the seek pointer.
C_dstring_getc()
reads a single character and moves the seek pointer forward one character. The function returns the character read on success, orNUL
if the seek pointer is already at the end of the string or if d isNULL
.
C_dstring_gets()
reads characters into s until len - 1 characters have been read or the termin character is encountered, whichever occurs first. The buffer s is unconditionallyNUL
terminated; if the terminator character is encountered, it is discarded and replaced byNUL
in s. The seek pointer is updated to point immediately past the last character read. The function returns s on success, orNULL
on failure (for example, if the seek pointer is already at the end of the string, if d isNULL
, or if len is 0).
C_dstring_seek()
moves the seek pointer for the dynamic string d. The argument where specifies the relative or absolute number of characters by which the pointer should be moved. The argument whence specifies how the where argument should be interpreted. A value ofC_DSTRING_SEEK_REL
signifies that where is a relative offset from the seek pointer's current position (and may be positive or negative). A value ofC_DSTRING_SEEK_ABS
specifies that where is an absolute offset from the beginning of the dynamic string (and must be positive). A value ofC_DSTRING_SEEK_END
specifies that where is an absolute offset from the end of the dynamic string toward the beginning (and must be positive as well). The function returnsTRUE
on success, orFALSE
on failure (for example, if the new seek position would be out of range, or if d isNULL
, or if the value of whence is invalid).
C_dstring_ungetc()
moves the seek pointer back one character,C_dstring_rewind()
moves it to the beginning of the dynamic string, andC_dstring_append()
moves it to the end. These functions are implemented as macros, and their return values are the same as those for theC_dstring_seek()
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
TRUE
on success, orFALSE
on failure (for example, if d isNULL
or if size is greater than the current length of the dynamic string).
These functions read dynamic strings from and write dynamic strings to the file specified by path.
C_dstring_load()
reads a dynamic string into memory. The meaning of blocksz is the same as inC_dstring_create()
; it specifies the resize rate for the new string. On success, the function returns a pointer to the loaded dynamic string. On failure, it returnsNULL
(for example, if blocksz is greater thanC_DSTRING_MAX_BLOCKSZ
, if d isNULL
, or if path does not exist or could not read).
C_dstring_save()
writes the dynamic string d to a file. It returnsTRUE
on success, orFALSE
on failure (for example, if d isNULL
or if path could not be written). If the save fails, a partially written file may exist as a result of this call.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.
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 cbase/xml.h.
The type c_xml_document_t represents an XML document, and the type c_xml_element_t represents an XML element.
These functions create and destroy XML documents.
C_xml_document_create()
creates a new, empty XML document with the specified encoding. Currently only the ASCII and UTF-8 encodings are supported, therefore `us-ascii' or `utf-8' should be passed as the value of encoding. The function returns a pointer to the newly created c_xml_document_t structure.
C_xml_document_destroy()
destroys the XML document doc. All of the elements in the document are recursively destroyed, and then the document itself is destroyed. All memory associated with the document is deallocated. The function returnsTRUE
on success, orFALSE
on failure (for example, if doc isNULL
).
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
).
These functions set and get the root element of the XML document doc.
C_xml_document_set_root()
sets the root element of the document doc to root. The argument root may beNULL
to effectively “empty” the document. The function returnsTRUE
on success orFALSE
on failure (for example, if doc isNULL
).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_xml_element_destroy_recursive()
on the old root element to reclaim the memory used by that tree before setting a new root element.
C_xml_document_get_root()
returns the root element of the document doc, orNULL
if the document is empty.
These functions set and get the content for the XML element elem.
C_xml_element_set_content()
sets the content of elem to content. The string content is duplicated in memory, so it does not need to be dynamically allocated by the caller. Any existing content for elem is removed and deallocated. The argument content may beNULL
to delete any existing content. The function returnsTRUE
on success orFALSE
on failure (for example, if elem isNULL
).
C_xml_element_get_content()
returns the content for the XML element elem, orNULL
if the element has no content or upon failure (for example, if elem isNULL
).
These functions set and get parameters for the XML element elem.
C_xml_element_set_param()
sets the parameter named param to the value value in the element elem, replacing any existing value for that parameter. The function returnsTRUE
on success, orFALSE
on failure (for example, if elem, param, or value isNULL
).
C_xml_element_get_param()
gets the value of the parameter named param in the element elem. It returns the value of the parameter on success, orNULL
on failure (for example, if a parameter named param does not exist in the element, or if elem or param isNULL
).
These functions delete parameters from the XML element elem.
C_xml_element_delete_param()
deletes the parameter named param from the element elem.C_xml_element_delete_params()
deletes all parameters from the element elem.These functions return
TRUE
on success orFALSE
on failure (for example, if a parameter named param does not exist in the element, or if elem or param isNULL
).
These functions return a list of child elements of the specified XML element parent.
C_xml_element_get_children()
returns a list of the child elements of the element parent.C_xml_element_get_children_named()
returns a list of the child elements of the element parent that are named name.On success, the functions return a dynamically allocated, possibly empty,
NULL
-terminated array of pointers to c_xml_element_t structures. This array must be eventually freed by the caller via a call toC_free_vec()
. On failure, they returnNULL
(for example, if parent or name isNULL
).
This function returns the first child element of the element parent, or
NULL
if parent has no children or on failure (for example if parent isNULL
).
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
TRUE
on success, orFALSE
on failure (for example, if parent or elem isNULL
, or if one of the constraints described above is violated).
This function removes the specified element elem from the parent element parent. The element tree rooted at elem is destroyed. The function returns
TRUE
on success, orFALSE
on failure (for example, if parent or elem isNULL
, or if elem is not a child of parent).
These functions remove multiple child elements from the parent element parent. The element tree rooted at each removed child element is destroyed.
C_xml_element_remove_children()
removes all children from the parent element elem.C_xml_element_remove_children_named()
removes all children from the parent element elem that are named name.These functions return
TRUE
on success, orFALSE
on failure (for example, if parent or name isNULL
).
These functions read and write XML documents to and from files.
C_xml_document_read()
reads XML data from the file fp into the (presumably empty) document doc. It returnsTRUE
on success, orFALSE
on failure (for example, if fp or doc isNULL
, if an I/O error occurred, or if the XML parser reported an error).
C_xml_document_write()
writes the XML document doc to the file fp. It returnsTRUE
on success, orFALSE
on failure (for example, if doc or fp isNULL
, or if an I/O error occurred).
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 cbase/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.
These functions initialize and shut down the real-time scheduler.
C_sched_init()
initializes the real-time scheduler. The current disposition of the real-time signalSIGRTMIN
is saved in static storage within the library, and is then reassigned to call the scheduler's internal event handler. The function returnsTRUE
on success, orFALSE
on failure (for example, if the scheduler has already been initialized).
C_sched_shutdown()
shuts down the real-time scheduler. The scheduler is deactivated, and the disposition of the real-time signalSIGRTMIN
is restored. All events being managed by this scheduler are then deactivated via calls toC_sched_event_deactivate()
. The function returnsTRUE
on success, orFALSE
on failure (for example, if the scheduler was not initialized).
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.
These functions create and destroy scheduler events.
C_sched_event_create()
creates a new scheduler event. The date/time specification string is passed as timespec. The flag once specifies whether the event should fire once or multiple times; if once isTRUE
, the scheduler will deactivate the event via a call toC_sched_event_deactivate()
immediately after the first time it fires. The pointer hook may be used to attach arbitrary user data to the event structure; this data may be retrieved using the functionC_sched_event_data()
, described below. The argument handler is a pointer to a handler function that will be invoked when the event fires; the event structure itself, and the time at which the event fired (as a time_t value) will be passed to the handler upon its invocation. The argument destructor is a pointer to an optional destructor function which should be called when this event is deactivated via a call toC_sched_event_deactivate()
. Either or both of handler and destructor may beNULL
, but aNULL
value for handler is not useful. The parameter id is a numeric ID to assign to the event.The function returns a pointer to the newly created event structure on success, or
NULL
on failure (for example, if timespec is an invalid specification string).
C_sched_event_destroy()
destroys the scheduler event e. All memory associated with the event (not including any user-supplied data) is deallocated. The function returnsTRUE
on success, orFALSE
on failure (for example, if e isNULL
).
These functions activate and deactive the scheduler event e.
C_sched_event_activate()
activates the event e by adding it to the scheduler's event list. The function returnsTRUE
on success, orFALSE
on failure (for example, if e isNULL
, or is already in the scheduler's event list).
C_sched_event_deactivate()
deactivates the event e by removing it from the scheduler's event list. If a destructor function was specified for this event when it was created viaC_sched_event_create()
, that function is invoked with e as an argument. The function returnsTRUE
on success, orFALSE
on failure (for example, if e isNULL
, or is not in the scheduler's event list).
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
NULL
on failure.
This function (which is implemented as a macro) returns the user-data for the scheduler event e.
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 cbase/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.
This function sends the file descriptor fd over the stream pipe sd. It returns
TRUE
on success orFALSE
on failure.
This function receives a file descriptor over the stream pipe sd, storing the received descriptor at fd. It returns
TRUE
on success orFALSE
on failure.
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.
These functions create and destroy semaphores.
C_sem_create()
initializes a new semaphore with the specified symbolic name and initial value of value. The POSIX standard specifies that name must begin with a slash character (`/
') and may contain no other slash characters. For best portability, the length of name should not exceed 14 characters. The initial value must be an integer between 1 andC_SEM_MAX_VALUE
.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
NULL
on failure.
C_sem_destroy()
destroys the semaphore sem. If no other processes are using this semaphore, the underlying POSIX semaphore object is destroyed.
These functions wait on the semaphore sem.
C_sem_wait()
waits for the semaphore, blocking the calling process or thread until the semaphore is acquired.C_sem_trywait()
attempts to acquire the semaphore, returning immediately if it cannot be locked.Both functions return
TRUE
if the semaphore was successfully acquired andFALSE
otherwise.
This function posts the semaphore sem. It returns
TRUE
if the semaphore was successfully released andFALSE
otherwise.
This function (which is implemented as a macro) returns the symbolic name of the semaphore sem.
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.
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.
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 (`
/
') and may contain no other slash characters. For best portability, the length of name should not exceed 14 characters. The size of the segment will be rounded up to the nearest system page size as reported bysysconf()
.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
NULL
on failure. The functionC_shmem_base()
may be used to obtain a pointer to the shared memory block itself.
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.
This function (which is implemented as a macro) returns a pointer to the base of the shared memory segment mem.
This function (which is implemented as a macro) returns the size, in bytes, of the shared memory segment mem.
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
sysconf()
.The function returns
TRUE
on success orFALSE
on failure.
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.
This function returns a string representation of the signal specified by sig, or
NULL
if sig does not refer to a known signal.
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.
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
C_tty_unraw()
.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_ENOTTY
fd does not refer to a terminal. C_ETCATTR
The call to tcgetattr()
ortcsetattr()
failed.
This function undoes the changes to the attributes of the terminal associated with the file descriptor fd that resulted from the latest call to
C_tty_raw()
. The terminal attributes are restored to what they were just before the call toC_tty_raw()
.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_ENOTTY
fd does not refer to a terminal. C_ETCATTR
The call to tcsetattr()
failed.C_EINVAL
There was no previous call to C_tty_raw()
.
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
C_tty_restore()
. The function is useful when a terminal's attributes must be modified from their original values temporarily by a program, or when the attributes of one terminal must be copied to another terminal (or to a pseudoterminal).The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_ENOTTY
fd does not refer to a terminal. C_ETCATTR
The call to tcgetattr()
failed.
This function restores the terminal attributes saved with the latest call to
C_tty_store()
, applying them to the terminal associated with the file descriptor fd.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_ENOTTY
fd does not refer to a terminal. C_ETCATTR
The call to tcgetattr()
failed.C_EINVAL
There was no previous call to C_tty_store()
.
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
(ICRNL | IXON | IXOFF)
, the output flag word is set to(OPOST)
, the control flag word is set to(CREAD | HUPCL)
, and the functions flag word is set to(ECHO | ECHOE | ECHOK | ICANON | ISIG | IEXTEN)
. The control characters are set to the following ASCII values:VEOF
= 4,VEOL
= 28,VERASE
= 8,VINTR
= 21,VKILL
= 3,VQUIT
= 255,VSUSP
= 255,VSTART
= 17,VSTOP
= 19.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_ENOTTY
fd does not refer to a terminal. C_ETCATTR
The call to tcsetattr()
failed.
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.
This function allocates a pseudoterminal from the system. On success, it returns a pointer to the new c_pty_t structure. The functions
C_pty_master_fd()
andC_pty_slave_fd()
, described below, can be used to obtain the file descriptors for the corresponding devices. On failure, the function returnsNULL
and setsc_errno
to one of the following values:
C_EGETPTY
The call to grantpt()
,unlockpt()
, orptsname()
(System V) oropenpty()
(BSD) failed.C_EOPEN
The call to open()
failed.C_EIOCTL
The call to ioctl()
failed.
This function closes the master and slave devices for the pseudoterminal pty and deallocates the data structure at pty. The function returns
TRUE
on success, orFALSE
on failure (for example, if pty isNULL
).
These functions (which are implemented as macros) return the file descriptors for the master and slave device, respectively, of the pseudoterminal pty.
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 cbase/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 cbase/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.
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
C_NET_TCP
,C_NET_UDP
, orC_NET_UNKNOWN
. If the value at type isC_NET_UNKNOWN
, it is modified to reflect the actual type of the service found;C_NET_OTHER
is stored at type if the service is neither TCP- nor UDP-based.On success, the function returns the port number of the named service. On failure, it returns
-1
and setsc_errno
to one of the following values:
C_EINVAL
name or type is NULL
, or the value at type is invalid.C_ESVCINFO
The call to getservbyname_r()
failed.
This function is the inverse of
C_net_get_svcport()
. It attempts to find a service on the specified port of the specified type, and writes up to bufsz - 1 bytes of the service's name at buf. The buffer is unconditionallyNUL
-terminated. If the value at type isC_NET_UNKNOWN
, it is modified to reflect the actual type of the service:C_NET_OTHER
is stored at type if the service is neither TCP- nor UDP-based.The function returns
TRUE
if the service was found. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
type or buf is NULL
, bufsz is 0, or the value at type is invalid.C_ESVCINFO
The call to getservbyport_r()
failed.
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
NUL
-terminated.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
ipaddr is NULL
or is an empty string, or buf isNULL
.C_EADDRINFO
The call to inet_addr()
orgethostbyaddr_r()
failed.
This function obtains the address of the local host in one or more formats. If addr is not
NULL
, up to bufsz - 1 bytes of the local host's canonical DNS name are written at addr, and the buffer is unconditionallyNUL
-terminated. If ipaddr is notNULL
, up to bufsz - 1 bytes of the host's address in the form of a dot-separated IP address are written at ipaddr, and the buffer is unconditionallyNUL
-terminated. Finally, if ip is notNULL
, the local host's packed IP address is stored at ip.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
addr, ipaddr, and ip are all NULL
, or bufsz is 0.C_EADDRINFO
The call to gethostbyname_r()
failed.
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.
These two functions create and destroy sockets.
C_socket_create()
creates a new socket of the specified type. The value of type may be eitherC_NET_TCP
(for reliable, connection-based stream sockets) orC_NET_UDP
(for unreliable, connectionless or connection-based datagram sockets). The function returns the newly created c_socket_t structure on success. On failure, it returnsNULL
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
, or the value of type is invalid.C_ESOCKET
The call to socket()
failed.C_socket_destroy()
shuts down and closes the socket s, freeing all memory associated with the socket, including the c_socket_t structure. The function will only destroy the socket if it is created but not connected or listening, or if it has been shut down via a call toC_socket_shutdown()
. It returnsTRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
.C_EBADSTATE
The socket is not in a created or shut down state.
These functions are static variants of
C_socket_create()
andC_socket_destroy()
, respectively. They do not perform any allocation or deallocation of c_socket_t structures, but rather operate on pointers to preallocated structures.
C_socket_create_s()
initializes the socket structure at s as a new socket. It returnsTRUE
on success andFALSE
on failure.
C_socket_destroy_s()
disposes the socket at s. It returnsTRUE
on success andFALSE
on failure.
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_accept()
. The function may also be used with a multicast UDP socket to notify the operating system that the socket should only receive multicast datagrams that are destined for the specified port. The function returnsTRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
.C_EBADSTATE
The socket is not in a created state. C_EADDRINFO
The call to gethostbyname_r()
failed.C_EBIND
The call to bind()
failed.C_ELISTEN
The call to listen()
failed.
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
NULL
; otherwise, it blocks until a connection request arrives. This new socket is created as a blocking socket and will be connected to the client.The function returns the newly created socket on success. On failure, it returns
NULL
and setsc_errno
to one of the following values:
C_EINVAL
s or ns is NULL
.C_EBADSTATE
The socket is not in a listening state. C_EBLOCKED
The socket is marked as non-blocking and no connection is currently pending. C_EACCEPT
The call to accept()
failed.
This function is a static variant of
C_socket_accept()
. It does not perform any allocation or deallocation of c_socket_t structures, but rather operates on pointers to preallocated structures.
C_socket_accept_s()
accepts a pending connection request on the socket ms and initializes the socket structure at s as a socket for that connection. The function returnsTRUE
on success andFALSE
on failure.
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
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s or host is NULL
, or host is an empty string.C_EBADSTATE
The socket is not in a created state. C_EADDRINFO
The call to gethostbyaddr_r()
orgethostbyname_r()
failed, most likely because host is not a valid host address.C_ENOCONN
The connection was refused. C_ECONNECT
The call to connect()
failed.C_ETIMEOUT
The connect operation timed out.
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:
C_NET_SHUTRD
for reading,C_NET_SHUTWR
for writing, orC_NET_SHUTALL
for both reading and writing. If a socket is shut down for writing only, then the process at the remote end of the socket will receive anEOF
if it attempts to read from it. Conversely, if it is shut down for reading, the process at the local end will receive anEOF
if it attempts to read from it. This function may be called repeatedly on a connected socket.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
, or the value of how is invalid.C_EBADSTATE
The socket is not in a connected or partially shut down state.
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
NUL
-terminated. The address may either be a DNS name, such as “ftp.uu.net” or, if the address could not be resolved, a dot-separated IP address, such as “132.32.5.1”.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s or buf is NULL
, or bufsz is 0.C_EBADSTATE
The socket is not in a connected state. C_EADDRINFO
The address could not be determined (the call to gethostbyaddr_r()
failed).
These functions obtain the packed IP address of each end of the socket s.
C_socket_get_ipaddr()
returns the IP address of the local end of the socket, andC_socket_get_peeripaddr()
returns the IP address of the remote end of the socket. These values will only be meaningful if the socket is in a connected state.These functions are implemented as macros.
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
C_socket_get_fp()
macro. The argument buffering specifies what type of buffering will be performed on the new stream:C_NET_BUFFERING_NONE
for no buffering,C_NET_BUFFERING_LINE
for line buffering, orC_NET_BUFFERING_FULL
for full buffering.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
, or the value of buffering is invalid.C_EBADSTATE
The socket is not in a connected state. C_EBADTYPE
s is not a TCP socket. C_EFDOPEN
The call to fdopen()
failed.
This function closes the stdio stream associated with the socket s, if one has been opened via a call to
C_socket_fopen()
.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
.
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
NULL
and setsc_errno
to one of the following values:
C_EINVAL
sd is negative. C_EFCNTL
The call to fcntl()
failed.C_EBADTYPE
The socket is neither a TCP nor UDP socket. C_ESOCKINFO
sd does not refer to a socket, or the call to getpeername()
failed.
This function is a static variant of
C_socket_reopen()
. It does not perform any allocation or deallocation of c_socket_t structures, but rather operates on pointers to preallocated structures.
C_socket_reopen_s()
initializes the socket structure at s as the socket whose descriptor is sd. The function returnsTRUE
on success andFALSE
on failure.
This function sets the option option on the socket s. Valid options are as follows:
C_NET_OPT_BLOCK
- Changes the blocking state on the socket. If a socket is in an unblocked state, any I/O or control operation on the socket that would cause the process or thread to block returns immediately with an error code of
C_EBLOCKED
. Blocking is turned on if flag isTRUE
and turned off if flag isFALSE
.C_NET_OPT_LINGER
- Changes the linger mode on the socket. By default, linger mode is off; when a socket is closed and there is still data in the socket send buffer, the operating system will attempt to deliver this data before destroying the socket, but the close operation will return immediately. If linger mode is turned on (flag is
TRUE
), the process will be blocked for up to value seconds when it closes a socket while the operating system attempts to deliver any pending data; any data still not delivered after this interval (which may be 0 seconds) will be discarded. The default setting is off.C_NET_OPT_REUSEADDR
- While there are various uses for this option, the most common use is to allow a server to bind to its port even if there are existing clients connected to that port. The option is turned on if flag is
TRUE
and turned off if flag isFALSE
. The default setting is off. The functionC_socket_listen()
automatically turns on this option.C_NET_OPT_OOBINLINE
- Specifies whether out-of-band data should be sent inline on the socket. The option is turned on if flag is
TRUE
and turned off if flag isFALSE
. The default setting is off.C_NET_OPT_KEEPALIVE
- This option provides a means to detect if the host at the remote end of the socket is still alive by sending a periodic TCP probe. If the option is turned on, the operating system will terminate the connection if the remote host does not respond to the probes. The option is turned on if flag is
TRUE
and turned off if flag isFALSE
. The default setting is off.C_NET_OPT_RECVBUF
- Changes the size of the socket receive buffer. The argument value specifies the new size of the receive buffer, in bytes, and must be greater than 0. The argument flag is ignored.
C_NET_OPT_SENDBUF
- Changes the size of the socket send buffer. The argument value specifies the new size of the send buffer, in bytes, and must be greater than 0. The argument flag is ignored.
This function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
or the value of option is invalid.C_EFCNTL
The call to fcntl()
failed.C_EBADSTATE
An attempt was made to change the blocking state on a socket that is shut down. C_ESOCKINFO
The call to setsockopt()
failed.
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
C_socket_set_option()
above for a description of the available options and their settings.This function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s, flag, or value is NULL
, or the value of option is invalid.C_ESOCKINFO
The call to getsockopt()
failed.
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
C_socket_set_option()
andC_socket_get_option()
.
C_socket_block()
marks the socket s as blocking, andC_socket_unblock()
marks the socket s as non-blocking.C_socket_isblocked()
returnsTRUE
if the socket is in blocking mode andFALSE
if it is non-blocking.
These functions (which are implemented as macros) return the socket descriptor and file stream pointer, respectively, for the socket s.
C_socket_get_fp()
returns the stream pointer, if one has been created viaC_socket_fopen()
; otherwise it returnsNULL
.
This function returns the type of the socket s, either
C_NET_TCP
orC_NET_UDP
. It is implemented as a macro.
These functions set and get the I/O timeout for the socket s. They are implemented as macros.
C_socket_set_timeout()
sets the timeout to sec seconds. The socket receive and send functions described below all return an error if the corresponding I/O operation times out after the given number of seconds.
These functions set and get the connection timeout for the socket s. They are implemented as macros.
C_socket_set_conn_timeout()
sets the timeout to sec seconds. TheC_socket_connect()
function will return an error if a connection cannot be established within the specified number of seconds. The default, system-imposed timeout of roughly 75 seconds is an upper bound on this timeout; therefore passing values greater than 75 will not lengthen the timeout. Timeout values of 0 or less are interpreted as an infinite timeout.
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.
These functions provide a means for joining and leaving a multicast group.
C_socket_mcast_join()
assigns the UDP socket s to the multicast group specified by the address addr, which may either be a valid DNS name or a dot-separated IP address.C_socket_mcast_leave()
removes the UDP socket s from the multicast group specified by the address addr.These functions return
TRUE
on success. On failure, they returnFALSE
and setc_errno
to one of the following values:
C_EINVAL
s or addr is NULL
, or addr is an empty string.C_EBADTYPE
s is not a UDP socket. C_EADDRINFO
The call to gethostbyaddr_r()
orgethostbyname_r()
failed, most likely because addr is not a valid network address.C_ESOCKINFO
The call to setsockopt()
failed.
This function sets the time-to-live value on the socket s to ttl. It returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
.C_EBADTYPE
s is not a UDP socket. C_ESOCKINFO
The call to setsockopt()
failed.
This function enables or disables the loopback function for the UDP socket s. If loopback is enabled (loop is
TRUE
), then any multicast datagrams that are sent out over this socket from the local host will also be delivered back to the host. If loopback is disabled, they are not. The loopback feature is enabled by default.The function returns
TRUE
on success. On failure, it returnsFALSE
and setsc_errno
to one of the following values:
C_EINVAL
s is NULL
.C_EBADTYPE
s is not a UDP socket. C_ESOCKINFO
The call to setsockopt()
failed.
The following functions are high-level routines for reading data from and writing data to TCP and UDP sockets.
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
TRUE
, the data is read or written out-of-band.
C_socket_recv()
reads up to bufsz bytes of data from the socket s into buf. If s is a UDP socket, it attempts to receive the data as a single datagram. If s is a TCP socket, then the function continually loops, reading as much data as it can on each iteration, until either the buffer has been filled, or no more data is available for reading on the socket. If the socket is marked as blocking, the function will block waiting for more data to arrive, and will then continue to read the data.
C_socket_send()
writes bufsz bytes of data starting at buf to the socket s. If s is a UDP socket, it attempts to send the buffer as a single datagram. If s is a TCP socket, then the function continually loops, writing as much data as it can on each iteration, until either the entire buffer has been written, or the socket is unable to accept any more data. If the socket is marked as blocking, the function will block waiting for it to drain, and will then continue writing the data.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
0
if an error occurs before any data has been read or written. On timeout or failure,c_errno
is set to one of the following values:
C_EINVAL
s or buf is NULL
, or bufsz is 0.C_EBADTYPE
s is neither a TCP nor a UDP socket. C_EBADSTATE
The socket is not in a connected state. C_ELOSTCONN
The connection was lost during data transfer. C_EBLOCKED
The socket is marked as non-blocking and the requested transfer would block the process. C_ESEND
The call to send()
orsendto()
failed.C_ERECV
The call to recv()
orrecvfrom()
failed.C_EMSG2BIG
s is a UDP socket, and bufsz is too many bytes to send as one datagram.
These functions send and receive datagrams over the unconnected UDP socket s.
C_socket_sendto()
sends bufsz bytes beginning at buf to the specified port on the remote host named addr.C_socket_recvfrom()
receives bufsz bytes from a remote host and writes them to buf, storing up to addrsz - 1 bytes of the remote host's address at addr and unconditionallyNUL
-terminates the buffer. This address is either a DNS name or, if the address could not be resolved, a dot separated IP address.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
-1
upon failure. On block or failure,c_errno
is set to one of the following values:
C_EINVAL
s or addr is NULL
, or (forC_socket_sendo()
) addr is an empty string.C_EBADTYPE
s is not a UDP socket. C_EBADSTATE
The socket is not in a created state. C_EADDRINFO
The remote source or destination address could not be determined. C_ELOSTCONN
The connection was lost. C_EBLOCKED
The socket is marked as non-blocking and the requested operation would block. C_ESENDTO
The call to sendto()
failed.C_ERECVFROM
The call to recvfrom()
failed.C_EMSG2BIG
bufsz is too many bytes to send or receive as one datagram.
These functions are similar to
C_socket_sendto()
andC_socket_recvfrom()
above, except that they reuse the remote address currently set for the UDP socket s. Specifically,C_socket_sendreply()
sends a buffer of data to the address from which the last datagram was received on s, andC_socket_recvreply()
receives a buffer of data from the address to which the last datagram was sent on s. These functions are intended for use on unconnected UDP sockets.On success, the functions return the number of bytes sent or received. On failure, they return
-1
and setc_errno
to one of the following values:
C_EINVAL
buf or s is NULL
or bufsz is 0.C_EBADTYPE
s is not a UDP socket. C_EBADSTATE
The socket is not in a created state. C_ELOSTCONN
The connection was lost. C_EBLOCKED
The socket is marked as non-blocking and the requested operation would block. C_ESENDTO
The call to sendto()
failed.C_ERECVFROM
The call to recvfrom()
failed.C_EMSG2BIG
bufsz is too many bytes to send or receive as one datagram.
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.
C_net_socket_sendline()
writes the data at buf, followed by a CR+LF pair, to the socket s. The function returns when all of the data has been written or a timeout occurs.
C_net_socket_recvline()
reads data into buf. It continues reading until bufsz - 1 bytes have been read, or a CR+LF pair has been encountered in the input, whichever occurs first. The CR+LF pair, if present, is discarded, and the buffer is unconditionallyNUL
-terminated. The function returns when all of the data has been read, or a timeout occurs.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
0
if an error occurs before any data has been read or written. On timeout or failure,c_errno
is set to one of the following values:
C_EINVAL
s or buf is NULL
, or bufsz is 0.C_EBADTYPE
s is not a TCP socket. C_EBADSTATE
The socket is not in a connected state, or it is in non-blocking mode. C_ELOSTCONN
The connection was lost during data transfer. C_ETIMEOUT
A timeout occurred while waiting to read or write data. C_ESEND
The call to send()
orsendto()
failed.C_ERECV
The call to recv()
orrecvfrom()
failed.
These interfaces are deprecated, and are emulated by macros for backward compatibility. They evaluate to calls to the
C_socket_sendline()
andC_socket_recvline()
functions, described above, ignoring the termin, slen, and snum arguments.
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 cbase/fortune.h.
The type c_fortune_db_t represents a fortune database.
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 .idx extension.
The function returns
TRUE
on success andFALSE
on failure.
These functions open and close fortune databases.
C_fortune_opendb()
opens the fortune database specified by basename and returns a handle to the database on success, orNULL
on failure (for example, if either the text or index file does not exist or can't be read).
C_fortune_closedb()
closes the fortune database db, deallocating all memory and closing all file descriptors associated with the database. The function returnsTRUE
on success orFALSE
on failure (for example, if db isNULL
).
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
NULL
or if an I/O error occurred) the function returnsNULL
.
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:
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
NULL
if no parameters were passed.Before sending data through the socket, the handler should call the functions
C_httpsrv_send_status()
andC_httpsrv_send_headers()
, in that order, to send the appropriate response status code and HTTP headers to the client.
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.
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
NULL
on failure.
This function destroys the HTTP server srv. It shuts down the server and deallocates all memory associated with it.
These functions add and remove request handlers for the HTTP server srv.
C_httpsrv_add_handler()
associates the given handler function with the URI uri, replacing any handler currently associated with that URI. HTTP requests for the given URI will be routed to this handler.
C_httpsrv_remove_handler()
removes the handler associated with the URI uri, if any.
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
NULL
for handler removes the default handler.
This function accepts the next pending connection for the HTTP server srv and processes the request. It returns
TRUE
if the request was handled successfully andFALSE
otherwise.
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.
C_httpsrv_send_status()
sends a status line back to the client. The status is a numeric value which must be a valid HTTP status code. The following table enumerates some of the more common HTTP status codes.
Code Meaning
200
OK 400
Bad Request 403
Forbidden 404
Not Found 408
Request Timed Out 500
Internal Server Error 501
Not Implemented 503
Server Busy If errmsg isTRUE
, an appropriate HTML-formatted error message is sent back to the client as the content of the message. In this case, it is not necessary to callC_httpsrv_send_headers()
.
C_httpsrv_send_headers()
sends the mandatory `Content-Type' and the optional `Content-Length' headers to the client, followed by a blank line. The argument mime_type specifies the value for the `Content-Type' header. It may not beNULL
. The argument content_length specifies the value for the `Content-Length' header. If content_length is negative, the header will not be sent.Both functions return
TRUE
on success andFALSE
on failure.
This function retrieves the HTTP parameter named key from the parameter list params. It returns the parameter on success, or
NULL
if the parameter does not exist. The accessor functions described below may be used to retrieve the value(s) of the parameter.
C_http_param_isarray()
determines if the HTTP parameter param has an array of values or a single value.
C_http_param_value()
returns the single value of the HTTP parameter param, or, if the parameter has an array of values, the first value in the array.
C_http_param_values()
returns the array of values for the HTTP parameter param as a linked list, orNULL
if the parameter does not have an array of values.These functions are implemented as macros.
The following functions provide runtime information about the cbase library itself. All of the functions described in this chapter are defined in the header cbase/version.h.
This function returns a string containing the version number of the library. This version number corresponds to the version of the package.
This function returns a string containing information about the library, including the package name and version, the author, bug report email address, and copyright.
This function returns a
NULL
-terminated array of strings which represent the set of options that are enabled in the library. Currently only the following options are defined: `xml' (if the XML functions are available) and `threaded' (if the multi-threaded version of the library is in use).
The following books proved to be indispensable during the implementation of this library.
The cbase 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.
If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
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 FunctionsC_bit_clear
: Convenience MacrosC_bit_isset
: Convenience MacrosC_bit_set
: Convenience MacrosC_bitstring_clear
: Bitstring FunctionsC_bitstring_clear_all
: Bitstring FunctionsC_bitstring_clear_range
: Bitstring FunctionsC_bitstring_compare
: Bitstring FunctionsC_bitstring_create
: Bitstring FunctionsC_bitstring_destroy
: Bitstring FunctionsC_bitstring_isclear
: Bitstring FunctionsC_bitstring_isset
: Bitstring FunctionsC_bitstring_set
: Bitstring FunctionsC_bitstring_set_all
: Bitstring FunctionsC_bitstring_set_range
: Bitstring FunctionsC_bitstring_size
: Bitstring FunctionsC_btree_create
: B-TreesC_btree_delete
: B-TreesC_btree_destroy
: B-TreesC_btree_iterate
: B-TreesC_btree_order
: B-TreesC_btree_restore
: B-TreesC_btree_set_destructor
: B-TreesC_btree_store
: B-TreesC_buffer_clear
: Data Buffer FunctionsC_buffer_create
: Data Buffer FunctionsC_buffer_data
: Data Buffer FunctionsC_buffer_datalen
: Data Buffer FunctionsC_buffer_destroy
: Data Buffer FunctionsC_buffer_hook
: Data Buffer FunctionsC_buffer_resize
: Data Buffer FunctionsC_buffer_size
: Data Buffer FunctionsC_byteord_htond
: Byte Order Conversion FunctionsC_byteord_htonf
: Byte Order Conversion FunctionsC_byteord_htonl
: Byte Order Conversion FunctionsC_byteord_htonll
: Byte Order Conversion FunctionsC_byteord_htons
: Byte Order Conversion FunctionsC_byteord_ntohd
: Byte Order Conversion FunctionsC_byteord_ntohf
: Byte Order Conversion FunctionsC_byteord_ntohl
: Byte Order Conversion FunctionsC_byteord_ntohll
: Byte Order Conversion FunctionsC_byteord_ntohs
: Byte Order Conversion FunctionsC_calloc
: Memory Management FunctionsC_darray_create
: Dynamic ArraysC_darray_defragment
: Dynamic ArraysC_darray_delete
: Dynamic ArraysC_darray_destroy
: Dynamic ArraysC_darray_iterate
: Dynamic ArraysC_darray_load
: Dynamic ArraysC_darray_restore
: Dynamic ArraysC_darray_save
: Dynamic ArraysC_darray_size
: Dynamic ArraysC_darray_store
: Dynamic ArraysC_datum_key
: Data ElementsC_datum_value
: Data ElementsC_debug_printf
: Debugging and Tracing FunctionsC_debug_set_stream
: Debugging and Tracing FunctionsC_debug_set_termattr
: Debugging and Tracing FunctionsC_debug_set_trace
: Debugging and Tracing FunctionsC_dlobject_create
: Dynamic Linker FunctionsC_dlobject_destroy
: Dynamic Linker FunctionsC_dlobject_error
: Dynamic Linker FunctionsC_dlobject_isloaded
: Dynamic Linker FunctionsC_dlobject_load
: Dynamic Linker FunctionsC_dlobject_lookup
: Dynamic Linker FunctionsC_dlobject_path
: Dynamic Linker FunctionsC_dlobject_unload
: Dynamic Linker FunctionsC_dstring_append
: Dynamic StringsC_dstring_create
: Dynamic StringsC_dstring_destroy
: Dynamic StringsC_dstring_getc
: Dynamic StringsC_dstring_gets
: Dynamic StringsC_dstring_length
: Dynamic StringsC_dstring_load
: Dynamic StringsC_dstring_putc
: Dynamic StringsC_dstring_puts
: Dynamic StringsC_dstring_puts_len
: Dynamic StringsC_dstring_rewind
: Dynamic StringsC_dstring_save
: Dynamic StringsC_dstring_seek
: Dynamic StringsC_dstring_trunc
: Dynamic StringsC_dstring_ungetc
: Dynamic StringsC_error_get_errno
: Error Handling FunctionsC_error_init
: Error Handling FunctionsC_error_printf
: Error Handling FunctionsC_error_set_errno
: Error Handling FunctionsC_error_string
: Error Handling FunctionsC_error_syserr
: Error Handling FunctionsC_error_usage
: Error Handling FunctionsC_exec_pipefrom
: Process Control FunctionsC_exec_pipefrom_cwd
: Process Control FunctionsC_exec_pipeto
: Process Control FunctionsC_exec_pipeto_cwd
: Process Control FunctionsC_exec_run
: Process Control FunctionsC_exec_run_cwd
: Process Control FunctionsC_exec_va_call
: Process Control FunctionsC_exec_va_run
: Process Control FunctionsC_exec_va_run_cwd
: Process Control FunctionsC_exec_wait
: Process Control FunctionsC_fd_recv
: File Descriptor Passing FunctionsC_fd_send
: File Descriptor Passing FunctionsC_file_getcwd
: Filesystem FunctionsC_file_issymlink
: Filesystem FunctionsC_file_load
: Filesystem FunctionsC_file_lock
: Mandatory File Locking FunctionsC_file_mkdirs
: Filesystem FunctionsC_file_readdir
: Filesystem FunctionsC_file_traverse
: Filesystem FunctionsC_file_trylock
: Mandatory File Locking FunctionsC_file_unlock
: Mandatory File Locking FunctionsC_fortune_closedb
: Fortune Database FunctionsC_fortune_indexdb
: Fortune Database FunctionsC_fortune_opendb
: Fortune Database FunctionsC_fortune_select
: Fortune Database FunctionsC_free
: Memory Management FunctionsC_free_vec
: Memory Management FunctionsC_getchar
: I/O FunctionsC_getline
: I/O FunctionsC_gets
: I/O FunctionsC_hashtable_create
: HashtablesC_hashtable_delete
: HashtablesC_hashtable_destroy
: HashtablesC_hashtable_keys
: HashtablesC_hashtable_restore
: HashtablesC_hashtable_set_destructor
: HashtablesC_hashtable_set_hashfunc
: HashtablesC_hashtable_size
: HashtablesC_hashtable_store
: HashtablesC_hex_decode
: Hexadecimal Encoding FunctionsC_hex_encode
: Hexadecimal Encoding FunctionsC_hex_frombyte
: Hexadecimal Encoding FunctionsC_hex_fromnibble
: Hexadecimal Encoding FunctionsC_hex_isdigit
: Hexadecimal Encoding FunctionsC_hex_tobyte
: Hexadecimal Encoding FunctionsC_hex_tonibble
: Hexadecimal Encoding FunctionsC_http_param_get
: HTTP FunctionsC_http_param_isarray
: HTTP FunctionsC_http_param_value
: HTTP FunctionsC_http_param_values
: HTTP FunctionsC_httpsrv_accept
: HTTP FunctionsC_httpsrv_add_handler
: HTTP FunctionsC_httpsrv_create
: HTTP FunctionsC_httpsrv_destroy
: HTTP FunctionsC_httpsrv_remove_handler
: HTTP FunctionsC_httpsrv_send_headers
: HTTP FunctionsC_httpsrv_send_status
: HTTP FunctionsC_httpsrv_set_default_handler
: HTTP FunctionsC_io_fprintf
: I/O FunctionsC_io_getchar
: I/O FunctionsC_io_getline
: I/O FunctionsC_io_getline_buf
: I/O FunctionsC_io_getpasswd
: I/O FunctionsC_io_gets
: I/O FunctionsC_lengthof
: Convenience MacrosC_library_info
: Library Information FunctionsC_library_options
: Library Information FunctionsC_library_version
: Library Information FunctionsC_link_data
: LinksC_link_next
: LinksC_link_prev
: LinksC_linklist_create
: Linked ListsC_linklist_delete
: Linked ListsC_linklist_delete_r
: Linked ListsC_linklist_destroy
: Linked ListsC_linklist_head
: Linked ListsC_linklist_ishead
: Linked ListsC_linklist_ishead_r
: Linked ListsC_linklist_istail
: Linked ListsC_linklist_istail_r
: Linked ListsC_linklist_length
: Linked ListsC_linklist_move
: Linked ListsC_linklist_move_head
: Linked ListsC_linklist_move_head_r
: Linked ListsC_linklist_move_next
: Linked ListsC_linklist_move_next_r
: Linked ListsC_linklist_move_prev
: Linked ListsC_linklist_move_prev_r
: Linked ListsC_linklist_move_r
: Linked ListsC_linklist_move_tail
: Linked ListsC_linklist_move_tail_r
: Linked ListsC_linklist_restore
: Linked ListsC_linklist_restore_r
: Linked ListsC_linklist_search
: Linked ListsC_linklist_search_r
: Linked ListsC_linklist_set_destructor
: Linked ListsC_linklist_store
: Linked ListsC_linklist_store_r
: Linked ListsC_linklist_tail
: Linked ListsC_log_error
: Logging FunctionsC_log_info
: Logging FunctionsC_log_set_console
: Logging FunctionsC_log_set_stream
: Logging FunctionsC_log_set_termattr
: Logging FunctionsC_log_warning
: Logging FunctionsC_malloc
: Memory Management FunctionsC_max
: Convenience MacrosC_mem_default_alloc_hook
: Memory Management FunctionsC_mem_defrag
: Memory Management FunctionsC_mem_free
: Memory Management FunctionsC_mem_freevec
: Memory Management FunctionsC_mem_manage
: Memory Management FunctionsC_mem_set_alloc_hook
: Memory Management FunctionsC_mem_set_errorfunc
: Memory Management FunctionsC_mem_va_free
: Memory Management FunctionsC_memfile_base
: Memory Mapped FilesC_memfile_close
: Memory Mapped FilesC_memfile_length
: Memory Mapped FilesC_memfile_open
: Memory Mapped FilesC_memfile_pointer
: Memory Mapped FilesC_memfile_resize
: Memory Mapped FilesC_memfile_sync
: Memory Mapped FilesC_mempool_alloc
: Memory Pool FunctionsC_mempool_avail
: Memory Pool FunctionsC_mempool_create
: Memory Pool FunctionsC_mempool_destroy
: Memory Pool FunctionsC_min
: Convenience MacrosC_net_get_svcname
: Network Information FunctionsC_net_get_svcport
: Network Information FunctionsC_net_resolve
: Network Information FunctionsC_net_resolve_local
: Network Information FunctionsC_new
: Memory Management FunctionsC_newa
: Memory Management FunctionsC_newb
: Memory Management FunctionsC_newstr
: Memory Management FunctionsC_offsetof
: Convenience MacrosC_palloc
: Memory Pool FunctionsC_palloc1
: Memory Pool FunctionsC_pallocstr
: Memory Pool FunctionsC_printf
: I/O FunctionsC_pty_create
: Pseudoterminal Control FunctionsC_pty_destroy
: Pseudoterminal Control FunctionsC_pty_master_fd
: Pseudoterminal Control FunctionsC_pty_slave_fd
: Pseudoterminal Control FunctionsC_pty_slave_name
: Pseudoterminal Control FunctionsC_queue_create
: QueuesC_queue_dequeue
: QueuesC_queue_destroy
: QueuesC_queue_enqueue
: QueuesC_queue_length
: QueuesC_queue_set_destructor
: QueuesC_random
: Random Number FunctionsC_random_seed
: Random Number FunctionsC_realloc
: Memory Management FunctionsC_sched_event_activate
: Event Scheduling FunctionsC_sched_event_create
: Event Scheduling FunctionsC_sched_event_data
: Event Scheduling FunctionsC_sched_event_deactivate
: Event Scheduling FunctionsC_sched_event_destroy
: Event Scheduling FunctionsC_sched_event_find
: Event Scheduling FunctionsC_sched_event_id
: Event Scheduling FunctionsC_sched_init
: Scheduler Control FunctionsC_sched_poll
: Scheduler Control FunctionsC_sched_shutdown
: Scheduler Control FunctionsC_sem_create
: Semaphore FunctionsC_sem_destroy
: Semaphore FunctionsC_sem_initial_value
: Semaphore FunctionsC_sem_name
: Semaphore FunctionsC_sem_post
: Semaphore FunctionsC_sem_trywait
: Semaphore FunctionsC_sem_value
: Semaphore FunctionsC_sem_wait
: Semaphore FunctionsC_sgn
: Convenience MacrosC_shmem_base
: Shared Memory FunctionsC_shmem_create
: Shared Memory FunctionsC_shmem_destroy
: Shared Memory FunctionsC_shmem_name
: Shared Memory FunctionsC_shmem_resize
: Shared Memory FunctionsC_shmem_size
: Shared Memory FunctionsC_signal_name
: Signal Handling FunctionsC_socket_accept
: Socket Control FunctionsC_socket_accept_s
: Socket Control FunctionsC_socket_block
: Socket Control FunctionsC_socket_connect
: Socket Control FunctionsC_socket_create
: Socket Control FunctionsC_socket_create_s
: Socket Control FunctionsC_socket_destroy
: Socket Control FunctionsC_socket_destroy_s
: Socket Control FunctionsC_socket_fclose
: Socket Control FunctionsC_socket_fopen
: Socket Control FunctionsC_socket_get_conn_timeout
: Socket Control FunctionsC_socket_get_fd
: Socket Control FunctionsC_socket_get_fp
: Socket Control FunctionsC_socket_get_ipaddr
: Socket Control FunctionsC_socket_get_option
: Socket Control FunctionsC_socket_get_peeraddr
: Socket Control FunctionsC_socket_get_peeripaddr
: Socket Control FunctionsC_socket_get_timeout
: Socket Control FunctionsC_socket_get_type
: Socket Control FunctionsC_socket_get_userdata
: Socket Control FunctionsC_socket_isblocked
: Socket Control FunctionsC_socket_listen
: Socket Control FunctionsC_socket_mcast_join
: Socket Multicast FunctionsC_socket_mcast_leave
: Socket Multicast FunctionsC_socket_mcast_set_loop
: Socket Multicast FunctionsC_socket_mcast_set_ttl
: Socket Multicast FunctionsC_socket_readline
: Socket I/O FunctionsC_socket_recv
: Socket I/O FunctionsC_socket_recvfrom
: Socket I/O FunctionsC_socket_recvline
: Socket I/O FunctionsC_socket_recvreply
: Socket I/O FunctionsC_socket_reopen
: Socket Control FunctionsC_socket_reopen_s
: Socket Control FunctionsC_socket_rl
: Socket I/O FunctionsC_socket_send
: Socket I/O FunctionsC_socket_sendline
: Socket I/O FunctionsC_socket_sendreply
: Socket I/O FunctionsC_socket_sendto
: Socket I/O FunctionsC_socket_set_conn_timeout
: Socket Control FunctionsC_socket_set_option
: Socket Control FunctionsC_socket_set_timeout
: Socket Control FunctionsC_socket_set_userdata
: Socket Control FunctionsC_socket_shutdown
: Socket Control FunctionsC_socket_unblock
: Socket Control FunctionsC_socket_wl
: Socket I/O FunctionsC_socket_writeline
: Socket I/O FunctionsC_stack_create
: StacksC_stack_depth
: StacksC_stack_destroy
: StacksC_stack_peek
: StacksC_stack_pop
: StacksC_stack_push
: StacksC_stack_set_destructor
: StacksC_strbuffer_clear
: String Buffer FunctionsC_strbuffer_create
: String Buffer FunctionsC_strbuffer_destroy
: String Buffer FunctionsC_strbuffer_putc
: String Buffer FunctionsC_strbuffer_size
: String Buffer FunctionsC_strbuffer_sprintf
: String Buffer FunctionsC_strbuffer_strcat
: String Buffer FunctionsC_strbuffer_strcpy
: String Buffer FunctionsC_strbuffer_string
: String Buffer FunctionsC_strbuffer_strlen
: String Buffer FunctionsC_string_chop
: String Manipulation and Parsing FunctionsC_string_clean
: String Manipulation and Parsing FunctionsC_string_compare
: String Manipulation and Parsing FunctionsC_string_concat
: String Manipulation and Parsing FunctionsC_string_copy
: String Manipulation and Parsing FunctionsC_string_dup
: String Manipulation and Parsing FunctionsC_string_dup1
: String Manipulation and Parsing FunctionsC_string_endswith
: String Manipulation and Parsing FunctionsC_string_hash
: String Manipulation and Parsing FunctionsC_string_isnumeric
: String Manipulation and Parsing FunctionsC_string_sortvec
: String Manipulation and Parsing FunctionsC_string_split
: String Manipulation and Parsing FunctionsC_string_startswith
: String Manipulation and Parsing FunctionsC_string_tokenize
: String Manipulation and Parsing FunctionsC_string_tolower
: String Manipulation and Parsing FunctionsC_string_toupper
: String Manipulation and Parsing FunctionsC_string_trim
: String Manipulation and Parsing FunctionsC_string_va_concat
: String Manipulation and Parsing FunctionsC_string_va_copy
: String Manipulation and Parsing FunctionsC_string_va_makevec
: String Manipulation and Parsing FunctionsC_string_valist2vec
: String Manipulation and Parsing FunctionsC_system_cdhome
: System Information FunctionsC_system_get_fullname
: System Information FunctionsC_system_get_gid
: System Information FunctionsC_system_get_homedir
: System Information FunctionsC_system_get_hostname
: System Information FunctionsC_system_get_login
: System Information FunctionsC_system_get_pid
: System Information FunctionsC_system_get_term
: System Information FunctionsC_system_get_uid
: System Information FunctionsC_system_getinfo
: System Information FunctionsC_system_ingroup
: System Information FunctionsC_system_passwd_generate
: System Information FunctionsC_system_passwd_validate
: System Information FunctionsC_tag_data
: TagsC_tag_key
: TagsC_time_format
: Time FunctionsC_time_parse
: Time FunctionsC_timer_create
: CPU Timer FunctionsC_timer_created
: CPU Timer FunctionsC_timer_destroy
: CPU Timer FunctionsC_timer_elapsed
: CPU Timer FunctionsC_timer_isrunning
: CPU Timer FunctionsC_timer_reset
: CPU Timer FunctionsC_timer_resume
: CPU Timer FunctionsC_timer_start
: CPU Timer FunctionsC_timer_stop
: CPU Timer FunctionsC_timer_system
: CPU Timer FunctionsC_timer_user
: CPU Timer FunctionsC_tty_raw
: Terminal Control FunctionsC_tty_restore
: Terminal Control FunctionsC_tty_sane
: Terminal Control FunctionsC_tty_store
: Terminal Control FunctionsC_tty_unraw
: Terminal Control FunctionsC_va_free
: Memory Management FunctionsC_vector_abort
: String Vector FunctionsC_vector_end
: String Vector FunctionsC_vector_free
: String Vector FunctionsC_vector_start
: String Vector FunctionsC_vector_store
: String Vector FunctionsC_xml_document_create
: XML Data Manipulation FunctionsC_xml_document_destroy
: XML Data Manipulation FunctionsC_xml_document_get_root
: XML Data Manipulation FunctionsC_xml_document_read
: XML Data Manipulation FunctionsC_xml_document_set_root
: XML Data Manipulation FunctionsC_xml_document_write
: XML Data Manipulation FunctionsC_xml_element_add_child
: XML Data Manipulation FunctionsC_xml_element_create
: XML Data Manipulation FunctionsC_xml_element_delete_param
: XML Data Manipulation FunctionsC_xml_element_delete_params
: XML Data Manipulation FunctionsC_xml_element_destroy
: XML Data Manipulation FunctionsC_xml_element_destroy_recursive
: XML Data Manipulation FunctionsC_xml_element_get_children
: XML Data Manipulation FunctionsC_xml_element_get_children_named
: XML Data Manipulation FunctionsC_xml_element_get_content
: XML Data Manipulation FunctionsC_xml_element_get_first_child
: XML Data Manipulation FunctionsC_xml_element_get_param
: XML Data Manipulation FunctionsC_xml_element_remove_child
: XML Data Manipulation FunctionsC_xml_element_remove_children
: XML Data Manipulation FunctionsC_xml_element_remove_children_named
: XML Data Manipulation FunctionsC_xml_element_set_content
: XML Data Manipulation FunctionsC_xml_element_set_param
: XML Data Manipulation FunctionsC_zero
: Memory Management FunctionsC_zeroa
: Memory Management Functionshttp_handler
: HTTP Functionsc_bitstring_t
: Bitstring Functionsc_bool_t
: Basic Typesc_btree_t
: B-Treesc_buffer_t
: Data Buffer Functionsc_byte_t
: Basic Typesc_darray_t
: Dynamic Arraysc_datum_t
: Data Elementsc_dirlist_t
: Filesystem Functionsc_dlobject_t
: Dynamic Linker Functionsc_dstring_t
: Dynamic Stringsc_fortune_db_t
: Fortune Database Functionsc_hashtable_t
: Hashtablesc_http_param_t
: HTTP Functionsc_httpsrv_handler_t
: HTTP Functionsc_httpsrv_t
: HTTP Functionsc_id_t
: IDsc_link_t
: Basic Data Typesc_linklist_t
: Linked Listsc_memfile_t
: Memory Mapped Filesc_mempool_t
: Memory Pool Functionsc_pty_t
: Pseudoterminal Control Functionsc_queue_t
: Queuesc_schedevt_t
: Event Scheduling Functionsc_sem_t
: Semaphore Functionsc_shmem_t
: Shared Memory Functionsc_socket_t
: Socket Control Functionsc_stack_t
: Stacksc_strbuffer_t
: String Buffer Functionsc_sysinfo_t
: System Information Functionsc_tag_t
: Basic Data Typesc_timer_t
: CPU Timer Functionsc_vector_t
: String Vector Functionsc_xml_document_t
: XML Data Manipulation Functionsc_xml_element_t
: XML Data Manipulation Functionsuint_t
: Basic TypesC_DARRAY_MAX_RESIZE
: Dynamic ArraysC_DSTRING_MIN_BLOCKSZ
: Dynamic StringsC_DSTRING_SEEK_ABS
: Dynamic StringsC_DSTRING_SEEK_END
: Dynamic StringsC_DSTRING_SEEK_REL
: Dynamic StringsC_EACCEPT
: Socket Control FunctionsC_EADDRINFO
: Socket I/O FunctionsC_EADDRINFO
: Socket Multicast FunctionsC_EADDRINFO
: Socket Control FunctionsC_EADDRINFO
: Network Information FunctionsC_EBADSTATE
: Socket I/O FunctionsC_EBADSTATE
: Socket Control FunctionsC_EBADTYPE
: Socket I/O FunctionsC_EBADTYPE
: Socket Multicast FunctionsC_EBADTYPE
: Socket Control FunctionsC_EBIND
: Socket Control FunctionsC_EBLOCKED
: Socket I/O FunctionsC_EBLOCKED
: Socket Control FunctionsC_ECONNECT
: Socket Control FunctionsC_EFCNTL
: Socket Control FunctionsC_EFDOPEN
: Socket Control FunctionsC_EGETPTY
: Pseudoterminal Control FunctionsC_EINVAL
: Socket I/O FunctionsC_EINVAL
: Socket Multicast FunctionsC_EINVAL
: Socket Control FunctionsC_EINVAL
: Network Information FunctionsC_EINVAL
: Terminal Control FunctionsC_EIOCTL
: Pseudoterminal Control FunctionsC_ELISTEN
: Socket Control FunctionsC_ELOSTCONN
: Socket I/O FunctionsC_EMSG2BIG
: Socket I/O FunctionsC_ENOCONN
: Socket Control FunctionsC_ENOTTY
: Terminal Control FunctionsC_EOPEN
: Pseudoterminal Control FunctionsC_ERECV
: Socket I/O FunctionsC_ERECVFROM
: Socket I/O FunctionsC_ESEND
: Socket I/O FunctionsC_ESENDTO
: Socket I/O FunctionsC_ESOCKET
: Socket Control FunctionsC_ESOCKINFO
: Socket Multicast FunctionsC_ESOCKINFO
: Socket Control FunctionsC_ESVCINFO
: Network Information FunctionsC_ETCATTR
: Terminal Control FunctionsC_ETIMEOUT
: Socket I/O FunctionsC_ETIMEOUT
: Socket Control FunctionsC_FILE_ADDSLASH
: Filesystem FunctionsC_FILE_GETCHAR_DELAY
: I/O FunctionsC_FILE_READ_LOCK
: Mandatory File Locking FunctionsC_FILE_SEPARATE
: Filesystem FunctionsC_FILE_SKIP2DOT
: Filesystem FunctionsC_FILE_SKIPDIRS
: Filesystem FunctionsC_FILE_SKIPDOT
: Filesystem FunctionsC_FILE_SKIPFILES
: Filesystem FunctionsC_FILE_SKIPHIDDEN
: Filesystem FunctionsC_FILE_SORT
: Filesystem FunctionsC_FILE_WRITE_LOCK
: Mandatory File Locking FunctionsC_LINKLIST_HEAD
: Linked ListsC_LINKLIST_NEXT
: Linked ListsC_LINKLIST_PREV
: Linked ListsC_LINKLIST_TAIL
: Linked ListsC_NET_BUFFERING_FULL
: Socket Control FunctionsC_NET_BUFFERING_LINE
: Socket Control FunctionsC_NET_BUFFERING_NONE
: Socket Control FunctionsC_NET_OPT_BLOCK
: Socket Control FunctionsC_NET_OPT_KEEPALIVE
: Socket Control FunctionsC_NET_OPT_LINGER
: Socket Control FunctionsC_NET_OPT_OOBINLINE
: Socket Control FunctionsC_NET_OPT_RECVBUF
: Socket Control FunctionsC_NET_OPT_REUSEADDR
: Socket Control FunctionsC_NET_OPT_SENDBUF
: Socket Control FunctionsC_NET_OTHER
: Network Information FunctionsC_NET_SHUTALL
: Socket Control FunctionsC_NET_SHUTRD
: Socket Control FunctionsC_NET_SHUTWR
: Socket Control FunctionsC_NET_TCP
: Network Information FunctionsC_NET_UDP
: Network Information FunctionsC_NET_UNKNOWN
: Network Information FunctionsC_SEM_MAX_VALUE
: Semaphore FunctionsCRLF
: Miscellaneous ConstantsDEBUG
: Debugging and Tracing FunctionsFALSE
: API ConventionsNUL
: Miscellaneous ConstantsTRUE
: API Conventions