Sortix volatile manual
This manual documents Sortix volatile, a development build that has not been officially released. You can instead view this document in the latest official manual.
| OPENSSL_SK_NEW(3) | Library Functions Manual | OPENSSL_SK_NEW(3) | 
NAME
sk_new_null,
    sk_new, sk_set_cmp_func,
    sk_dup, sk_free,
    sk_pop_free, sk_num,
    sk_value, sk_find,
    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
SYNOPSIS
#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);
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);
DESCRIPTION
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_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(), or
    sk_find() 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.
RETURN VALUES
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_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.
SEE ALSO
HISTORY
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.
BUGS
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() 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.
| March 4, 2024 | Sortix 1.1.0-dev | 
