---
name: "libressl-BIO_push"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-BIO_push"
---

# libressl-BIO\_push(3)

manipulate BIO chains

## NAME

**BIO\_push**, **BIO\_pop**, **BIO\_set\_next** – manipulate BIO chains

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#include \<openssl/bio.h\>**

*BIO* *\**\

**BIO\_push**(*BIO \*b*, *BIO \*new\_tail*);

*BIO* *\**\

**BIO\_pop**(*BIO \*b*);

*void*\

**BIO\_set\_next**(*BIO \*b*, *BIO \*new\_tail*);

## DESCRIPTION

BIOs can be joined together to form chains. A chain normally consists of one or more filter BIOs and one source/sink BIO at the end. Data read from or written to the first BIO traverses the chain to the end.

Every BIO is a member of exactly one chain. It is either at the beginning of its chain or there is exactly one preceding BIO. It is either at the end of its chain or there is exactly one following BIO. If there is neither a preceding nor a following BIO, it can be regarded as a chain with one member. Every chain has exactly one beginning and exactly one end.

**BIO\_push**() appends the chain starting at *new\_tail* to the end of the chain that contains *b*. Unless *b* is NULL, it then calls BIO\_ctrl(3) on *b* with an argument of BIO\_CTRL\_PUSH. If *b* or *new\_tail* is NULL, nothing is appended.

In LibreSSL, if *new\_tail* is not at the beginning of its chain, the head of that chain up to but not including *new\_tail* is cut off and becomes a separate chain. For portability, it is best to make sure that *new\_tail* is at the beginning of its chain before calling **BIO\_push**().

**BIO\_pop**() removes the BIO *b* from its chain. Despite the word “pop” in the function name, *b* can be at the beginning, in the middle, or at the end of its chain. Before removal, BIO\_ctrl(3) is called on *b* with an argument of BIO\_CTRL\_POP. The removed BIO *b* becomes the only member of its own chain and can thus be freed or attached to a different chain. If *b* is NULL, no action occurs.

**BIO\_set\_next**() appends the chain starting with *new\_tail* to the chain ending with *b*.

In LibreSSL, if *new\_tail* is not at the beginning of its chain, the head of that chain up to but not including *new\_tail* is cut off and becomes a separate chain, and if *b* is not at the end of its chain, the tail of that chain starting after *b* is cut off and becomes a separate chain.

For portability, it is best to make sure that *b* is at the end of its chain and that *new\_tail* is at the beginning of its chain before calling **BIO\_set\_next**() and to avoid calling **BIO\_pop**() on *new\_tail* afterwards.

In LibreSSL, the only built-in BIO type for which BIO\_ctrl(3) calls with an argument of BIO\_CTRL\_PUSH or BIO\_CTRL\_POP have any effect is BIO\_f\_ssl(3).

## RETURN VALUES

**BIO\_push**() returns *b* if it is not NULL or *new\_tail* if it is.

**BIO\_pop**() returns the BIO that followed *b* in its chain, or NULL if *b* is NULL or was at the end of its chain.

## EXAMPLES

For these examples suppose **md1** and **md2** are digest BIOs, **b64** is a Base64 BIO and **f** is a file BIO (see BIO\_f\_md(3), BIO\_f\_base64(3), and BIO\_s\_file(3), respectively).

If the call

```
BIO_push(b64, f);
```

is made then the new chain will be **b64-f**. After making the calls

```
BIO_push(md2, b64);
BIO_push(md1, md2);
```

the new chain is **md1-md2-b64-f**. Data written to **md1** will be digested by **md1** and **md2**, Base64-encoded and written to **f**.

It should be noted that reading causes data to pass in the reverse direction. That is, data is read from **f**, Base64-decoded and digested by **md1** and **md2**. If this call is made:

```
BIO_pop(md2);
```

The call will return **b64** and the new chain will be **md1-b64-f**; data can be written to **md1** as before.

## SEE ALSO

BIO\_find\_type(3), BIO\_new(3), BIO\_read(3)

## HISTORY

**BIO\_push**() first appeared in SSLeay 0.6.0. **BIO\_pop**() first appeared in SSLeay 0.6.4. Both functions have been available since OpenBSD 2.4.

**BIO\_set\_next**() first appeared in OpenSSL 1.1.0 and has been available since OpenBSD 7.1.

## CAVEATS

Creating a cyclic chain results in undefined behavior. For example, infinite recursion or infinite loops may ensue.

If it is unknown whether *b* and *new\_tail* are already members of the same chain and whether joining them would create a cycle, the calling code can use the following safe idiom:

```
BIO *btest;
for (btest = new_tail; btest != NULL; btest = BIO_next(btest))
	if (btest == b)
		/* Bail out because this would create a cycle. */
BIO_push(b, new_tail);  /* This is now safe. */
```

The same idiom can be used with **BIO\_set\_next**() instead of **BIO\_push**().

Often, the safe idiom is not needed because it is already known that *b* and *new\_tail* are not members of the same chain, for example when *b* or *new\_tail* was created right before.
