STK(3ast) STK(3ast)

# [NAME](#NAME)

**stk** - data stack storage library

# [SYNOPSIS](#SYNOPSIS)

```

#include <stk.h>
Stk_t *stkopen(int flags);
void stkoverflow(Stk_t *stack, void *(overflow)(size_t));
Stk_t *stkinstall(Stk_t *stack, char *(overflow)(size_t));
int stkclose(Stk_t *stack);
unsigned int stklink(Stk_t *stack)
void *stkalloc(Stk_t *stack, unsigned size);
char *stkcopy(Stk_t *stack, const char *string);
void *stkset(Stk_t *stack, void *address, unsigned offset);
void *stkseek(Stk_t *stack, unsigned offset);
int stktell(Stk_t *stack);
char *stkptr(Stk_t *stack, unsigned offset);
void *stkfreeze(Stk_t *stack, unsigned extra);
int stkon(Stk *stack, char* addr)
```

# [DESCRIPTION](#DESCRIPTION)

**stk** is a package of routines designed to provide efficient stack oriented dynamic storage. A stack abstraction consists of an ordered list of contiguous memory regions, called stack frames, that can hold objects of arbitrary size. A stack is represented by the type **Stk\_t** defined in the header **&lt;stk.h&gt;**. The type **Stk\_t** is compatible with the type **Sfio\_t** defined by the [**sfio**(3)](/man/os/ksh/sfio.3) library. There is a preset initial stack which can be referenced by the constant **stkstd** (stack standard).

Objects of variable size can be added to a stack, and programs can reference these objects directly with pointers. In addition, the last object on the stack (referred to here as the current object) can be built incrementally. The current object has an associated offset that determines its current size. While the current object is being built incrementally, its location might change so that it is necessary to reference the object with relative offsets ranging from zero to the current offset of the object.

The [**sfio**(3)](/man/os/ksh/sfio.3) output functions can be used to build the current object incrementally. An object that is built incrementally on the stack will always occupy contiguous memory within a stack frame, but until **stkfreeze**() is called, the location in memory for the object can change. There is a current offset associated with the current object that determines where subsequent operations apply. Initially, this offset is zero, and the offset changes as a result of the operations you specify.

## [Descriptions of the functions](#Descriptions_of_the_functions)

The **stkopen**() function creates a new stack. The *flags* argument is an options bitmask. If the **STK\_SMALL** bit is set, the stack allocates memory in small blocks, optimizing memory usage at the expense of performance. If the **STK\_NULL** bit is set, a stack overflow will cause stack operations to return a null pointer instead of throwing an exception. If the **STK\_NULL** bit is not set and the **stkstd** stack has a custom overflow function set (see **stkoverflow**() below), then the new stack inherits the pointer to that overflow function. If successful, **stkopen**() returns a pointer to a stack whose reference count is 1. Otherwise, **stkopen**() returns a null pointer.

The **stkoverflow**() function specifies a function that will be called whenever [**malloc**(3)](/man/os/ksh/malloc.3) fails while trying to grow the stack. The *overflow* function will be called with the size that was passed to [**malloc**(3)](/man/os/ksh/malloc.3). The *overflow* function can call [**exit**(3)](/man/os/ksh/exit.3), call [**longjmp**(3)](/man/os/ksh/longjmp.3) or return. If the *overflow* function returns, it must return a pointer to a memory region of the given size. If *overflow* is **NULL**, then the stack overflow action is reset to the default. If the stack was opened with the **STK\_NULL** option, the default is to return a null pointer, otherwise the default is to write an error to standard error and to call [**exit**(2)](/man/os/ksh/exit.2) with a non-zero exit value.

The **stkinstall**() function is deprecated and provided for backward compatibility. **stkinstall**() makes **stkstd** refer to the specified *stack* pointer and returns a pointer to the previous **stkstd** stack. If the *overflow* argument is not null and the stack was not opened with the **STK\_NULL** option, then *overflow* sets the overflow action (see **overflow**() above). When *stack* is a null pointer, the **stkstd** stack is not changed but the *overflow* function for the **stkstd** stack can be changed and a pointer to the **stkstd** stack is returned. (Current usage is simply passing the pointer to the desired stack to the **stk** functions, and using **stkoverflow**() to set the stack overflow function).

The **stkclose**() function decrements the reference count and frees the memory associated with the specified stack when the reference count is zero. The effect of subsequent references to objects on the stack is undefined.

The **stklink**() function increases the reference count for the given *stack* and returns the increased count.

The **stkalloc**() function returns an aligned pointer to space on the active stack that can be used to hold any object of the given *size*. **stkalloc**() is similar to [**malloc**(3)](/man/os/ksh/malloc.3) except that individual items returned by **stkalloc**() can not be freed. **stkalloc**() causes the offset of the current object to be set to zero.

The **stkcopy**() function copies the given string onto the stack and returns a pointer to the *string* on the stack. **stkcopy**() causes the offset of the current object to be set to zero.

The **stkset**() function finds the frame containing the given *address*, frees all frames that were created after the one containing the given *address*, and sets the current object to the given *address*. The top of the current object is set to *offset* bytes from current object. If *address* is null, the stack is reset to the beginning. If it is non-null, but is not the address of an object on the stack, the program aborts and dumps core.

The **stkseek**() function is used set the offset for the current object. The *offset* argument to **stkseek**() specifies the new offset for the current object. The frame will be extended or moved if **offset** causes the new current offset to extend beyond the current frame. **stkseek**() returns a pointer to the beginning of the current object.

The **stktell**() function gives the offset of the current object.

The **stkptr**() function converts the given **offset** for the current object into a memory address on the stack. This address is only valid until another stack operation is given. The result is not defined if *offset* exceeds the size of the current object. This function returns a **char** pointer instead of **void** pointer to make it easy to dereference the return value directly and read an individual byte on the stack.

The **stkfreeze**() function terminates the current object on the stack and returns a pointer to the beginning of this object. If *extra* is non-zero, *extra* bytes are added to the stack before the current object is terminated. The first added byte will contain zero and the contents of the remaining bytes are undefined.

The **stkon**() function returns non-zero if the address given by *addr* is on the stack *stack* and **0** otherwise.

# [HISTORY](#HISTORY)

The **stk** interface was derived from similar routines in the KornShell code that is used for building parse trees and carrying out expansions. It provides an efficient mechanism for grouping dynamically allocated objects so that they can be freed all at once rather than individually.

In 2024, as part of changes made by Martijn Dekker &lt;martijn@inlv.org&gt; for ksh 93u+m, the return types of **stkalloc**(), **stkset**(), **stkseek**() and **stkfreeze**() were changed from **char\*** to **void\***, the **stkoverflow**() function was added, and the **stkinstall**() function was deprecated.

# [AUTHOR](#AUTHOR)

David Korn

# [SEE ALSO](#SEE_ALSO)

[**exit**(2)](/man/os/ksh/exit.2), [**longjmp**(3)](/man/os/ksh/longjmp.3), [**malloc**(3)](/man/os/ksh/malloc.3), [**sfio**(3)](/man/os/ksh/sfio.3)

---

Document: stk(3ast) from ksh 1.0.10-r37 (Chainguard OS)
Source: https://github.com/ksh93/ksh
