sync
This commit is contained in:
parent
451579e149
commit
a2dd1eda92
89 changed files with 1343 additions and 775 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: crypto_init.c,v 1.8 2023/05/08 13:53:26 tb Exp $ */
|
||||
/* $OpenBSD: crypto_init.c,v 1.9 2023/06/19 18:32:05 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2018 Bob Beck <beck@openbsd.org>
|
||||
*
|
||||
|
@ -21,7 +21,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <openssl/conf.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
|
@ -79,7 +81,9 @@ OPENSSL_cleanup(void)
|
|||
ERR_free_strings();
|
||||
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_cleanup();
|
||||
#endif
|
||||
EVP_cleanup();
|
||||
x509_issuer_cache_free();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_lib.c,v 1.57 2023/05/04 13:51:59 tb Exp $ */
|
||||
/* $OpenBSD: ec_lib.c,v 1.58 2023/06/20 14:37:15 tb Exp $ */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
|
@ -236,7 +236,8 @@ EC_METHOD_get_field_type(const EC_METHOD *meth)
|
|||
}
|
||||
|
||||
/*
|
||||
* Try computing the cofactor from generator order n and field cardinality q.
|
||||
* If there is a user-provided cofactor, sanity check and use it. Otherwise
|
||||
* try computing the cofactor from generator order n and field cardinality q.
|
||||
* This works for all curves of cryptographic interest.
|
||||
*
|
||||
* Hasse's theorem: | h * n - (q + 1) | <= 2 * sqrt(q)
|
||||
|
@ -250,38 +251,43 @@ EC_METHOD_get_field_type(const EC_METHOD *meth)
|
|||
* Otherwise, zero cofactor and return success.
|
||||
*/
|
||||
static int
|
||||
ec_guess_cofactor(EC_GROUP *group)
|
||||
ec_set_cofactor(EC_GROUP *group, const BIGNUM *in_cofactor)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *q = NULL;
|
||||
BIGNUM *cofactor;
|
||||
int ret = 0;
|
||||
|
||||
BN_zero(&group->cofactor);
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((cofactor = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Unfortunately, the cofactor is an optional field in many standards.
|
||||
* Internally, the library uses a 0 cofactor as a marker for "unknown
|
||||
* cofactor". So accept in_cofactor == NULL or in_cofactor >= 0.
|
||||
*/
|
||||
if (in_cofactor != NULL && !BN_is_zero(in_cofactor)) {
|
||||
if (BN_is_negative(in_cofactor)) {
|
||||
ECerror(EC_R_UNKNOWN_COFACTOR);
|
||||
goto err;
|
||||
}
|
||||
if (!bn_copy(cofactor, in_cofactor))
|
||||
goto err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the cofactor is too large, we cannot guess it and default to zero.
|
||||
* The RHS of below is a strict overestimate of log(4 * sqrt(q)).
|
||||
*/
|
||||
if (BN_num_bits(&group->order) <=
|
||||
(BN_num_bits(&group->field) + 1) / 2 + 3) {
|
||||
BN_zero(&group->cofactor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((q = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* Set q = 2**m for binary fields; q = p otherwise. */
|
||||
if (group->meth->field_type == NID_X9_62_characteristic_two_field) {
|
||||
BN_zero(q);
|
||||
if (!BN_set_bit(q, BN_num_bits(&group->field) - 1))
|
||||
goto err;
|
||||
} else {
|
||||
if (!bn_copy(q, &group->field))
|
||||
goto err;
|
||||
}
|
||||
(BN_num_bits(&group->field) + 1) / 2 + 3)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Compute
|
||||
|
@ -289,17 +295,26 @@ ec_guess_cofactor(EC_GROUP *group)
|
|||
*/
|
||||
|
||||
/* h = n/2 */
|
||||
if (!BN_rshift1(&group->cofactor, &group->order))
|
||||
if (!BN_rshift1(cofactor, &group->order))
|
||||
goto err;
|
||||
/* h = 1 + n/2 */
|
||||
if (!BN_add(&group->cofactor, &group->cofactor, BN_value_one()))
|
||||
if (!BN_add_word(cofactor, 1))
|
||||
goto err;
|
||||
/* h = q + 1 + n/2 */
|
||||
if (!BN_add(&group->cofactor, &group->cofactor, q))
|
||||
if (!BN_add(cofactor, cofactor, &group->field))
|
||||
goto err;
|
||||
/* h = (q + 1 + n/2) / n */
|
||||
if (!BN_div_ct(&group->cofactor, NULL, &group->cofactor, &group->order,
|
||||
ctx))
|
||||
if (!BN_div_ct(cofactor, NULL, cofactor, &group->order, ctx))
|
||||
goto err;
|
||||
|
||||
done:
|
||||
/* Use Hasse's theorem to bound the cofactor. */
|
||||
if (BN_num_bits(cofactor) > BN_num_bits(&group->field) + 1) {
|
||||
ECerror(EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!bn_copy(&group->cofactor, cofactor))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
@ -308,9 +323,6 @@ ec_guess_cofactor(EC_GROUP *group)
|
|||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
if (ret != 1)
|
||||
BN_zero(&group->cofactor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -339,16 +351,6 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unfortunately, the cofactor is an optional field in many standards.
|
||||
* Internally, the library uses a 0 cofactor as a marker for "unknown
|
||||
* cofactor". So accept cofactor == NULL or cofactor >= 0.
|
||||
*/
|
||||
if (cofactor != NULL && BN_is_negative(cofactor)) {
|
||||
ECerror(EC_R_UNKNOWN_COFACTOR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (group->generator == NULL) {
|
||||
group->generator = EC_POINT_new(group);
|
||||
if (group->generator == NULL)
|
||||
|
@ -360,19 +362,9 @@ EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
|
|||
if (!bn_copy(&group->order, order))
|
||||
return 0;
|
||||
|
||||
/* Either take the provided positive cofactor, or try to compute it. */
|
||||
if (cofactor != NULL && !BN_is_zero(cofactor)) {
|
||||
if (!bn_copy(&group->cofactor, cofactor))
|
||||
return 0;
|
||||
} else if (!ec_guess_cofactor(group))
|
||||
if (!ec_set_cofactor(group, cofactor))
|
||||
return 0;
|
||||
|
||||
/* Use Hasse's theorem to bound the cofactor. */
|
||||
if (BN_num_bits(&group->cofactor) > BN_num_bits(&group->field) + 1) {
|
||||
ECerror(EC_R_INVALID_GROUP_ORDER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: pmeth_lib.c,v 1.27 2022/12/26 07:18:52 jmc Exp $ */
|
||||
/* $OpenBSD: pmeth_lib.c,v 1.31 2023/06/20 14:14:00 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
*/
|
||||
|
@ -151,69 +151,65 @@ EVP_PKEY_meth_find(int type)
|
|||
}
|
||||
|
||||
static EVP_PKEY_CTX *
|
||||
int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
||||
evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *engine, int id)
|
||||
{
|
||||
EVP_PKEY_CTX *ret;
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
const EVP_PKEY_METHOD *pmeth;
|
||||
|
||||
if (id == -1) {
|
||||
if (!pkey || !pkey->ameth)
|
||||
if (pkey == NULL || pkey->ameth == NULL)
|
||||
return NULL;
|
||||
id = pkey->ameth->pkey_id;
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (pkey && pkey->engine)
|
||||
e = pkey->engine;
|
||||
/* Try to find an ENGINE which implements this method */
|
||||
if (e) {
|
||||
if (!ENGINE_init(e)) {
|
||||
if (pkey != NULL && pkey->engine != NULL)
|
||||
engine = pkey->engine;
|
||||
/* Try to find an ENGINE which implements this method. */
|
||||
if (engine != NULL) {
|
||||
if (!ENGINE_init(engine)) {
|
||||
EVPerror(ERR_R_ENGINE_LIB);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
e = ENGINE_get_pkey_meth_engine(id);
|
||||
engine = ENGINE_get_pkey_meth_engine(id);
|
||||
|
||||
/* If an ENGINE handled this method look it up. Otherwise
|
||||
* use internal tables.
|
||||
*/
|
||||
|
||||
if (e)
|
||||
pmeth = ENGINE_get_pkey_meth(e, id);
|
||||
/* Look up method handler in ENGINE or use internal tables. */
|
||||
if (engine != NULL)
|
||||
pmeth = ENGINE_get_pkey_meth(engine, id);
|
||||
else
|
||||
#endif
|
||||
pmeth = EVP_PKEY_meth_find(id);
|
||||
|
||||
if (pmeth == NULL) {
|
||||
EVPerror(EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = malloc(sizeof(EVP_PKEY_CTX));
|
||||
if (ret == NULL) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(e);
|
||||
#endif
|
||||
if ((pkey_ctx = calloc(1, sizeof(*pkey_ctx))) == NULL) {
|
||||
EVPerror(ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
ret->engine = e;
|
||||
ret->pmeth = pmeth;
|
||||
ret->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
ret->pkey = pkey;
|
||||
ret->peerkey = NULL;
|
||||
ret->pkey_gencb = 0;
|
||||
if (pkey)
|
||||
CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
ret->data = NULL;
|
||||
pkey_ctx->engine = engine;
|
||||
engine = NULL;
|
||||
pkey_ctx->pmeth = pmeth;
|
||||
pkey_ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
if ((pkey_ctx->pkey = pkey) != NULL)
|
||||
EVP_PKEY_up_ref(pkey_ctx->pkey);
|
||||
|
||||
if (pmeth->init) {
|
||||
if (pmeth->init(ret) <= 0) {
|
||||
EVP_PKEY_CTX_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
if (pmeth->init != NULL) {
|
||||
if (pmeth->init(pkey_ctx) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return pkey_ctx;
|
||||
|
||||
err:
|
||||
EVP_PKEY_CTX_free(pkey_ctx);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(engine);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_PKEY_METHOD*
|
||||
|
@ -261,57 +257,54 @@ EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
|
|||
}
|
||||
|
||||
EVP_PKEY_CTX *
|
||||
EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
|
||||
EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *engine)
|
||||
{
|
||||
return int_ctx_new(pkey, e, -1);
|
||||
return evp_pkey_ctx_new(pkey, engine, -1);
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *
|
||||
EVP_PKEY_CTX_new_id(int id, ENGINE *e)
|
||||
EVP_PKEY_CTX_new_id(int id, ENGINE *engine)
|
||||
{
|
||||
return int_ctx_new(NULL, e, id);
|
||||
return evp_pkey_ctx_new(NULL, engine, id);
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *
|
||||
EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
|
||||
{
|
||||
EVP_PKEY_CTX *rctx;
|
||||
EVP_PKEY_CTX *rctx = NULL;
|
||||
|
||||
if (!pctx->pmeth || !pctx->pmeth->copy)
|
||||
return NULL;
|
||||
if (pctx->pmeth == NULL || pctx->pmeth->copy == NULL)
|
||||
goto err;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Make sure it's safe to copy a pkey context using an ENGINE */
|
||||
if (pctx->engine && !ENGINE_init(pctx->engine)) {
|
||||
if (pctx->engine != NULL && !ENGINE_init(pctx->engine)) {
|
||||
EVPerror(ERR_R_ENGINE_LIB);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
rctx = malloc(sizeof(EVP_PKEY_CTX));
|
||||
if (!rctx)
|
||||
return NULL;
|
||||
if ((rctx = calloc(1, sizeof(*rctx))) == NULL) {
|
||||
EVPerror(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rctx->pmeth = pctx->pmeth;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
rctx->engine = pctx->engine;
|
||||
#endif
|
||||
|
||||
if (pctx->pkey)
|
||||
CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
if ((rctx->pkey = pctx->pkey) != NULL)
|
||||
EVP_PKEY_up_ref(rctx->pkey);
|
||||
if ((rctx->peerkey = pctx->peerkey) != NULL)
|
||||
EVP_PKEY_up_ref(rctx->peerkey);
|
||||
|
||||
rctx->pkey = pctx->pkey;
|
||||
|
||||
if (pctx->peerkey)
|
||||
CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
|
||||
rctx->peerkey = pctx->peerkey;
|
||||
|
||||
rctx->data = NULL;
|
||||
rctx->app_data = NULL;
|
||||
rctx->operation = pctx->operation;
|
||||
|
||||
if (pctx->pmeth->copy(rctx, pctx) > 0)
|
||||
return rctx;
|
||||
if (pctx->pmeth->copy(rctx, pctx) <= 0)
|
||||
goto err;
|
||||
|
||||
return rctx;
|
||||
|
||||
err:
|
||||
EVP_PKEY_CTX_free(rctx);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: x509_purp.c,v 1.25 2023/04/23 21:49:15 job Exp $ */
|
||||
/* $OpenBSD: x509_purp.c,v 1.26 2023/06/20 14:21:19 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2001.
|
||||
*/
|
||||
|
@ -449,6 +449,7 @@ x509v3_cache_extensions_internal(X509 *x)
|
|||
ASN1_BIT_STRING *ns;
|
||||
EXTENDED_KEY_USAGE *extusage;
|
||||
X509_EXTENSION *ex;
|
||||
long version;
|
||||
int i;
|
||||
|
||||
if (x->ex_flags & EXFLAG_SET)
|
||||
|
@ -456,12 +457,18 @@ x509v3_cache_extensions_internal(X509 *x)
|
|||
|
||||
X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL);
|
||||
|
||||
/* V1 should mean no extensions ... */
|
||||
if (X509_get_version(x) == 0) {
|
||||
version = X509_get_version(x);
|
||||
if (version < 0 || version > 2)
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
if (version == 0) {
|
||||
x->ex_flags |= EXFLAG_V1;
|
||||
if (X509_get_ext_count(x) != 0)
|
||||
/* UIDs may only appear in v2 or v3 certs */
|
||||
if (x->cert_info->issuerUID != NULL ||
|
||||
x->cert_info->subjectUID != NULL)
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
if (version != 2 && X509_get_ext_count(x) != 0)
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
|
||||
/* Handle basic constraints */
|
||||
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) {
|
||||
|
|
|
@ -18,13 +18,28 @@
|
|||
getptmfd;
|
||||
getrawpartition;
|
||||
ibuf_add;
|
||||
ibuf_add_buf;
|
||||
ibuf_add_n8;
|
||||
ibuf_add_n16;
|
||||
ibuf_add_n32;
|
||||
ibuf_add_n64;
|
||||
ibuf_add_zero;
|
||||
ibuf_close;
|
||||
ibuf_data;
|
||||
ibuf_dynamic;
|
||||
ibuf_fd_avail;
|
||||
ibuf_fd_get;
|
||||
ibuf_fd_set;
|
||||
ibuf_free;
|
||||
ibuf_left;
|
||||
ibuf_open;
|
||||
ibuf_reserve;
|
||||
ibuf_seek;
|
||||
ibuf_set;
|
||||
ibuf_set_n8;
|
||||
ibuf_set_n16;
|
||||
ibuf_set_n32;
|
||||
ibuf_set_n64;
|
||||
ibuf_size;
|
||||
ibuf_write;
|
||||
imsg_add;
|
||||
|
@ -32,6 +47,7 @@
|
|||
imsg_close;
|
||||
imsg_compose;
|
||||
imsg_composev;
|
||||
imsg_compose_ibuf;
|
||||
imsg_create;
|
||||
imsg_fd_overhead;
|
||||
imsg_flush;
|
||||
|
@ -47,7 +63,6 @@
|
|||
logout;
|
||||
logwtmp;
|
||||
msgbuf_clear;
|
||||
msgbuf_drain;
|
||||
msgbuf_init;
|
||||
msgbuf_write;
|
||||
ober_add_bitstring;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: imsg-buffer.c,v 1.15 2023/05/23 12:41:28 claudio Exp $ */
|
||||
/* $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <endian.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
@ -32,6 +33,7 @@
|
|||
static int ibuf_realloc(struct ibuf *, size_t);
|
||||
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
|
||||
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
|
||||
static void msgbuf_drain(struct msgbuf *, size_t);
|
||||
|
||||
struct ibuf *
|
||||
ibuf_open(size_t len)
|
||||
|
@ -99,23 +101,6 @@ ibuf_realloc(struct ibuf *buf, size_t len)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add(struct ibuf *buf, const void *data, size_t len)
|
||||
{
|
||||
if (len > SIZE_MAX - buf->wpos) {
|
||||
errno = ERANGE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (buf->wpos + len > buf->size)
|
||||
if (ibuf_realloc(buf, len) == -1)
|
||||
return (-1);
|
||||
|
||||
memcpy(buf->buf + buf->wpos, data, len);
|
||||
buf->wpos += len;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *
|
||||
ibuf_reserve(struct ibuf *buf, size_t len)
|
||||
{
|
||||
|
@ -136,16 +121,156 @@ ibuf_reserve(struct ibuf *buf, size_t len)
|
|||
return (b);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add(struct ibuf *buf, const void *data, size_t len)
|
||||
{
|
||||
void *b;
|
||||
|
||||
if ((b = ibuf_reserve(buf, len)) == NULL)
|
||||
return (-1);
|
||||
|
||||
memcpy(b, data, len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
|
||||
{
|
||||
return ibuf_add(buf, from->buf, from->wpos);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add_n8(struct ibuf *buf, uint64_t value)
|
||||
{
|
||||
uint8_t v;
|
||||
|
||||
if (value > UINT8_MAX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
v = value;
|
||||
return ibuf_add(buf, &v, sizeof(v));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add_n16(struct ibuf *buf, uint64_t value)
|
||||
{
|
||||
uint16_t v;
|
||||
|
||||
if (value > UINT16_MAX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
v = htobe16(value);
|
||||
return ibuf_add(buf, &v, sizeof(v));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add_n32(struct ibuf *buf, uint64_t value)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
if (value > UINT32_MAX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
v = htobe32(value);
|
||||
return ibuf_add(buf, &v, sizeof(v));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add_n64(struct ibuf *buf, uint64_t value)
|
||||
{
|
||||
value = htobe64(value);
|
||||
return ibuf_add(buf, &value, sizeof(value));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_add_zero(struct ibuf *buf, size_t len)
|
||||
{
|
||||
void *b;
|
||||
|
||||
if ((b = ibuf_reserve(buf, len)) == NULL)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *
|
||||
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
|
||||
{
|
||||
/* only allowed to seek in already written parts */
|
||||
if (len > SIZE_MAX - pos || pos + len > buf->wpos)
|
||||
if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
|
||||
errno = ERANGE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (buf->buf + pos);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
|
||||
{
|
||||
void *b;
|
||||
|
||||
if ((b = ibuf_seek(buf, pos, len)) == NULL)
|
||||
return (-1);
|
||||
|
||||
memcpy(b, data, len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
|
||||
{
|
||||
uint8_t v;
|
||||
|
||||
if (value > UINT8_MAX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
v = value;
|
||||
return (ibuf_set(buf, pos, &v, sizeof(v)));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
|
||||
{
|
||||
uint16_t v;
|
||||
|
||||
if (value > UINT16_MAX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
v = htobe16(value);
|
||||
return (ibuf_set(buf, pos, &v, sizeof(v)));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
if (value > UINT32_MAX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
v = htobe32(value);
|
||||
return (ibuf_set(buf, pos, &v, sizeof(v)));
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
|
||||
{
|
||||
value = htobe64(value);
|
||||
return (ibuf_set(buf, pos, &value, sizeof(value)));
|
||||
}
|
||||
|
||||
void *
|
||||
ibuf_data(struct ibuf *buf)
|
||||
{
|
||||
return (buf->buf);
|
||||
}
|
||||
|
||||
size_t
|
||||
ibuf_size(struct ibuf *buf)
|
||||
{
|
||||
|
@ -164,6 +289,45 @@ ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
|
|||
ibuf_enqueue(msgbuf, buf);
|
||||
}
|
||||
|
||||
void
|
||||
ibuf_free(struct ibuf *buf)
|
||||
{
|
||||
if (buf == NULL)
|
||||
return;
|
||||
#ifdef NOTYET
|
||||
if (buf->fd != -1)
|
||||
close(buf->fd);
|
||||
#endif
|
||||
freezero(buf->buf, buf->size);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_fd_avail(struct ibuf *buf)
|
||||
{
|
||||
return (buf->fd != -1);
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_fd_get(struct ibuf *buf)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = buf->fd;
|
||||
#ifdef NOTYET
|
||||
buf->fd = -1;
|
||||
#endif
|
||||
return (fd);
|
||||
}
|
||||
|
||||
void
|
||||
ibuf_fd_set(struct ibuf *buf, int fd)
|
||||
{
|
||||
if (buf->fd != -1)
|
||||
close(buf->fd);
|
||||
buf->fd = fd;
|
||||
}
|
||||
|
||||
int
|
||||
ibuf_write(struct msgbuf *msgbuf)
|
||||
{
|
||||
|
@ -200,15 +364,6 @@ again:
|
|||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ibuf_free(struct ibuf *buf)
|
||||
{
|
||||
if (buf == NULL)
|
||||
return;
|
||||
freezero(buf->buf, buf->size);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void
|
||||
msgbuf_init(struct msgbuf *msgbuf)
|
||||
{
|
||||
|
@ -217,7 +372,7 @@ msgbuf_init(struct msgbuf *msgbuf)
|
|||
TAILQ_INIT(&msgbuf->bufs);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
|
||||
{
|
||||
struct ibuf *buf, *next;
|
||||
|
@ -326,8 +481,10 @@ ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
|
|||
{
|
||||
TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
|
||||
|
||||
if (buf->fd != -1)
|
||||
if (buf->fd != -1) {
|
||||
close(buf->fd);
|
||||
buf->fd = -1;
|
||||
}
|
||||
|
||||
msgbuf->queued--;
|
||||
ibuf_free(buf);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: imsg.c,v 1.18 2023/03/08 04:43:05 guenther Exp $ */
|
||||
/* $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
|
@ -175,8 +175,7 @@ imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
|
|||
if (imsg_add(wbuf, data, datalen) == -1)
|
||||
return (-1);
|
||||
|
||||
wbuf->fd = fd;
|
||||
|
||||
ibuf_fd_set(wbuf, fd);
|
||||
imsg_close(ibuf, wbuf);
|
||||
|
||||
return (1);
|
||||
|
@ -199,13 +198,49 @@ imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
|
|||
if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
|
||||
return (-1);
|
||||
|
||||
wbuf->fd = fd;
|
||||
|
||||
ibuf_fd_set(wbuf, fd);
|
||||
imsg_close(ibuf, wbuf);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
|
||||
pid_t pid, struct ibuf *buf)
|
||||
{
|
||||
struct ibuf *wbuf = NULL;
|
||||
struct imsg_hdr hdr;
|
||||
int save_errno;
|
||||
|
||||
if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
|
||||
errno = ERANGE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hdr.type = type;
|
||||
hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
|
||||
hdr.flags = 0;
|
||||
hdr.peerid = peerid;
|
||||
if ((hdr.pid = pid) == 0)
|
||||
hdr.pid = ibuf->pid;
|
||||
|
||||
if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
|
||||
goto fail;
|
||||
if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
|
||||
goto fail;
|
||||
|
||||
ibuf_close(&ibuf->w, wbuf);
|
||||
ibuf_close(&ibuf->w, buf);
|
||||
return (1);
|
||||
|
||||
fail:
|
||||
save_errno = errno;
|
||||
ibuf_free(buf);
|
||||
ibuf_free(wbuf);
|
||||
errno = save_errno;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
struct ibuf *
|
||||
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
|
||||
uint16_t datalen)
|
||||
|
@ -252,10 +287,9 @@ imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
|
|||
hdr = (struct imsg_hdr *)msg->buf;
|
||||
|
||||
hdr->flags &= ~IMSGF_HASFD;
|
||||
if (msg->fd != -1)
|
||||
if (ibuf_fd_avail(msg))
|
||||
hdr->flags |= IMSGF_HASFD;
|
||||
|
||||
hdr->len = (uint16_t)msg->wpos;
|
||||
hdr->len = ibuf_size(msg);
|
||||
|
||||
ibuf_close(&ibuf->w, msg);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: imsg.h,v 1.6 2021/01/13 09:56:28 claudio Exp $ */
|
||||
/* $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
|
||||
|
@ -80,21 +80,35 @@ struct imsg {
|
|||
|
||||
struct iovec;
|
||||
|
||||
/* buffer.c */
|
||||
/* imsg-buffer.c */
|
||||
struct ibuf *ibuf_open(size_t);
|
||||
struct ibuf *ibuf_dynamic(size_t, size_t);
|
||||
int ibuf_add(struct ibuf *, const void *, size_t);
|
||||
int ibuf_add_buf(struct ibuf *, const struct ibuf *);
|
||||
int ibuf_add_zero(struct ibuf *, size_t);
|
||||
int ibuf_add_n8(struct ibuf *, uint64_t);
|
||||
int ibuf_add_n16(struct ibuf *, uint64_t);
|
||||
int ibuf_add_n32(struct ibuf *, uint64_t);
|
||||
int ibuf_add_n64(struct ibuf *, uint64_t);
|
||||
void *ibuf_reserve(struct ibuf *, size_t);
|
||||
void *ibuf_seek(struct ibuf *, size_t, size_t);
|
||||
int ibuf_set(struct ibuf *, size_t, const void *, size_t);
|
||||
int ibuf_set_n8(struct ibuf *, size_t, uint64_t);
|
||||
int ibuf_set_n16(struct ibuf *, size_t, uint64_t);
|
||||
int ibuf_set_n32(struct ibuf *, size_t, uint64_t);
|
||||
int ibuf_set_n64(struct ibuf *, size_t, uint64_t);
|
||||
void *ibuf_data(struct ibuf *);
|
||||
size_t ibuf_size(struct ibuf *);
|
||||
size_t ibuf_left(struct ibuf *);
|
||||
void ibuf_close(struct msgbuf *, struct ibuf *);
|
||||
int ibuf_write(struct msgbuf *);
|
||||
void ibuf_free(struct ibuf *);
|
||||
int ibuf_fd_avail(struct ibuf *);
|
||||
int ibuf_fd_get(struct ibuf *);
|
||||
void ibuf_fd_set(struct ibuf *, int);
|
||||
int ibuf_write(struct msgbuf *);
|
||||
void msgbuf_init(struct msgbuf *);
|
||||
void msgbuf_clear(struct msgbuf *);
|
||||
int msgbuf_write(struct msgbuf *);
|
||||
void msgbuf_drain(struct msgbuf *, size_t);
|
||||
|
||||
/* imsg.c */
|
||||
void imsg_init(struct imsgbuf *, int);
|
||||
|
@ -104,6 +118,8 @@ int imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
|
|||
const void *, uint16_t);
|
||||
int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
|
||||
const struct iovec *, int);
|
||||
int imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
|
||||
struct ibuf *);
|
||||
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
|
||||
int imsg_add(struct ibuf *, const void *, uint16_t);
|
||||
void imsg_close(struct imsgbuf *, struct ibuf *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: imsg_init.3,v 1.25 2022/05/19 08:05:23 stsp Exp $
|
||||
.\" $OpenBSD: imsg_init.3,v 1.28 2023/06/20 06:53:29 jsg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2010 Nicholas Marriott <nicm@openbsd.org>
|
||||
.\"
|
||||
|
@ -14,7 +14,7 @@
|
|||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 19 2022 $
|
||||
.Dd $Mdocdate: June 20 2023 $
|
||||
.Dt IMSG_INIT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -23,6 +23,7 @@
|
|||
.Nm imsg_get ,
|
||||
.Nm imsg_compose ,
|
||||
.Nm imsg_composev ,
|
||||
.Nm imsg_compose_ibuf ,
|
||||
.Nm imsg_create ,
|
||||
.Nm imsg_add ,
|
||||
.Nm imsg_close ,
|
||||
|
@ -32,17 +33,31 @@
|
|||
.Nm ibuf_open ,
|
||||
.Nm ibuf_dynamic ,
|
||||
.Nm ibuf_add ,
|
||||
.Nm ibuf_add_buf ,
|
||||
.Nm ibuf_add_n8 ,
|
||||
.Nm ibuf_add_n16 ,
|
||||
.Nm ibuf_add_n32 ,
|
||||
.Nm ibuf_add_n64 ,
|
||||
.Nm ibuf_add_zero ,
|
||||
.Nm ibuf_reserve ,
|
||||
.Nm ibuf_seek ,
|
||||
.Nm ibuf_set ,
|
||||
.Nm ibuf_set_n8 ,
|
||||
.Nm ibuf_set_n16 ,
|
||||
.Nm ibuf_set_n32 ,
|
||||
.Nm ibuf_set_n64 ,
|
||||
.Nm ibuf_data ,
|
||||
.Nm ibuf_size ,
|
||||
.Nm ibuf_left ,
|
||||
.Nm ibuf_close ,
|
||||
.Nm ibuf_write ,
|
||||
.Nm ibuf_free ,
|
||||
.Nm ibuf_fd_avail ,
|
||||
.Nm ibuf_fd_get ,
|
||||
.Nm ibuf_fd_set ,
|
||||
.Nm ibuf_write ,
|
||||
.Nm msgbuf_init ,
|
||||
.Nm msgbuf_clear ,
|
||||
.Nm msgbuf_write ,
|
||||
.Nm msgbuf_drain
|
||||
.Nm msgbuf_write
|
||||
.Nd IPC messaging functions
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
|
@ -62,6 +77,9 @@
|
|||
.Ft int
|
||||
.Fn imsg_composev "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \
|
||||
"pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt"
|
||||
.Ft int
|
||||
.Fn imsg_compose_ibuf "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \
|
||||
"pid_t pid" "struct ibuf *buf"
|
||||
.Ft "struct ibuf *"
|
||||
.Fn imsg_create "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \
|
||||
"pid_t pid" "uint16_t datalen"
|
||||
|
@ -81,28 +99,57 @@
|
|||
.Fn ibuf_dynamic "size_t len" "size_t max"
|
||||
.Ft int
|
||||
.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len"
|
||||
.Ft int
|
||||
.Fn ibuf_add_buf "struct ibuf *buf" "const struct ibuf *from"
|
||||
.Ft int
|
||||
.Fn ibuf_add_n8 "struct ibuf *buf" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_add_n16 "struct ibuf *buf" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_add_n32 "struct ibuf *buf" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_add_n64 "struct ibuf *buf" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_add_zero "struct ibuf *buf" "size_t len"
|
||||
.Ft "void *"
|
||||
.Fn ibuf_reserve "struct ibuf *buf" "size_t len"
|
||||
.Ft "void *"
|
||||
.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len"
|
||||
.Ft int
|
||||
.Fn ibuf_set "struct ibuf *buf" "size_t pos" "const void *data" \
|
||||
"size_t len"
|
||||
.Ft int
|
||||
.Fn ibuf_set_n8 "struct ibuf *buf" "size_t pos" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_set_n16 "struct ibuf *buf" "size_t pos" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_set_n32 "struct ibuf *buf" "size_t pos" "uint64_t value"
|
||||
.Ft int
|
||||
.Fn ibuf_set_n64 "struct ibuf *buf" "size_t pos" "uint64_t value"
|
||||
.Ft "void *"
|
||||
.Fn ibuf_data "struct ibuf *buf"
|
||||
.Ft size_t
|
||||
.Fn ibuf_size "struct ibuf *buf"
|
||||
.Ft size_t
|
||||
.Fn ibuf_left "struct ibuf *buf"
|
||||
.Ft void
|
||||
.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf"
|
||||
.Ft int
|
||||
.Fn ibuf_write "struct msgbuf *msgbuf"
|
||||
.Ft void
|
||||
.Fn ibuf_free "struct ibuf *buf"
|
||||
.Ft int
|
||||
.Fn ibuf_fd_avail "struct ibuf *buf"
|
||||
.Ft int
|
||||
.Fn ibuf_fd_get "struct ibuf *buf"
|
||||
.Ft void
|
||||
.Fn ibuf_fd_set "struct ibuf *buf" "int fd"
|
||||
.Ft int
|
||||
.Fn ibuf_write "struct msgbuf *msgbuf"
|
||||
.Ft void
|
||||
.Fn msgbuf_init "struct msgbuf *msgbuf"
|
||||
.Ft void
|
||||
.Fn msgbuf_clear "struct msgbuf *msgbuf"
|
||||
.Ft int
|
||||
.Fn msgbuf_write "struct msgbuf *msgbuf"
|
||||
.Ft void
|
||||
.Fn msgbuf_drain "struct msgbuf *msgbuf" "size_t n"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm imsg
|
||||
|
@ -133,7 +180,7 @@ struct imsgbuf {
|
|||
.Ed
|
||||
.Pp
|
||||
.Fn imsg_init
|
||||
is a routine which initializes
|
||||
initializes
|
||||
.Fa ibuf
|
||||
as one side of a channel associated with
|
||||
.Fa fd .
|
||||
|
@ -199,7 +246,7 @@ by adding it to
|
|||
output buffer.
|
||||
.Pp
|
||||
.Fn imsg_compose
|
||||
is a routine which is used to quickly create and queue an imsg.
|
||||
is used to quickly create and queue an imsg.
|
||||
It takes the same parameters as the
|
||||
.Fn imsg_create ,
|
||||
.Fn imsg_add
|
||||
|
@ -223,8 +270,19 @@ It takes the same parameters, except that the ancillary data buffer is specified
|
|||
by
|
||||
.Fa iovec .
|
||||
.Pp
|
||||
.Fn imsg_compose_ibuf
|
||||
is similar to
|
||||
.Fn imsg_compose .
|
||||
It takes the same parameters, except that the ancillary data buffer is specified
|
||||
by an ibuf
|
||||
.Fa buf .
|
||||
This routine returns 1 if it succeeds, \-1 otherwise.
|
||||
In either case the buffer
|
||||
.Fa buf
|
||||
is consumed by the function.
|
||||
.Pp
|
||||
.Fn imsg_flush
|
||||
is a function which calls
|
||||
calls
|
||||
.Fn msgbuf_write
|
||||
in a loop until all imsgs in the output buffer are sent.
|
||||
It returns 0 if it succeeds, \-1 otherwise.
|
||||
|
@ -357,7 +415,34 @@ Buffers allocated with
|
|||
are automatically grown if necessary when data is added.
|
||||
.Pp
|
||||
.Fn ibuf_add
|
||||
is a routine which appends a block of data to
|
||||
appends a block of data to
|
||||
.Fa buf .
|
||||
0 is returned on success and \-1 on failure.
|
||||
.Pp
|
||||
.Fn ibuf_add_buf
|
||||
appends the buffer
|
||||
.Fa from
|
||||
to
|
||||
.Fa buf .
|
||||
0 is returned on success and \-1 on failure.
|
||||
.Pp
|
||||
.Fn ibuf_add_n8 ,
|
||||
.Fn ibuf_add_n16 ,
|
||||
.Fn ibuf_add_n32 ,
|
||||
and
|
||||
.Fn ibuf_add_n64
|
||||
add a 1-byte, 2-byte, 4-byte, and 8-byte
|
||||
.Fa value
|
||||
to
|
||||
.Fa buf
|
||||
in network byte order.
|
||||
This function checks
|
||||
.Fa value
|
||||
to not overflow.
|
||||
0 is returned on success and \-1 on failure.
|
||||
.Pp
|
||||
.Fn ibuf_add_zero
|
||||
appends a block of zeros to
|
||||
.Fa buf .
|
||||
0 is returned on success and \-1 on failure.
|
||||
.Pp
|
||||
|
@ -369,13 +454,45 @@ bytes in
|
|||
A pointer to the start of the reserved space is returned, or NULL on error.
|
||||
.Pp
|
||||
.Fn ibuf_seek
|
||||
is a function which returns a pointer to the part of the buffer at offset
|
||||
returns a pointer to the part of the buffer at offset
|
||||
.Fa pos
|
||||
and of extent
|
||||
.Fa len .
|
||||
NULL is returned if the requested range is outside the part of the buffer
|
||||
in use.
|
||||
.Pp
|
||||
.Fn ibuf_set
|
||||
replaces a part of
|
||||
.Fa buf
|
||||
at offset
|
||||
.Fa pos
|
||||
with the data of extent
|
||||
.Fa len .
|
||||
0 is returned on success and \-1 on failure.
|
||||
.Pp
|
||||
.Fn ibuf_set_n8 ,
|
||||
.Fn ibuf_set_n16 ,
|
||||
.Fn ibuf_seek_set_n32
|
||||
and
|
||||
.Fn ibuf_seek_set_n64
|
||||
replace a 1-byte, 2-byte, 4-byte or 8-byte
|
||||
.Fa value
|
||||
at offset
|
||||
.Fa pos
|
||||
in the buffer
|
||||
.Fa buf
|
||||
in network byte order.
|
||||
This function checks
|
||||
.Fa value
|
||||
to not overflow.
|
||||
0 is returned on success and \-1 on failure.
|
||||
.Pp
|
||||
.Fn ibuf_data
|
||||
returns the pointer to the internal buffer.
|
||||
This function should only be used together with
|
||||
.Fn ibuf_size
|
||||
to process a previously generated buffer.
|
||||
.Pp
|
||||
.Fn ibuf_size
|
||||
and
|
||||
.Fn ibuf_left
|
||||
|
@ -390,6 +507,35 @@ to
|
|||
.Fa msgbuf
|
||||
ready to be sent.
|
||||
.Pp
|
||||
.Fn ibuf_fd_avail ,
|
||||
.Fn ibuf_fd_get
|
||||
and
|
||||
.Fn ibuf_fd_set
|
||||
are functions to check, get and set the file descriptor assigned to
|
||||
.Fa buf .
|
||||
After calling
|
||||
.Fn ibuf_fd_set
|
||||
the file descriptor is part of the
|
||||
.Fa buf
|
||||
and will be transmitted or closed by the ibuf API.
|
||||
Any previously set file descriptor will be closed before assigning a
|
||||
new descriptor.
|
||||
.Fn ibuf_fd_get
|
||||
returns the file descriptor and passes the responsibility to track the
|
||||
descriptor back to the program.
|
||||
.Fn ibuf_fd_avail
|
||||
returns true if there is a file descriptor set on
|
||||
.Fa buf .
|
||||
.Pp
|
||||
.Fn ibuf_free
|
||||
frees
|
||||
.Fa buf
|
||||
and any associated storage, and closes any file descriptor set with
|
||||
.Fn ibuf_fd_set .
|
||||
If
|
||||
.Fa buf
|
||||
is a NULL pointer, no action occurs.
|
||||
.Pp
|
||||
The
|
||||
.Fn ibuf_write
|
||||
routine transmits as many pending buffers as possible from
|
||||
|
@ -402,14 +548,6 @@ Temporary resource shortages are returned with errno
|
|||
.Er EAGAIN
|
||||
and require the application to retry again in the future.
|
||||
.Pp
|
||||
.Fn ibuf_free
|
||||
frees
|
||||
.Fa buf
|
||||
and any associated storage.
|
||||
If
|
||||
.Fa buf
|
||||
is a NULL pointer, no action occurs.
|
||||
.Pp
|
||||
The
|
||||
.Fn msgbuf_init
|
||||
function initializes
|
||||
|
@ -435,15 +573,6 @@ or an EOF condition on the socket is detected.
|
|||
Temporary resource shortages are returned with errno
|
||||
.Er EAGAIN
|
||||
and require the application to retry again in the future.
|
||||
.Pp
|
||||
.Fn msgbuf_drain
|
||||
discards data from buffers queued in
|
||||
.Fa msgbuf
|
||||
until
|
||||
.Fa n
|
||||
bytes have been removed or
|
||||
.Fa msgbuf
|
||||
is empty.
|
||||
.Sh EXAMPLES
|
||||
In a typical program, a channel between two processes is created with
|
||||
.Xr socketpair 2 ,
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
major=16
|
||||
major=17
|
||||
minor=0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue