summaryrefslogtreecommitdiffstats
path: root/src/tests/shlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/shlib')
-rw-r--r--src/tests/shlib/ChangeLog22
-rw-r--r--src/tests/shlib/t_loader.c199
2 files changed, 182 insertions, 39 deletions
diff --git a/src/tests/shlib/ChangeLog b/src/tests/shlib/ChangeLog
index 82a123eca..32e9b4834 100644
--- a/src/tests/shlib/ChangeLog
+++ b/src/tests/shlib/ChangeLog
@@ -1,3 +1,25 @@
+2005-02-08 Ken Raeburn <raeburn@mit.edu>
+
+ * t_loader.c (verbose): New variable.
+ (do_close_1): Drop filename argument. Change messages
+ accordingly, and only display them if verbose. Line up "done"
+ messages vertically.
+ (do_open_1): Likewise. Add library version argument, used when on
+ AIX, in combination with RTLD_MEMBER.
+ (do_open): Don't pass filename. Do pass library version; callers
+ changed.
+ (do_close): Don't pass filename.
+ (get_sym_1): Renamed from get_sym, added line number argument.
+ Print messages if verbose.
+ (get_sym): New macro.
+ (xbasename): Function deleted.
+ (HORIZ): New macro.
+ (main): Turn off output buffering. Print messages before and
+ after calling functions in loaded libraries. Disable first set of
+ tests, that don't call any functions. Test gssapi library without
+ loading any other libraries, then test it after loading com_err,
+ and unload com_err first.
+
2005-02-02 Ken Raeburn <raeburn@mit.edu>
* Makefile.in: New file.
diff --git a/src/tests/shlib/t_loader.c b/src/tests/shlib/t_loader.c
index 98c99682a..ecd6a4e83 100644
--- a/src/tests/shlib/t_loader.c
+++ b/src/tests/shlib/t_loader.c
@@ -7,6 +7,8 @@
#include "gssapi/gssapi.h"
#define HAVE_DLOPEN 1
+static int verbose = 1;
+
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
@@ -17,15 +19,15 @@
Return value is the library handle. On error, print a message and
exit. */
-#define do_open(LIB,FLAGS) do_open_1(LIB,FLAGS,__FILE__,__LINE__)
-static void *do_open_1(const char *libname, int lazy,
- const char *file, int line);
+#define do_open(LIB,REV,FLAGS) do_open_1(LIB,REV,FLAGS,__LINE__)
+static void *do_open_1(const char *libname, const char *rev, int lazy, int line);
/* Look up a function symbol in the library and return a pointer.
The return value may need casting to the correct type. On error,
print a message and exit. */
-static void *get_sym(void *libhandle, const char *sym);
+static void *get_sym_1(void *libhandle, const char *sym, int line);
+#define get_sym(LIB, NAME) get_sym_1(LIB, NAME, __LINE__)
#define GET_FSYM(TYPE, LIB, NAME) ((TYPE) get_sym(LIB, NAME))
#define get_gfun(LIB, NAME) ((OM_uint32 KRB5_CALLCONV(*)()) get_sym(LIB, NAME))
@@ -33,17 +35,8 @@ static void *get_sym(void *libhandle, const char *sym);
If the OS reports an error in doing so, print a message and
exit. */
-#define do_close(X) do_close_1(X, __FILE__, __LINE__)
-static void do_close_1(void *libhandle, const char *file, int line);
-
-static inline const char *xbasename(const char *path)
-{
- const char *p = strrchr(path, '/');
- if (p)
- return p+1;
- else
- return path;
-}
+#define do_close(X) do_close_1(X, __LINE__)
+static void do_close_1(void *libhandle, int line);
#ifdef HAVE_DLOPEN
@@ -53,15 +46,23 @@ static inline const char *xbasename(const char *path)
# define SHLIB_SUFFIX ".so"
#endif
-static void *do_open_1(const char *libname, int lazy,
- const char *file, int line)
+#define HORIZ 25
+
+static void *do_open_1(const char *libname, const char *rev,
+ int lazy, int line)
{
void *p;
char *namebuf;
+ size_t sz;
- file = xbasename(file);
- printf("from %s:%d: do_open(%s)\n", file, line, libname);
- namebuf = malloc(strlen(SHLIB_SUFFIX) + strlen(libname) + 4);
+ if (verbose)
+ printf("from line %d: do_open(%s)...%*s", line, libname,
+ HORIZ-strlen(libname), "");
+ sz = strlen(SHLIB_SUFFIX) + strlen(libname) + 4;
+#ifdef _AIX
+ sz += strlen(rev) + 8;
+#endif
+ namebuf = malloc(sz);
if (namebuf == 0) {
perror("malloc");
exit(1);
@@ -69,41 +70,62 @@ static void *do_open_1(const char *libname, int lazy,
strcpy(namebuf, "lib");
strcat(namebuf, libname);
strcat(namebuf, SHLIB_SUFFIX);
+#ifdef _AIX
+ strcat(namebuf, "(shr.o.");
+ strcat(namebuf, rev);
+ strcat(namebuf, ")");
+#endif
- p = dlopen(namebuf, lazy ? RTLD_LAZY : RTLD_NOW);
+#ifndef RTLD_MEMBER
+#define RTLD_MEMBER 0
+#endif
+ p = dlopen(namebuf, (lazy ? RTLD_LAZY : RTLD_NOW) | RTLD_MEMBER);
if (p == 0) {
fprintf(stderr, "dlopen of %s failed: %s\n", namebuf, dlerror());
exit(1);
}
free(namebuf);
+ if (verbose)
+ printf("done: %p\n", p);
return p;
}
#define SYM_PREFIX ""
-static void *get_sym(void *libhandle, const char *symname)
+static void *get_sym_1(void *libhandle, const char *symname, int line)
{
void *s;
/* Bah. Fix this later, if we care. */
assert(strlen(SYM_PREFIX) == 0);
+ if (verbose)
+ printf("from line %d: get_sym(%s)...%*s", line, symname,
+ HORIZ-strlen(symname), "");
+
s = dlsym(libhandle, symname);
if (s == 0) {
fprintf(stderr, "symbol %s not found\n", symname);
exit(1);
}
+ if (verbose)
+ printf("done: %p\n", s);
return s;
}
-#define do_close(X) do_close_1(X, __FILE__, __LINE__)
-static void do_close_1(void *libhandle, const char *file, int line)
+static void do_close_1(void *libhandle, int line)
{
- file = xbasename(file);
- printf("from %s:%d: do_close\n", file, line), fflush(stdout);
+ if (verbose) {
+ char pbuf[3*sizeof(libhandle)+4];
+ sprintf(pbuf, "%p", libhandle);
+ printf("from line %d: do_close(%s)...%*s", line, pbuf,
+ HORIZ-1-strlen(pbuf), "");
+ }
if (dlclose(libhandle) != 0) {
fprintf(stderr, "dlclose failed: %s\n", dlerror());
exit(1);
}
+ if (verbose)
+ printf("done\n");
}
#elif defined _WIN32
@@ -148,19 +170,24 @@ int main()
{
void *celib, *k5lib, *gsslib, *celib2;
- celib = do_open("com_err", 0);
- k5lib = do_open("krb5", 0);
- gsslib = do_open("gssapi_krb5", 0);
- celib2 = do_open("com_err", 0);
+ (void) setvbuf(stdout, 0, _IONBF, 0);
+
+#if 0
+ /* Simplest test: Load, then unload out of order. */
+ celib = do_open("com_err", "3.0", 0);
+ k5lib = do_open("krb5", "3.2", 0);
+ gsslib = do_open("gssapi_krb5", "2.2", 0);
+ celib2 = do_open("com_err", "3.0", 0);
do_close(celib);
do_close(k5lib);
do_close(celib2);
do_close(gsslib);
+#endif
- celib = do_open("com_err", 0);
- k5lib = do_open("krb5", 0);
- gsslib = do_open("gssapi_krb5", 0);
- celib2 = do_open("com_err", 0);
+ celib = do_open("com_err", "3.0", 0);
+ k5lib = do_open("krb5", "3.2", 0);
+ gsslib = do_open("gssapi_krb5", "2.2", 0);
+ celib2 = do_open("com_err", "3.0", 0);
do_close(celib2);
{
typedef krb5_error_code KRB5_CALLCONV (*ict)(krb5_context *);
@@ -171,22 +198,29 @@ int main()
krb5_context ctx;
krb5_error_code err;
+#define CALLING(S) (verbose ? printf("at line %d: calling %s...%*s", __LINE__, #S, (int)(HORIZ+1-strlen(#S)), "") : 0)
+#define DONE() (verbose ? printf("done\n") : 0)
+
+ CALLING(krb5_init_context);
err = init_context(&ctx);
+ DONE();
if (err) {
fprintf(stderr, "error 0x%lx initializing context\n",
(unsigned long) err);
exit(1);
}
+ CALLING(krb5_free_context);
free_context(ctx);
+ DONE();
}
- celib2 = do_open("com_err", 0);
+ celib2 = do_open("com_err", "3.0", 0);
do_close(celib);
do_close(k5lib);
do_close(celib2);
do_close(gsslib);
- celib = do_open("com_err", 1);
- gsslib = do_open("gssapi_krb5", 1);
+ /* Test gssapi_krb5 without having loaded anything else. */
+ gsslib = do_open("gssapi_krb5", "2.2", 1);
{
OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t,
gss_ctx_id_t *, gss_name_t,
@@ -221,7 +255,9 @@ int main()
10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"
};
+ CALLING(gss_import_name);
gmaj = import_name(&gmin, &target_name_buf, &service_name, &target);
+ DONE();
if (gmaj != GSS_S_COMPLETE) {
fprintf(stderr,
"import_name reports error major 0x%lx minor 0x%lx(%ld)\n",
@@ -234,15 +270,100 @@ int main()
we're ignoring the error and testing whether we're doing
cleanup properly. (Though the internal cleanup needed in
the two cases might be different.) */
+ CALLING(gss_init_sec_context);
gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target,
GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER,
NULL, &token, &retflags, NULL);
+ DONE();
/* Ignore success/failure indication. */
- if (token.length)
+ if (token.length) {
+ CALLING(gss_release_buffer);
release_buffer(&gmin, &token);
+ DONE();
+ }
+ CALLING(gss_release_name);
release_name(&gmin, &target);
- if (gctx != GSS_C_NO_CONTEXT)
+ DONE();
+ if (gctx != GSS_C_NO_CONTEXT) {
+ CALLING(gss_delete_sec_context);
delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER);
+ DONE();
+ }
+ }
+ do_close(gsslib);
+
+ /* Test gssapi_krb5 with com_err already loaded, then unload
+ com_err first. */
+ celib = do_open("com_err", "3.0", 1);
+ gsslib = do_open("gssapi_krb5", "2.2", 1);
+ {
+ OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t,
+ gss_ctx_id_t *, gss_name_t,
+ gss_OID,
+ OM_uint32, OM_uint32,
+ gss_channel_bindings_t,
+ gss_buffer_t, gss_OID *,
+ gss_buffer_t,
+ OM_uint32 *, OM_uint32 *)
+ = get_gfun(gsslib, "gss_init_sec_context");
+ OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t,
+ gss_OID, gss_name_t *)
+ = get_gfun(gsslib, "gss_import_name");
+ OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t)
+ = get_gfun(gsslib, "gss_release_buffer");
+ OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *)
+ = get_gfun(gsslib, "gss_release_name");
+ OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *,
+ gss_ctx_id_t *,
+ gss_buffer_t)
+ = get_gfun(gsslib, "gss_delete_sec_context");
+
+ OM_uint32 gmaj, gmin;
+ OM_uint32 retflags;
+ gss_ctx_id_t gctx = GSS_C_NO_CONTEXT;
+ gss_buffer_desc token;
+ gss_name_t target;
+ static gss_buffer_desc target_name_buf = {
+ 9, "x@mit.edu"
+ };
+ static gss_OID_desc service_name = {
+ 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"
+ };
+
+ CALLING(gss_import_name);
+ gmaj = import_name(&gmin, &target_name_buf, &service_name, &target);
+ DONE();
+ if (gmaj != GSS_S_COMPLETE) {
+ fprintf(stderr,
+ "import_name reports error major 0x%lx minor 0x%lx(%ld)\n",
+ (unsigned long) gmaj, (unsigned long) gmin,
+ (signed long) gmin);
+ exit(1);
+ }
+ /* This will probably get different errors, depending on
+ whether we have tickets at the time. Doesn't matter much,
+ we're ignoring the error and testing whether we're doing
+ cleanup properly. (Though the internal cleanup needed in
+ the two cases might be different.) */
+ CALLING(gss_init_sec_context);
+ gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target,
+ GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER,
+ NULL, &token, &retflags, NULL);
+ DONE();
+ /* Ignore success/failure indication. */
+ if (token.length) {
+ CALLING(gss_release_buffer);
+ release_buffer(&gmin, &token);
+ DONE();
+ }
+ CALLING(gss_release_name);
+ release_name(&gmin, &target);
+ DONE();
+ if (gctx != GSS_C_NO_CONTEXT) {
+ CALLING(gss_delete_sec_context);
+ delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER);
+ DONE();
+ }
}
do_close(celib);
do_close(gsslib);