+2001-01-17 Ken Raeburn <raeburn@mit.edu>
+
+ * error_message.c (add_error_table, remove_error_table): Allow
+ tables to be entered and removed multiple times, keeping the count
+ correct.
+ * t_com_err.c (main): Update to reflect new semantics.
+
2001-01-16 Ken Raeburn <raeburn@mit.edu>
* Makefile.in (test1.c, test2.c, et1.c, et2.c, test1.h, test2.h,
Transarc and Heimdal both have APIs that are different from this
version. (Specifics?)
+Karl Ramm has offered to try to combine them.
+
Workaround:
\f
-No reference counting:
+Reference counting:
If libraries are dynamically loaded and unloaded, and the init/fini
functions add and remove error tables for *other* libraries they
depend on (e.g., if a dynamically loadable Zephyr library's fini
function removes the krb4 library error table and then dlcloses the
krb4 library, while another dlopen reference keeps the krb4 library
-around), the error table is gone, even if the library is still in use.
+around), the error table is kept; a table must be removed the same
+number of times it was added before the library itself can be
+discarded.
+
+It's not implemented as a reference count, but the effect is the same.
-Workaround: None.
+Fix needed: Update documentation.
\f
64-bit support:
Workaround: Always use signed types of at least 32 bits for error
codes.
\f
+man page:
+
+No documentation on add_error_table/remove_error_table interfaces,
+even though they're the new, preferred interface.
+\f
/*
- * Copyright 1997 by Massachusetts Institute of Technology
+ * Copyright 1997,2000,2001 by Massachusetts Institute of Technology
*
* Copyright 1987, 1988 by MIT Student Information Processing Board
*
add_error_table(et)
/*@dependent@*/ const struct error_table FAR * et;
{
- struct et_list *el;
struct dynamic_et_list *del;
- /* Always check both lists, because the old interface code
- wouldn't check the dynamically maintained list before adding an
- entry to the static list. */
- for (el = _et_list; el != NULL; el = el->next)
- if (el->table != NULL && el->table->base == et->base)
- return EEXIST;
- for (del = et_list_dynamic; del != NULL; del = del->next)
- if (del->table->base == et->base)
- return EEXIST;
-
#ifdef _MSDOS
if (etl_used < PREALLOCATE_ETL) {
el = &etl[etl_used++];
{
struct dynamic_et_list **del;
struct et_list **el;
- errcode_t ret = ENOENT;
- /* Always check both lists, because the old interface code
- wouldn't check the dynamically maintained list before adding an
- entry to the static list. */
+ /* Remove the first occurrance we can find. Prefer dynamic
+ entries, but if there are none, check for a static one too. */
for (del = &et_list_dynamic; *del; del = &(*del)->next)
if ((*del)->table->base == et->base) {
/*@only@*/ struct dynamic_et_list *old = *del;
*del = old->next;
free (old);
- ret = 0;
- break;
+ return 0;
}
for (el = &_et_list; *el; el = &(*el)->next)
if ((*el)->table != NULL && (*el)->table->base == et->base) {
if ((old >= etl) && (old < &etl[PREALLOCATE_ETL-1]))
/* do something? */;
#endif
- ret = 0;
- break;
+ return 0;
}
- return ret;
+ return ENOENT;
}
(void) add_error_table (&et_et1_error_table);
try_em (1, 0);
(void) remove_error_table (&et_et1_error_table);
+ try_em (1, 0);
+ (void) remove_error_table (&et_et1_error_table);
try_em (0, 0);
initialize_et1_error_table ();
(void) add_error_table (&et_et2_error_table);
try_em (1, 1);
(void) remove_error_table (&et_et1_error_table);
+ try_em (1, 1);
+ (void) remove_error_table (&et_et1_error_table);
try_em (0, 1);
(void) remove_error_table (&et_et2_error_table);
try_em (0, 0);
(void) remove_error_table (&et_et1_error_table);
try_em (0, 1);
(void) remove_error_table (&et_et2_error_table);
+ try_em (0, 1);
+ (void) remove_error_table (&et_et2_error_table);
try_em (0, 0);
return fail;