2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-10-27 15:07:55 +00:00
Files
bind/lib/omapi/alloc.c
David Lawrence 0ae0a1f038 checkpoint conversion to ISC (doc/dev/coding.html) style.
* no spaces around " -> " in indirect postfix expression.
  * no space between function name and open parenthesis.
  * no space between array name and open bracket.
  * use NULL not 0 for pointers.
  * explicitly compare pointers to NULL.
  * explicitly compare integers to 0.
  * Do not cast NULL.
  * return type of function declaration on line by itself.
  * open brace of function definition follows close parenthesis if parameters
    all fit on one line.
  * comment-only lines start with /* on line by itself, and end with */
    on line by itself.
  * variable names in structures separated from their types in a column.
  * name the parameters in function prototypes.
  * ifndef multiple header file inclusion.

and other BIND9 conventions not in coding.html:

  * private structures defined in relevant source module, not private header.
  * RCS /* $Id: $ */ comments.
  * Principal Author (Ted Lemon) comments.
  * Updated ISC copyrights.
  * Parenthesize value of return().
  * Parenthesize argument of sizeof().
  * "unsigned int foo" not "unsigned foo".
  * ISC_LANG_(BEGIN|END)DECLS in header files.
  * header files included directly by source/header file that needs them.
  * ... and others I am probably forgetting.

and conversion to some libisc.a modules:

  * use isc/int.h for isc_uintXX_t types, not u_intXX_t.
  * use isc/assertions.h for REQUIRE() and INSIST().
  * use isc/error.h for UNEXPECTED_ERROR.
  * use isc/boolean.h for isc_boolean_t flags instead of int flags.
  * use isc/net.h for networking types.
  * use isc/netdb.h for gethostby*.

STILL TO COME ...

  * more isc_boolean_t.
  * isc/time.h to replace struct timeval.
  * isc/socket.h to replace socket/listen/select/etc.
  * isc/mem.h to replace malloc/free.
  * namespace overhaul & omapi/compatibility.h.

Please collect all your belongings but stand clear of the doors until this
train has come to a complete stop.
1999-11-02 04:01:34 +00:00

372 lines
8.6 KiB
C

/*
* Copyright (C) 1996, 1997, 1998, 1999 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* $Id: alloc.c,v 1.2 1999/11/02 04:01:30 tale Exp $ */
/* Principal Author: Ted Lemon */
/*
* Functions supporting memory allocation for the object management protocol.
*/
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memset */
#include <isc/assertions.h>
#include <isc/error.h>
#include <omapi/omapip_p.h>
void
omapi_object_reference(omapi_object_t **r, omapi_object_t *h,
const char *name)
{
REQUIRE(r != NULL && *r == NULL);
REQUIRE(h != NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_object_dereference(omapi_object_t **h, const char *name) {
int outer_reference = 0;
int inner_reference = 0;
int handle_reference = 0;
int extra_references;
omapi_object_t *p;
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
/*
* See if this object's inner object refers to it, but don't
* count this as a reference if we're being asked to free the
* reference from the inner object.
*/
if ((*h)->inner && (*h)->inner->outer && h != &((*h)->inner->outer))
inner_reference = 1;
/*
* Ditto for the outer object.
*/
if ((*h)->outer && (*h)->outer->inner && h != &((*h)->outer->inner))
outer_reference = 1;
/*
* Ditto for the outer object. The code below assumes that
* the only reason we'd get a dereference from the handle
* table is if this function does it - otherwise we'd have to
* traverse the handle table to find the address where the
* reference is stored and compare against that, and we don't
* want to do that if we can avoid it.
*/
if ((*h)->handle != 0)
handle_reference = 1;
/*
* If we are getting rid of the last reference other than
* references to inner and outer objects, or from the handle
* table, then we must examine all the objects in either
* direction to see if they hold any non-inner, non-outer,
* non-handle-table references. If not, we need to free the
* entire chain of objects.
*/
if ((*h)->refcnt ==
inner_reference + outer_reference + handle_reference + 1) {
if (inner_reference != 0 ||
outer_reference != 0 ||
handle_reference != 0) {
/*
* XXXTL we could check for a reference from the
* handle table here.
*/
extra_references = 0;
for (p = (*h)->inner;
p != NULL && extra_references == 0;
p = p->inner) {
extra_references += p->refcnt - 1;
if (p->inner != NULL)
--extra_references;
if (p->handle != 0)
--extra_references;
}
for (p = (*h)->outer;
p != NULL && extra_references == 0;
p = p->outer) {
extra_references += p->refcnt - 1;
if (p->outer != NULL)
--extra_references;
if (p->handle != 0)
--extra_references;
}
} else
extra_references = 0;
if (extra_references == 0) {
if (inner_reference != 0)
omapi_object_dereference(&(*h)->inner->outer,
name);
if (outer_reference != 0)
omapi_object_dereference(&(*h)->outer->inner,
name);
if ((*h)->type->destroy != NULL)
(*((*h)->type->destroy))(*h, name);
free(*h);
}
}
*h = NULL;
}
isc_result_t
omapi_buffer_new(omapi_buffer_t **h, const char *name) {
omapi_buffer_t *t;
REQUIRE(h != NULL && *h == NULL);
t = (omapi_buffer_t *)malloc(sizeof *t);
if (t == NULL)
return (ISC_R_NOMEMORY);
memset(t, 0, sizeof *t);
omapi_buffer_reference(h, t, name);
(*h)->head = sizeof((*h)->data) - 1;
return (ISC_R_SUCCESS);
}
void
omapi_buffer_reference(omapi_buffer_t **r, omapi_buffer_t *h, const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_buffer_dereference(omapi_buffer_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--(*h)->refcnt == 0)
free (*h);
*h = NULL;
}
isc_result_t
omapi_typed_data_new(omapi_typed_data_t **t, omapi_datatype_t type, ...) {
va_list l;
omapi_typed_data_t *new;
unsigned int len;
unsigned int val;
int intval;
char *s;
REQUIRE(type == omapi_datatype_int ||
type == omapi_datatype_string ||
type == omapi_datatype_data ||
type == omapi_datatype_object);
va_start(l, type);
/*
* Quiet bogus "might be used uninitialized in this function" warnings.
*/
val = 0;
intval = 0;
s = NULL;
switch (type) {
case omapi_datatype_int:
len = OMAPI_TYPED_DATA_INT_LEN;
intval = va_arg(l, int);
break;
case omapi_datatype_string:
s = va_arg(l, char *);
val = strlen(s);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
break;
case omapi_datatype_data:
val = va_arg(l, unsigned int);
len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
break;
case omapi_datatype_object:
len = OMAPI_TYPED_DATA_OBJECT_LEN;
break;
default:
UNEXPECTED_ERROR(__FILE__, __LINE__,
"unknown type in omapi_typed_data_new: %d\n",
type);
return (ISC_R_UNEXPECTED);
}
new = malloc(len);
if (new == NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, len);
switch (type) {
case omapi_datatype_int:
new->u.integer = intval;
break;
case omapi_datatype_string:
memcpy(new->u.buffer.value, s, val);
new->u.buffer.len = val;
break;
case omapi_datatype_data:
new->u.buffer.len = val;
break;
case omapi_datatype_object:
omapi_object_reference(&new->u.object,
va_arg(l, omapi_object_t *),
"omapi_datatype_new");
break;
}
new->type = type;
omapi_typed_data_reference(t, new, "omapi_typed_data_new");
return (ISC_R_SUCCESS);
}
void
omapi_typed_data_reference(omapi_typed_data_t **r, omapi_typed_data_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r != NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_typed_data_dereference(omapi_typed_data_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
if (--((*h)->refcnt) <= 0) {
switch ((*h)->type) {
case omapi_datatype_int:
case omapi_datatype_string:
case omapi_datatype_data:
default:
break;
case omapi_datatype_object:
omapi_object_dereference(&(*h)->u.object, name);
break;
}
free(*h);
}
*h = NULL;
}
isc_result_t
omapi_data_string_new(omapi_data_string_t **d, unsigned int len,
const char *name)
{
omapi_data_string_t *new;
new = malloc(OMAPI_DATA_STRING_EMPTY_SIZE + len);
if (new != NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
new->len = len;
omapi_data_string_reference(d, new, name);
return (ISC_R_SUCCESS);
}
void
omapi_data_string_reference(omapi_data_string_t **r, omapi_data_string_t *h,
const char *name)
{
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_data_string_dereference(omapi_data_string_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--((*h)->refcnt) <= 0)
free (*h);
*h = NULL;
}
isc_result_t
omapi_value_new(omapi_value_t **d, const char *name) {
omapi_value_t *new;
new = malloc(sizeof *new);
if (new != NULL)
return (ISC_R_NOMEMORY);
memset(new, 0, sizeof *new);
omapi_value_reference(d, new, name);
return (ISC_R_SUCCESS);
}
void
omapi_value_reference(omapi_value_t **r, omapi_value_t *h, const char *name) {
REQUIRE(r != NULL && h != NULL);
REQUIRE(*r == NULL);
(void)name; /* Unused. */
*r = h;
h->refcnt++;
}
void
omapi_value_dereference(omapi_value_t **h, const char *name) {
REQUIRE(h != NULL && *h != NULL);
REQUIRE((*h)->refcnt > 0);
(void)name; /* Unused. */
if (--((*h)->refcnt) <= 0) {
if ((*h)->name)
omapi_data_string_dereference(&(*h)->name, name);
if ((*h)->value)
omapi_typed_data_dereference(&(*h)->value, name);
free (*h);
}
*h = NULL;
}