diff options
Diffstat (limited to 'src/util/support')
-rw-r--r-- | src/util/support/ChangeLog | 8 | ||||
-rw-r--r-- | src/util/support/Makefile.in | 3 | ||||
-rw-r--r-- | src/util/support/errors.c | 134 | ||||
-rw-r--r-- | src/util/support/libkrb5support.exports | 6 | ||||
-rw-r--r-- | src/util/support/threads.c | 4 |
5 files changed, 155 insertions, 0 deletions
diff --git a/src/util/support/ChangeLog b/src/util/support/ChangeLog index 295f42f12..d1fae1dbe 100644 --- a/src/util/support/ChangeLog +++ b/src/util/support/ChangeLog @@ -1,3 +1,11 @@ +2006-03-26 Ken Raeburn <raeburn@mit.edu> + + * errors.c: New file. + * Makefile.in (SRCS, LIBOBJS, STLIBOBJS): Add it. + * threads.c (krb5int_thread_support_init): Call krb5int_err_init + to initialize the new file. + * libkrb5support.exports: Add the new symbols. + 2006-03-13 Ken Raeburn <raeburn@mit.edu> * plugins.c (krb5int_get_plugin_dir_data): If dirhandle is null or diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in index e6c75f525..2e96a88db 100644 --- a/src/util/support/Makefile.in +++ b/src/util/support/Makefile.in @@ -28,12 +28,14 @@ STLIBOBJS= \ threads.o \ init-addrinfo.o \ plugins.o \ + errors.o \ fake-addrinfo.o LIBOBJS= \ $(OUTPRE)threads.$(OBJEXT) \ $(OUTPRE)init-addrinfo.$(OBJEXT) \ $(OUTPRE)plugins.$(OBJEXT) \ + $(OUTPRE)errors.$(OBJEXT) \ $(OUTPRE)fake-addrinfo.$(OBJEXT) STOBJLISTS=OBJS.ST @@ -45,6 +47,7 @@ LOCALINCLUDES=-I. -I$(srcdir) SRCS=\ $(srcdir)/threads.c \ $(srcdir)/init-addrinfo.c \ + $(srcdir)/errors.c \ $(srcdir)/fake-addrinfo.c SHLIB_EXPDEPS = # Add -lm if dumping thread stats, for sqrt. diff --git a/src/util/support/errors.c b/src/util/support/errors.c new file mode 100644 index 000000000..185cb425a --- /dev/null +++ b/src/util/support/errors.c @@ -0,0 +1,134 @@ +/* Can't include krb5.h here, or k5-int.h which includes it, because + krb5.h needs to be generated with error tables, after util/et, + which builds after this directory. */ +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "k5-err.h" + +#include "k5-thread.h" +#include "k5-platform.h" + +/* It would be nice to just use error_message() always. Pity that + it's defined in a library that depends on this one, and we're not + allowed to make circular dependencies. */ +/* We really want a rwlock here, since we should hold it while calling + the function and copying out its results. But I haven't + implemented shims for rwlock yet. */ +static k5_mutex_t krb5int_error_info_support_mutex = + K5_MUTEX_PARTIAL_INITIALIZER; +static const char *(KRB5_CALLCONV *fptr)(long); /* = &error_message */ + +int +krb5int_err_init (void) +{ + return k5_mutex_finish_init (&krb5int_error_info_support_mutex); +} +#define initialize() krb5int_call_thread_support_init() +#define lock() k5_mutex_lock(&krb5int_error_info_support_mutex) +#define unlock() k5_mutex_unlock(&krb5int_error_info_support_mutex) + +void +krb5int_set_error (struct errinfo *ep, long code, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + krb5int_vset_error (ep, code, fmt, args); + va_end (args); +} + +void +krb5int_vset_error (struct errinfo *ep, long code, + const char *fmt, va_list args) +{ + if (ep->msg && ep->msg != ep->scratch_buf) { + free (ep->msg); + ep->msg = NULL; + } + ep->code = code; +#ifdef HAVE_VASPRINTF + { + char *str = NULL; + if (vasprintf(&str, fmt, args) >= 0 && str != NULL) { + ep->msg = str; + return; + } + } +#endif + vsnprintf(ep->scratch_buf, sizeof(ep->scratch_buf), fmt, args); + ep->msg = ep->scratch_buf; +} + +char * +krb5int_get_error (struct errinfo *ep, long code) +{ + char *r, *r2; + if (code != ep->code) + krb5int_clear_error (ep); + if (ep->msg) { + r = ep->msg; + ep->msg = NULL; + return r; + } + if (initialize() != 0) { + strncpy(ep->scratch_buf, _("Kerberos library initialization failure"), + sizeof(ep->scratch_buf)); + ep->scratch_buf[sizeof(ep->scratch_buf)-1] = 0; + ep->msg = NULL; + return ep->scratch_buf; + } + lock(); + if (fptr == NULL) { + unlock(); + r = strerror (code); + if (r) { + if (strlen (r) < sizeof (ep->scratch_buf) + || (r2 = strdup (r)) == NULL) { + strncpy (ep->scratch_buf, r, sizeof(ep->scratch_buf)); + return ep->scratch_buf; + } else + return r2; + } + format_number: + sprintf (ep->scratch_buf, _("error %ld"), code); + return ep->scratch_buf; + } + r = fptr(code); + if (r == NULL) { + unlock(); + goto format_number; + } + r2 = strdup (r); + if (r2 == NULL) { + strncpy(ep->scratch_buf, r, sizeof(ep->scratch_buf)); + unlock(); + return ep->scratch_buf; + } else { + unlock(); + return r2; + } +} + +void +krb5int_free_error (struct errinfo *ep, char *msg) +{ + if (msg != ep->scratch_buf) + free (msg); +} + +void +krb5int_clear_error (struct errinfo *ep) +{ + krb5int_free_error (ep, ep->msg); + ep->msg = NULL; +} + +void +krb5int_set_error_info_callout_fn (const char *(KRB5_CALLCONV *f)(long)) +{ + initialize(); + lock(); + fptr = f; + unlock(); +} diff --git a/src/util/support/libkrb5support.exports b/src/util/support/libkrb5support.exports index 1d7bc717f..00ce5c3e3 100644 --- a/src/util/support/libkrb5support.exports +++ b/src/util/support/libkrb5support.exports @@ -25,3 +25,9 @@ krb5int_mutex_alloc krb5int_mutex_free krb5int_mutex_lock krb5int_mutex_unlock +krb5int_set_error +krb5int_vset_error +krb5int_get_error +krb5int_free_error +krb5int_clear_error +krb5int_set_error_info_callout_fn diff --git a/src/util/support/threads.c b/src/util/support/threads.c index d0697bd93..7dc2e4828 100644 --- a/src/util/support/threads.c +++ b/src/util/support/threads.c @@ -453,6 +453,10 @@ int krb5int_thread_support_init (void) if (err) return err; + err = krb5int_err_init(); + if (err) + return err; + return 0; } |