sk_new_null
, sk_new
,
sk_set_cmp_func
, sk_dup
,
sk_free
, sk_pop_free
,
sk_num
, sk_value
,
sk_find
, sk_find_ex
,
sk_sort
, sk_is_sorted
,
sk_push
, sk_unshift
,
sk_insert
, sk_set
,
sk_pop
, sk_shift
,
sk_delete
, sk_delete_ptr
,
sk_zero
—
variable-sized arrays of void pointers, called OpenSSL
stacks
#include <openssl/stack.h>
_STACK *
sk_new_null
(void);
_STACK *
sk_new
(int (*compfunc)(const void *,
const void *));
old_function_pointer
sk_set_cmp_func
(_STACK *stack,
int (*compfunc)(const void *, const void *));
_STACK *
sk_dup
(_STACK *stack);
void
sk_free
(_STACK *stack);
void
sk_pop_free
(_STACK *stack,
void (*freefunc)(void *));
int
sk_num
(const _STACK *stack);
void *
sk_value
(const _STACK *stack,
int index);
int
sk_find
(_STACK *stack,
void *wanted);
int
sk_find_ex
(_STACK *stack,
void *wanted);
void
sk_sort
(_STACK *stack);
int
sk_is_sorted
(const _STACK
*stack);
int
sk_push
(_STACK *stack,
void *new_item);
int
sk_unshift
(_STACK *stack,
void *new_item);
int
sk_insert
(_STACK *stack,
void *new_item, int index);
void *
sk_set
(_STACK *stack,
int index, void *new_item);
void *
sk_pop
(_STACK *stack);
void *
sk_shift
(_STACK *stack);
void *
sk_delete
(_STACK *stack,
int index);
void *
sk_delete_ptr
(_STACK *stack,
void *wanted);
void
sk_zero
(_STACK *stack);
OpenSSL introduced an idiosyncratic concept of variable sized arrays of pointers
and somewhat misleadingly called such an array a “stack”.
Intrinsically, and as documented in this manual page, OpenSSL stacks are not
type safe but only handle void * function arguments and
return values.
OpenSSL also provides a fragile, unusually complicated system of
macro-generated wrappers that offers superficial type safety at the expense
of extensive obfuscation, implemented using large amounts of autogenerated
code involving exceedingly ugly, nested
cpp(1)
macros; see the
STACK_OF(3)
manual page for details.
The fundamental data type is the _STACK
structure. It stores a variable number of void pointers and remembers the
number of pointers currently stored. It can optionally hold a pointer to a
comparison function. As long as no comparison function is installed, the
order of pointers is meaningful; as soon as a comparison function is
installed, it becomes ill-defined.
sk_new_null
() allocates and initializes a
new, empty stack. sk_new
() is identical except that
it also installs compfunc as the comparison function
for the new stack object. sk_set_cmp_func
() installs
compfunc for the existing stack.
The compfunc is allowed to be
NULL
, but the stack is
not.
sk_dup
() creates a shallow copy of the
given stack, which must not be a
NULL
pointer. It neither copies the objects pointed
to from the stack nor increases their reference counts, but merely copies
the pointers. Extreme care must be taken in order to avoid freeing the
memory twice, for example by calling sk_free
() on
one copy and only calling sk_pop_free
() on the
other.
sk_free
() frees the given
stack. It does not free any of the pointers stored on
the stack. Unless these pointers are merely copies of pointers owned by
other objects, they must be freed before calling
sk_free
(), in order to avoid leaking memory. If
stack is a NULL
pointer, no
action occurs.
sk_pop_free
() is severely misnamed. It
does not at all do what one would expect from a function called
“pop”. Instead, it does the same as
sk_free
(), except that it also calls the function
freefunc on each of the pointers contained in the
stack. If the calls to freefunc
are intended to free the memory in use by the objects on the stack, ensure
that no other pointers to the same objects remain elsewhere.
sk_find
() searches the
stack for the wanted pointer. If
the stack contains more than one copy of the
wanted pointer, only the first match is found. If a
comparison function is installed for the stack, the stack is first sorted
with sk_sort
(), and instead of comparing pointers,
two pointers are considered to match if the comparison function returns
0.
sk_find_ex
() is identical to
sk_find
() except that if the
stack is not empty but no match is found, the index of
some pointer considered closest to wanted is
returned.
sk_sort
() sorts the
stack using
qsort(3)
and the installed comparison function. If stack is a
NULL
pointer or already considered sorted, no action
occurs. This function can only be called if a comparison function is
installed.
sk_is_sorted
() reports whether the
stack is considered sorted. Calling
sk_new_null
() or sk_new
(),
successfully calling sk_push
(),
sk_unshift
(), sk_insert
(),
or sk_set
(), or changing the comparison function
sets the state to unsorted. If a comparison function is installed, calling
sk_sort
(), sk_find
(), or
sk_find_ex
() sets the state to sorted.
sk_push
() pushes
new_item onto the end of the
stack, increasing the number of pointers by 1. If
stack is a NULL
pointer, no
action occurs.
sk_unshift
() inserts
new_item at the beginning of the
stack, such that it gets the index 0. The number of
pointers increases by 1. If stack is a
NULL
pointer, no action occurs.
sk_insert
() inserts the
new_item into the stack such
that it gets the given index. If
index is less than 0 or greater than or equal to
sk_num
(stack), the effect is
the same as for sk_push
(). If
stack is a NULL
pointer, no
action occurs.
sk_set
() replaces the pointer with the
given index on the stack with
the new_item. The old pointer is not freed, which may
leak memory if no copy of it exists elsewhere. If
stack is a NULL
pointer or if
index is less than 0 or greater than or equal to
sk_num
(stack), no action
occurs.
sk_pop
() and
sk_shift
() remove the pointer with the highest or
lowest index from the stack, respectively, reducing
the number of pointers by 1. If stack is a
NULL
pointer or if it is empty, no action
occurs.
sk_delete
() removes the pointer with the
given index from the stack,
reducing the number of pointers by 1. If stack is a
NULL
pointer or the index is
less than 0 or greater than or equal to
sk_num
(stack), no action
occurs.
sk_delete_ptr
() removes the
wanted pointer from the stack,
reducing the number of pointers by 1 if it is found. It never uses a
comparison function but only compares pointers themselves. The
stack pointer must not be
NULL
.
sk_zero
() removes all pointers from the
stack. It does not free any of the pointers. Unless
these pointers are merely copies of pointers owned by other objects, they
must be freed before calling sk_zero
(), in order to
avoid leaking memory. If stack is a
NULL
pointer, no action occurs.
sk_new_null
(), sk_new
(), and
sk_dup
() return a pointer to the newly allocated stack
object or NULL
if insufficient memory is available.
sk_set_cmp_func
() returns a pointer to the
comparison function that was previously installed for the
stack or NULL
if none was
installed.
sk_num
() returns the number of pointers
currently stored on the stack, or -1 if
stack is a NULL
pointer.
sk_value
() returns the pointer with the
given index from the stack, or
NULL
if stack is a
NULL
pointer or if the index
is less than 0 or greater than or equal to
sk_num
(stack).
sk_find
() returns the lowest index
considered to match or -1 if stack is a
NULL
pointer or if no match is found.
sk_find_ex
() returns some index or -1 if
stack is a NULL
pointer or
empty.
sk_is_sorted
() returns 1 if the
stack is considered sorted or if it is a
NULL
pointer, or 0 otherwise.
sk_push
(),
sk_unshift
(), and
sk_insert
() return the new number of pointers on the
stack or 0 if stack is a
NULL
pointer or if memory allocation fails.
sk_set
() returns
new_item or NULL
if
stack is a NULL
pointer or if
the index is less than 0 or greater than or equal to
sk_num
(stack).
sk_pop
() and
sk_shift
() return the deleted pointer or
NULL
if stack is a
NULL
pointer or if it is empty.
sk_delete
() returns the deleted pointer or
NULL
if stack is a
NULL
pointer or if the index
is less than 0 or greater than or equal to
sk_num
(stack).
sk_delete_ptr
() returns
wanted or NULL
if it is not
found.
sk_new_null
(), sk_new
(),
sk_free
(), sk_pop_free
(),
sk_num
(), sk_value
(),
sk_find
(), sk_push
(),
sk_unshift
(), sk_insert
(),
sk_pop
(), sk_shift
(),
sk_delete
(), and
sk_delete_ptr
() first appeared in SSLeay 0.5.1.
sk_set_cmp_func
(), sk_dup
(),
and sk_zero
() first appeared in SSLeay 0.8.0. These
functions have been available since OpenBSD 2.4.
sk_set
() first appeared in OpenSSL 0.9.3.
sk_sort
() first appeared in OpenSSL 0.9.4. Both
functions have been available since OpenBSD 2.6.
sk_is_sorted
() first appeared in OpenSSL
0.9.7e and has been available since OpenBSD 3.8.
sk_find_ex
() first appeared in OpenSSL
0.9.8 and has been available since OpenBSD 4.5.
Even if a comparison function is installed, empty stacks and stacks containing a
single pointer are sometimes considered sorted and sometimes considered
unsorted.
If a comparison function is installed, the concept of
“first match” in sk_find
() and
sk_find_ex
() is ill-defined because
qsort(3)
is not a stable sorting function. It is probably best to only assume that
they return an arbitrary match.
The concept of “closest” for
sk_find_ex
() is even less clearly defined. The match
may sometimes be smaller and sometimes larger than
wanted, even if both smaller and larger pointers exist
in the stack. Besides, it is again ill-defined which
of several pointers that compare equal is selected. It is probably best to
not assume anything about the selection for cases where there is no
match.