summaryrefslogtreecommitdiff
path: root/src/lib/libdll
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libdll')
-rw-r--r--src/lib/libdll/Makefile17
-rw-r--r--src/lib/libdll/Mamfile319
-rw-r--r--src/lib/libdll/RELEASE52
-rw-r--r--src/lib/libdll/dlfcn.c536
-rw-r--r--src/lib/libdll/dll_lib.c183
-rw-r--r--src/lib/libdll/dllcheck.c85
-rw-r--r--src/lib/libdll/dllerror.c52
-rw-r--r--src/lib/libdll/dllfind.c46
-rw-r--r--src/lib/libdll/dlllib.h34
-rw-r--r--src/lib/libdll/dlllook.c46
-rw-r--r--src/lib/libdll/dllnext.c223
-rw-r--r--src/lib/libdll/dllopen.c93
-rw-r--r--src/lib/libdll/dllplug.c126
-rw-r--r--src/lib/libdll/dllscan.c525
-rw-r--r--src/lib/libdll/features/dll263
15 files changed, 2600 insertions, 0 deletions
diff --git a/src/lib/libdll/Makefile b/src/lib/libdll/Makefile
new file mode 100644
index 0000000..1fdde57
--- /dev/null
+++ b/src/lib/libdll/Makefile
@@ -0,0 +1,17 @@
+:PACKAGE: ast
+
+LICENSE = since=1997,author=gsf
+
+CCFLAGS = $(CC.OPTIMIZE) $(CC.DLL)
+
+dll 1.0 :LIBRARY: dlfcn.c dllopen.c dllfind.c dllplug.c dll_lib.c \
+ dllnext.c dlllook.c dllscan.c dllcheck.c dllerror.c \
+ -ldl -ldld
+
+win32.i386-64 :NOOPTIMIZE: dllscan.c
+
+$(INCLUDEDIR) :INSTALLPROTO: dlldefs.h
+
+dlldefs.h :COPY: FEATURE/dll
+
+:: RELEASE
diff --git a/src/lib/libdll/Mamfile b/src/lib/libdll/Mamfile
new file mode 100644
index 0000000..198ac1e
--- /dev/null
+++ b/src/lib/libdll/Mamfile
@@ -0,0 +1,319 @@
+info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-02-29
+setv INSTALLROOT ../../..
+setv PACKAGE_ast_INCLUDE ${INSTALLROOT}/include/ast
+setv PACKAGE_ast_LIB ${INSTALLROOT}/lib
+setv PACKAGEROOT ../../../../..
+setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS}
+setv ARFLAGS rc
+setv AS as
+setv ASFLAGS
+setv CC cc
+setv mam_cc_FLAGS ${mam_cc_DLL}
+setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?}
+setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??}
+setv COTEMP $$
+setv CPIO cpio
+setv CPIOFLAGS
+setv CPP "${CC} -E"
+setv F77 f77
+setv HOSTCC ${CC}
+setv IGNORE
+setv LD ld
+setv LDFLAGS
+setv LEX lex
+setv LEXFLAGS
+setv LPR lpr
+setv LPRFLAGS
+setv M4FLAGS
+setv NMAKE nmake
+setv NMAKEFLAGS
+setv PR pr
+setv PRFLAGS
+setv SHELL /bin/sh
+setv SILENT
+setv TAR tar
+setv YACC yacc
+setv YACCFLAGS -d
+make ${PACKAGEROOT}/lib/package/ast.lic
+done ${PACKAGEROOT}/lib/package/ast.lic
+make install
+make dll
+make libdll.a archive
+make dll.req
+exec - set -
+exec - echo 'int main(){return 0;}' > 1.${COTEMP}.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -c 1.${COTEMP}.c &&
+exec - x=`${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l'*' 2>&1 | sed -e 's/[][()+@?]/#/g' || :` &&
+exec - {
+exec - case "" in
+exec - *?) echo " " ;;
+exec - esac
+exec - for i in dll dl dld ast
+exec - do case $i in
+exec - "dll"|dll)
+exec - ;;
+exec - *) if test -f ${INSTALLROOT}/lib/lib/$i
+exec - then y=`cat ${INSTALLROOT}/lib/lib/$i`
+exec - case $y in
+exec - *-?*) echo "" $y ;;
+exec - esac
+exec - continue
+exec - elif test ! -f ${INSTALLROOT}/lib/lib$i.a
+exec - then case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -L${INSTALLROOT}/lib ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in
+exec - *$x*) case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in
+exec - *$x*) continue ;;
+exec - esac
+exec - ;;
+exec - esac
+exec - fi
+exec - ;;
+exec - esac
+exec - echo " -l$i"
+exec - done
+exec - } > dll.req
+exec - rm -f 1.${COTEMP}.*
+done dll.req generated
+make dlfcn.o
+make dlfcn.c
+make dll.h implicit
+done dll.h dontcare virtual
+make xcoff.h implicit
+done xcoff.h dontcare virtual
+make dl.h implicit
+done dl.h dontcare virtual
+make ${PACKAGE_ast_INCLUDE}/error.h implicit
+make ${PACKAGE_ast_INCLUDE}/option.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_api.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_api.h dontcare
+make ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_map.h dontcare
+make ${PACKAGE_ast_INCLUDE}/endian.h implicit
+make ${PACKAGE_ast_INCLUDE}/bytesex.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+done ${PACKAGE_ast_INCLUDE}/bytesex.h dontcare
+done ${PACKAGE_ast_INCLUDE}/endian.h dontcare
+done ${PACKAGE_ast_INCLUDE}/ast_common.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+make ${PACKAGE_ast_INCLUDE}/regex.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_wchar.h implicit
+make ${PACKAGE_ast_INCLUDE}/wctype.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_wctype.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_wctype.h dontcare
+done ${PACKAGE_ast_INCLUDE}/wctype.h dontcare
+make ${PACKAGE_ast_INCLUDE}/stdio.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_stdio.h implicit
+make ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
+done ${PACKAGE_ast_INCLUDE}/sfio_s.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_stdio.h dontcare
+done ${PACKAGE_ast_INCLUDE}/stdio.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/stdio.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_wchar.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+make ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+make ${INSTALLROOT}/include/prototyped.h implicit
+done ${INSTALLROOT}/include/prototyped.h dontcare
+done ${PACKAGE_ast_INCLUDE}/prototyped.h dontcare
+done ${PACKAGE_ast_INCLUDE}/regex.h dontcare
+make ${PACKAGE_ast_INCLUDE}/getopt.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_getopt.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/getopt.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_map.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_botch.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_botch.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_limits.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_limits.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_fcntl.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_fs.h dontcare
+done ${PACKAGE_ast_INCLUDE}/ast_fcntl.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_getopt.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_sys.h implicit
+prev ${PACKAGE_ast_INCLUDE}/getopt.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_sys.h dontcare
+make ${PACKAGE_ast_INCLUDE}/ast_lib.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_lib.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_std.h dontcare
+done ${PACKAGE_ast_INCLUDE}/vmalloc.h dontcare
+make ${PACKAGE_ast_INCLUDE}/sfio.h implicit
+prev ${PACKAGE_ast_INCLUDE}/sfio_s.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+done ${PACKAGE_ast_INCLUDE}/sfio.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/option.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/error.h
+make dlldefs.h implicit
+make FEATURE/dll
+meta FEATURE/dll features/%>FEATURE/% features/dll dll
+make features/dll
+done features/dll
+bind -ldl dontcare
+bind -last
+exec - iffe -v -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdl} ${mam_libast} : run features/dll
+done FEATURE/dll generated
+exec - cmp 2>/dev/null -s FEATURE/dll dlldefs.h || { rm -f dlldefs.h; silent test -d . || mkdir .; cp FEATURE/dll dlldefs.h; }
+done dlldefs.h generated
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+done dlfcn.c
+meta dlfcn.o %.c>%.o dlfcn.c dlfcn
+prev dlfcn.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dlfcn.c
+done dlfcn.o generated
+make dllopen.o
+make dllopen.c
+make dlllib.h implicit
+prev ${PACKAGE_ast_INCLUDE}/error.h implicit
+prev dlldefs.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+done dlllib.h
+done dllopen.c
+meta dllopen.o %.c>%.o dllopen.c dllopen
+prev dllopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllopen.c
+done dllopen.o generated
+make dllfind.o
+make dllfind.c
+prev ${PACKAGE_ast_INCLUDE}/error.h implicit
+prev dlldefs.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+done dllfind.c
+meta dllfind.o %.c>%.o dllfind.c dllfind
+prev dllfind.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllfind.c
+done dllfind.o generated
+make dllplug.o
+make dllplug.c
+prev dlllib.h implicit
+done dllplug.c
+meta dllplug.o %.c>%.o dllplug.c dllplug
+prev dllplug.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllplug.c
+done dllplug.o generated
+make dll_lib.o
+make dll_lib.c
+prev dlllib.h implicit
+done dll_lib.c
+meta dll_lib.o %.c>%.o dll_lib.c dll_lib
+prev dll_lib.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dll_lib.c
+done dll_lib.o generated
+make dllnext.o
+make dllnext.c
+make rld_interface.h implicit
+done rld_interface.h dontcare virtual
+prev dlldefs.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+done dllnext.c
+meta dllnext.o %.c>%.o dllnext.c dllnext
+prev dllnext.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dllnext.c
+done dllnext.o generated
+make dlllook.o
+make dlllook.c
+prev dlldefs.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+done dlllook.c
+meta dlllook.o %.c>%.o dlllook.c dlllook
+prev dlllook.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dlllook.c
+done dlllook.o generated
+make dllscan.o
+make dllscan.c
+prev dlldefs.h implicit
+prev ${PACKAGE_ast_INCLUDE}/vmalloc.h implicit
+make ${PACKAGE_ast_INCLUDE}/fts.h implicit
+make ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit
+done ${PACKAGE_ast_INCLUDE}/ast_mode.h dontcare
+prev ${PACKAGE_ast_INCLUDE}/ast_fs.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+prev ${PACKAGE_ast_INCLUDE}/prototyped.h implicit
+done ${PACKAGE_ast_INCLUDE}/fts.h
+prev ${PACKAGE_ast_INCLUDE}/error.h implicit
+prev ${PACKAGE_ast_INCLUDE}/endian.h implicit
+make ${PACKAGE_ast_INCLUDE}/cdt.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_common.h implicit
+prev ${PACKAGE_ast_INCLUDE}/ast_std.h implicit
+done ${PACKAGE_ast_INCLUDE}/cdt.h
+prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
+done dllscan.c
+meta dllscan.o %.c>%.o dllscan.c dllscan
+prev dllscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dllscan.c
+done dllscan.o generated
+make dllcheck.o
+make dllcheck.c
+prev dlllib.h implicit
+done dllcheck.c
+meta dllcheck.o %.c>%.o dllcheck.c dllcheck
+prev dllcheck.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllcheck.c
+done dllcheck.o generated
+make dllerror.o
+make dllerror.c
+prev dlllib.h implicit
+done dllerror.c
+meta dllerror.o %.c>%.o dllerror.c dllerror
+prev dllerror.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -I${PACKAGE_ast_INCLUDE} -D_PACKAGE_ast -D_BLD_dll -c dllerror.c
+done dllerror.o generated
+exec - ${AR} rc libdll.a dlfcn.o dllopen.o dllfind.o dllplug.o dll_lib.o dllnext.o dlllook.o dllscan.o dllcheck.o dllerror.o
+exec - (ranlib libdll.a) >/dev/null 2>&1 || true
+done libdll.a generated
+done dll virtual
+prev libdll.a archive
+make ${INSTALLROOT}/lib
+exec - if silent test ! -d ${INSTALLROOT}/lib
+exec - then mkdir -p ${INSTALLROOT}/lib
+exec - fi
+done ${INSTALLROOT}/lib generated
+make ${INSTALLROOT}/lib/libdll.a archive
+prev ${INSTALLROOT}/lib
+prev libdll.a archive
+exec - test '' = 'libdll.a' || ${STDCMP} 2>/dev/null -s libdll.a ${INSTALLROOT}/lib/libdll.a || { ${STDMV} ${INSTALLROOT}/lib/libdll.a ${INSTALLROOT}/lib/libdll.a.old 2>/dev/null || true; ${STDCP} libdll.a ${INSTALLROOT}/lib/libdll.a ;}
+exec - (ranlib ${INSTALLROOT}/lib/libdll.a) >/dev/null 2>&1 || true
+done ${INSTALLROOT}/lib/libdll.a generated
+make ${INSTALLROOT}/lib/lib
+exec - if silent test ! -d ${INSTALLROOT}/lib/lib
+exec - then mkdir -p ${INSTALLROOT}/lib/lib
+exec - fi
+done ${INSTALLROOT}/lib/lib generated
+make ${INSTALLROOT}/lib/lib/dll
+prev ${INSTALLROOT}/lib/lib
+prev dll.req
+exec - test '' = 'dll.req' || ${STDCMP} 2>/dev/null -s dll.req ${INSTALLROOT}/lib/lib/dll || { ${STDMV} ${INSTALLROOT}/lib/lib/dll ${INSTALLROOT}/lib/lib/dll.old 2>/dev/null || true; ${STDCP} dll.req ${INSTALLROOT}/lib/lib/dll ;}
+done ${INSTALLROOT}/lib/lib/dll generated
+make ${PACKAGE_ast_INCLUDE}
+exec - if silent test ! -d ${PACKAGE_ast_INCLUDE}
+exec - then mkdir -p ${PACKAGE_ast_INCLUDE}
+exec - fi
+done ${PACKAGE_ast_INCLUDE} generated
+make ${PACKAGE_ast_INCLUDE}/dlldefs.h
+prev ${PACKAGE_ast_INCLUDE}
+prev dlldefs.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1997,author=gsf' dlldefs.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${PACKAGE_ast_INCLUDE}/dlldefs.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${PACKAGE_ast_INCLUDE}/dlldefs.h
+exec - fi
+done ${PACKAGE_ast_INCLUDE}/dlldefs.h generated
+done install virtual
+make test
+done test dontcare virtual
diff --git a/src/lib/libdll/RELEASE b/src/lib/libdll/RELEASE
new file mode 100644
index 0000000..516c866
--- /dev/null
+++ b/src/lib/libdll/RELEASE
@@ -0,0 +1,52 @@
+11-10-11 dll_lib.c: add { dllnames() dll_lib() }
+10-10-20 dllscan.c: version arg "-" => 0
+10-10-19 dllplug.c: fix bug that wiped out dlopen() error message
+10-10-19 dllplug.c: un-localize lookup names (happens with cut and paste)
+10-10-19 dllscan.c: still no code for implicit libs missed by dlopen()
+10-08-02 dllplug.c: fix local path dllcheck() call
+10-05-28 dllplug.c: add dllplugin() with dllcheck() version check
+10-05-28 dllcheck.c: add dllcheck() to do plugin_version() checks
+10-05-28 dllerror.c: add dllerror(int retain) for dll*() and dl*() messages
+09-11-17 dllscan.c: handle name[-.]version in dlsopen()
+09-04-15 dllopen.c: add, use dllopen() internally to wrap dlopen()
+08-05-12 dllscan.c: LIBSUFFIX==.dylib => default plugin version match 0.0
+06-10-11 dllscan.c: check sfstruse() return values -- doh
+06-01-25 dllplug.c: add errorf() library message for dlopen() error
+05-02-14 dllscan.c: "" || "-" => NiL
+04-10-01 dllfind.c: drop ksh "builtin" workaround
+ dllscan.c: directory prefix in name limits search to dir and siblings
+04-07-22 dllscan.c: access() => eaccess()
+04-01-30 dllfind.c: dllplug(error_info.id) then dllplug(0)
+04-01-28 dllscan.c: update for new plugin scheme: lib/foo/bar.xxx
+ dllplug.c: add dllplug() for plugin dllfind()
+03-03-12 dllfind.c: dlopen() with RTLD_GLOBAL|RTLD_PARENT defaults
+03-02-11 dllscan.c: change LIBPATH to <dir>[:<env>[:<pat>]][,...]
+03-01-08 dllscan.c: hack version logic again -- is consistency rocket science?
+03-01-07 dlfcn.c: fix darwin.ppc dlopen/dlsym/dlclose
+02-11-18 dllfind.c: add path,size args (with backwards compatibility checks)
+02-11-15 dllfind.c: check for ./path if '.' in path but no '/'
+02-08-30 dllfind.c: fix a bug that returned uninitialized value on not found
+02-08-28 dllscan.c: handle and display bin as a sibling dir
+02-07-31 dllscan.c: add dllsopen,dllsread,dllsclose
+ dllfind.c: use dllsopen,dllsread,dllsclose
+02-07-26 dllfind.c: add dllinfo()
+02-06-27 dllnext.c: define _GNU_SOURCE to enable RTLD_NEXT
+02-03-17 dllfind.c: fix dll prefix search (for cygwin)
+02-01-11 features/dll: include <dlfcn.h> only if _hdr_dlfcn&&_lib_dlopen
+01-10-31 dlfcn.c: change hp.pa dlopen() prototype (<dlfcn.h> but no -ldl!)
+01-09-25 dllfind: add LIBSUFFIX
+01-07-17 dllfind: do at least one dlopen() to prime dlerror()
+01-05-29 dlopen: fix dlopen(0,0) for HP
+01-04-20 dllfind: use getconf HOSTTYPE LIBPATH LIBSUFFIX
+01-02-14 features/dll: fix unbalanced ' quote and ancient hostinfo reference
+00-01-26 dlllook: add -- dlsym() with `_' weak prefix fallback
+99-04-01 features/dll: drop <stdio.h> -- iffe protos printf
+99-03-19 static=1 for all but win32.*
+98-06-01 dllfind: fix version search
+98-03-11 features/dll: probe for _DLL_RLD_SYM
+98-03-01 dllnext: fix to work!
+98-01-23 -ldl test moved to lib0ast
+98-01-11 update for astconf("LIBPATH")
+ add dllnext(flags) to uncover next layer
+ dllfind() and dllnext() in separate files (for 3d)
+97-10-11 move from libast so libast can link static
diff --git a/src/lib/libdll/dlfcn.c b/src/lib/libdll/dlfcn.c
new file mode 100644
index 0000000..810be1b
--- /dev/null
+++ b/src/lib/libdll/dlfcn.c
@@ -0,0 +1,536 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * provide dlopen/dlsym/dlerror interface
+ *
+ * David Korn
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+static const char id[] = "\n@(#)$Id: dll library (AT&T Research) 2010-10-20 $\0\n";
+
+#include <ast.h>
+#include <dlldefs.h>
+#include <error.h>
+
+#define T(x) ERROR_dictionary(x)
+
+#if _BLD_dll && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if _hdr_dlfcn && _lib_dlopen
+
+ /*
+ * standard
+ */
+
+# include <dlfcn.h>
+
+#else
+#if _hdr_dl
+
+ /*
+ * HP-UX
+ */
+
+# include <dl.h>
+# ifndef BIND_FIRST
+# define BIND_FIRST 0x4
+# endif
+# ifndef BIND_NOSTART
+# define BIND_NOSTART 0x10
+# endif
+
+ static shl_t all;
+ static int err;
+
+ extern void* dlopen(const char* path, int mode)
+ {
+ void* dll;
+
+ if (!path)
+ return (void*)&all;
+ if (mode)
+ mode = (BIND_IMMEDIATE|BIND_FIRST|BIND_NOSTART);
+ if (!(dll = (void*)shl_load(path, mode, 0L)))
+ err = errno;
+ return dll;
+ }
+
+ extern int dlclose(void* dll)
+ {
+ return 0;
+ }
+
+ extern void* dlsym(void* dll, const char* name)
+ {
+ shl_t handle;
+ long addr;
+
+ handle = dll == (void*)&all ? (shl_t)0 : (shl_t)dll;
+ if (shl_findsym(&handle, name, TYPE_UNDEFINED, &addr))
+ {
+ err = errno;
+ return 0;
+ }
+ return (void*)addr;
+ }
+
+ extern char* dlerror(void)
+ {
+ char* msg;
+
+ if (!err)
+ return 0;
+ msg = fmterror(err);
+ err = 0;
+ return msg;
+ }
+
+#else
+#if _sys_ldr && _lib_loadbind
+
+ /*
+ * rs6000
+ */
+
+# include <sys/ldr.h>
+# include <xcoff.h>
+
+ /* xcoff module header */
+ struct hdr
+ {
+ struct filehdr f;
+ struct aouthdr a;
+ struct scnhdr s[1];
+ };
+
+ static struct ld_info* ld_info;
+ static unsigned int ld_info_size = 1024;
+ static void* last_module;
+ static int err;
+
+ extern void* dlopen(const char* path, int mode)
+ {
+ void* dll;
+
+ if (!(dll = (void*)load((char*)path, mode, getenv("LIBPATH"))))
+ err = errno;
+ return dll;
+ }
+
+ extern int dlclose(void* dll)
+ {
+ return 0;
+ }
+
+ static int getquery(void)
+ {
+ if (!ld_info)
+ ld_info = malloc(ld_info_size);
+ for (;;)
+ {
+ if (!ld_info)
+ return 1;
+ if (!loadquery(L_GETINFO, ld_info, ld_info_size))
+ return 0;
+ if (errno != ENOMEM)
+ return 1;
+ ld_info = realloc(ld_info, ld_info_size *= 2);
+ }
+ }
+
+ /* find the loaded module whose data area contains the
+ * address passed in. Remember that procedure pointers
+ * are implemented as pointers to descriptors in the
+ * data area of the module defining the procedure
+ */
+ static struct ld_info* getinfo(void* module)
+ {
+ struct ld_info* info = ld_info;
+ register int n = 1;
+
+ if (!ld_info || module != last_module)
+ {
+ last_module = module;
+ if (getquery())
+ return 0;
+ info = ld_info;
+ }
+ while (n)
+ {
+ if ((char*)(info->ldinfo_dataorg) <= (char*)module &&
+ (char*)module <= ((char*)(info->ldinfo_dataorg)
+ + (unsigned)(info->ldinfo_datasize)))
+ return info;
+ if (n=info->ldinfo_next)
+ info = (void*)((char*)info + n);
+ }
+ return 0;
+ }
+
+ static char* getloc(struct hdr* hdr, char* data, char* name)
+ {
+ struct ldhdr* ldhdr;
+ struct ldsym* ldsym;
+ ulong datareloc;
+ ulong textreloc;
+ int i;
+
+ /* data is relocated by the difference between
+ * its virtual origin and where it was
+ * actually placed
+ */
+ /*N.B. o_sndata etc. are one based */
+ datareloc = (ulong)data - hdr->s[hdr->a.o_sndata-1].s_vaddr;
+ /*hdr is address of header, not text, so add text s_scnptr */
+ textreloc = (ulong)hdr + hdr->s[hdr->a.o_sntext-1].s_scnptr
+ - hdr->s[hdr->a.o_sntext-1].s_vaddr;
+ ldhdr = (void*)((char*)hdr+ hdr->s[hdr->a.o_snloader-1].s_scnptr);
+ ldsym = (void*) (ldhdr+1);
+ /* search the exports symbols */
+ for(i=0; i < ldhdr->l_nsyms;ldsym++,i++)
+ {
+ char *symname,symbuf[9];
+ char *loc;
+ /* the symbol name representation is a nuisance since
+ * 8 character names appear in l_name but may
+ * not be null terminated. This code works around
+ * that by brute force
+ */
+ if (ldsym->l_zeroes)
+ {
+ symname = symbuf;
+ memcpy(symbuf,ldsym->l_name,8);
+ symbuf[8] = 0;
+ }
+ else
+ symname = (void*)(ldsym->l_offset + (ulong)ldhdr + ldhdr->l_stoff);
+ if (strcmp(symname,name))
+ continue;
+ loc = (char*)ldsym->l_value;
+ if ((ldsym->l_scnum==hdr->a.o_sndata) ||
+ (ldsym->l_scnum==hdr->a.o_snbss))
+ loc += datareloc;
+ else if (ldsym->l_scnum==hdr->a.o_sntext)
+ loc += textreloc;
+ return loc;
+ }
+ return 0;
+ }
+
+ extern void* dlsym(void* handle, const char* name)
+ {
+ void* addr;
+ struct ld_info* info;
+
+ if (!(info = getinfo(handle)) || !(addr = getloc(info->ldinfo_textorg,info->ldinfo_dataorg,(char*)name)))
+ {
+ err = errno;
+ return 0;
+ }
+ return addr;
+ }
+
+ extern char* dlerror(void)
+ {
+ char* msg;
+
+ if (!err)
+ return 0;
+ msg = fmterror(err);
+ err = 0;
+ return msg;
+ }
+
+#else
+#if _hdr_dll && _lib_dllload
+
+ /*
+ * MVS
+ */
+
+# include <dll.h>
+
+ static int err;
+
+ extern void* dlopen(const char* path, int mode)
+ {
+ void* dll;
+
+ NoP(mode);
+ if (!(dll = (void*)dllload(path)))
+ err = errno;
+ return dll;
+ }
+
+ extern int dlclose(void* dll)
+ {
+ return 0;
+ }
+
+ extern void* dlsym(void* handle, const char* name)
+ {
+ void* addr;
+
+ if (!(addr = (void*)dllqueryfn(handle, (char*)name)))
+ err = errno;
+ return addr;
+ }
+
+ extern char* dlerror(void)
+ {
+ char* msg;
+
+ if (!err)
+ return 0;
+ msg = fmterror(err);
+ err = 0;
+ return msg;
+ }
+
+#else
+#if _hdr_mach_o_dyld
+
+ /*
+ * mac[h]
+ */
+
+# include <mach-o/dyld.h>
+
+ typedef const struct mach_header* NSImage;
+
+ typedef struct Dll_s
+ {
+ unsigned long magic;
+ NSImage image;
+ NSModule module;
+ char path[1];
+ } Dll_t;
+
+ #define DL_MAGIC 0x04190c04
+ #define DL_NEXT ((Dll_t*)RTLD_NEXT)
+
+ static const char* dlmessage = "no error";
+
+ static const char e_cover[] = T("cannot access covered library");
+ static const char e_handle[] = T("invalid handle");
+ static const char e_space[] = T("out of space");
+ static const char e_static[] = T("image statically linked");
+ static const char e_undefined[] = T("undefined symbol");
+
+ static Dll_t global = { DL_MAGIC };
+
+ static void undefined(const char* name)
+ {
+ }
+
+ static NSModule multiple(NSSymbol sym, NSModule om, NSModule nm)
+ {
+ return om;
+ }
+
+ static void linkedit(NSLinkEditErrors c, int n, const char* f, const char* m)
+ {
+ dlmessage = m;
+ }
+
+ static NSLinkEditErrorHandlers handlers =
+ {
+ undefined, multiple, linkedit
+ };
+
+ extern void* dlopen(const char* path, int mode)
+ {
+ Dll_t* dll;
+ int i;
+ NSObjectFileImage image;
+
+ static int init = 0;
+
+ if (!_dyld_present())
+ {
+ dlmessage = e_static;
+ return 0;
+ }
+ if (!init)
+ {
+ init = 1;
+ NSInstallLinkEditErrorHandlers(&handlers);
+ }
+ if (!path)
+ dll = &global;
+ else if (!(dll = newof(0, Dll_t, 1, strlen(path))))
+ {
+ dlmessage = e_space;
+ return 0;
+ }
+ else
+ {
+ switch (NSCreateObjectFileImageFromFile(path, &image))
+ {
+ case NSObjectFileImageSuccess:
+ dll->module = NSLinkModule(image, path, (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
+ NSDestroyObjectFileImage(image);
+ if (!dll->module)
+ {
+ free(dll);
+ return 0;
+ }
+ break;
+ case NSObjectFileImageInappropriateFile:
+ dll->image = NSAddImage(path, 0);
+ if (!dll->image)
+ {
+ free(dll);
+ return 0;
+ }
+ break;
+ default:
+ free(dll);
+ return 0;
+ }
+ strcpy(dll->path, path);
+ dll->magic = DL_MAGIC;
+ }
+ return (void*)dll;
+ }
+
+ extern int dlclose(void* handle)
+ {
+ Dll_t* dll = (Dll_t*)handle;
+
+ if (!dll || dll == DL_NEXT || dll->magic != DL_MAGIC)
+ {
+ dlmessage = e_handle;
+ return -1;
+ }
+ if (dll->module)
+ NSUnLinkModule(dll->module, 0);
+ free(dll);
+ return 0;
+ }
+
+ static NSSymbol
+ lookup(Dll_t* dll, const char* name)
+ {
+ unsigned long pun;
+ void* address;
+
+ if (dll == DL_NEXT)
+ {
+ if (!_dyld_func_lookup(name, &pun))
+ return 0;
+ address = (NSSymbol)pun;
+ }
+ else if (dll->module)
+ address = NSLookupSymbolInModule(dll->module, name);
+ else if (dll->image)
+ {
+ if (!NSIsSymbolNameDefinedInImage(dll->image, name))
+ return 0;
+ address = NSLookupSymbolInImage(dll->image, name, 0);
+ }
+ else
+ {
+ if (!NSIsSymbolNameDefined(name))
+ return 0;
+ address = NSLookupAndBindSymbol(name);
+ }
+ if (address)
+ address = NSAddressOfSymbol(address);
+ return address;
+ }
+
+ extern void* dlsym(void* handle, const char* name)
+ {
+ Dll_t* dll = (Dll_t*)handle;
+ NSSymbol address;
+ char buf[1024];
+
+ if (!dll || dll != DL_NEXT && (dll->magic != DL_MAGIC || !dll->image && !dll->module))
+ {
+ dlmessage = e_handle;
+ return 0;
+ }
+ if (!(address = lookup(dll, name)) && name[0] != '_' && strlen(name) < (sizeof(buf) - 1))
+ {
+ buf[0] = '_';
+ strcpy(buf + 1, name);
+ address = lookup(dll, buf);
+ }
+ if (!address)
+ {
+ dlmessage = dll == DL_NEXT ? e_cover : e_undefined;
+ return 0;
+ }
+ return (void*)address;
+ }
+
+ extern char* dlerror(void)
+ {
+ char* msg;
+
+ msg = (char*)dlmessage;
+ dlmessage = 0;
+ return msg;
+ }
+
+#else
+ /*
+ * punt
+ */
+
+ static int err;
+
+ extern void* dlopen(const char* path, int mode)
+ {
+ err = 1;
+ return 0;
+ }
+
+ extern int dlclose(void* dll)
+ {
+ err = 1;
+ return 0;
+ }
+
+ extern void* dlsym(void* handle, const char* name)
+ {
+ err = 1;
+ return 0;
+ }
+
+ extern char* dlerror(void)
+ {
+ if (!err)
+ return 0;
+ err = 0;
+ return "dynamic linking not supported";
+ }
+
+#endif
+#endif
+#endif
+#endif
+#endif
diff --git a/src/lib/libdll/dll_lib.c b/src/lib/libdll/dll_lib.c
new file mode 100644
index 0000000..29e4cd8
--- /dev/null
+++ b/src/lib/libdll/dll_lib.c
@@ -0,0 +1,183 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include "dlllib.h"
+
+typedef void* (*Dll_lib_f)(const char*, void*, const char*);
+
+typedef struct Dll_lib_s
+{
+ struct Dll_lib_s* next;
+ Dll_lib_f libf;
+ char* path;
+ char base[1];
+} Dll_lib_t;
+
+/*
+ * split <name,base,type,opts> from name into names
+ */
+
+Dllnames_t*
+dllnames(const char* id, const char* name, Dllnames_t* names)
+{
+ char* s;
+ char* t;
+ char* b;
+ char* e;
+ size_t n;
+
+ n = strlen(id);
+ if (strneq(name, id, n) && (streq(name + n, "_s") || streq(name + n, "_t")))
+ return 0;
+ if (!names)
+ {
+ s = fmtbuf(sizeof(Dllnames_t*) + sizeof(names) - 1);
+ if (n = (s - (char*)0) % sizeof(names))
+ s += sizeof(names) - n;
+ names = (Dllnames_t*)s;
+ }
+
+ /*
+ * determine the base name
+ */
+
+ if ((s = strrchr(name, '/')) || (s = strrchr(name, '\\')))
+ s++;
+ else
+ s = (char*)name;
+ if (strneq(s, "lib", 3))
+ s += 3;
+ b = names->base = names->data;
+ e = b + sizeof(names->data) - 1;
+ t = s;
+ while (b < e && *t && *t != '.' && *t != '-' && *t != ':')
+ *b++ = *t++;
+ *b++ = 0;
+
+ /*
+ * determine the optional type
+ */
+
+ if (t = strrchr(s, ':'))
+ {
+ names->name = b;
+ while (b < e && s < t)
+ *b++ = *s++;
+ *b++ = 0;
+ names->type = b;
+ while (b < e && *++t)
+ *b++ = *t;
+ *b++ = 0;
+ }
+ else
+ {
+ names->name = (char*)name;
+ names->type = 0;
+ }
+ *(names->path = b) = 0;
+ names->opts = 0;
+ names->id = (char*)id;
+ return names;
+}
+
+/*
+ * return method pointer for <id,version> in names
+ */
+
+void*
+dll_lib(Dllnames_t* names, unsigned long version, Dllerror_f errorf, void* disc)
+{
+ void* dll;
+ Dll_lib_t* lib;
+ Dll_lib_f libf;
+ int n;
+ char sym[64];
+
+ static Dll_lib_t* loaded;
+
+ if (!names)
+ return 0;
+
+ /*
+ * check if plugin already loaded
+ */
+
+ for (lib = loaded; lib; lib = lib->next)
+ if (streq(names->base, lib->base))
+ {
+ libf = lib->libf;
+ goto init;
+ }
+
+ /*
+ * load
+ */
+
+ if (!(dll = dllplugin(names->id, names->name, NiL, version, NiL, RTLD_LAZY, names->path, names->data + sizeof(names->data) - names->path)) && (streq(names->name, names->base) || !(dll = dllplugin(names->id, names->base, NiL, version, NiL, RTLD_LAZY, names->path, names->data + sizeof(names->data) - names->path))))
+ {
+ if (errorf)
+ (*errorf)(NiL, disc, 2, "%s: library not found", names->name);
+ return 0;
+ }
+
+ /*
+ * init
+ */
+
+ sfsprintf(sym, sizeof(sym), "%s_lib", names->id);
+ if (!(libf = (Dll_lib_f)dlllook(dll, sym)))
+ {
+ if (errorf)
+ (*errorf)(NiL, disc, 2, "%s: %s: initialization function not found in library", names->path, sym);
+ return 0;
+ }
+
+ /*
+ * add to the loaded list
+ */
+
+ if (lib = newof(0, Dll_lib_t, 1, (n = strlen(names->base)) + strlen(names->path) + 1))
+ {
+ lib->libf = libf;
+ strcpy(lib->base, names->base);
+ strcpy(lib->path = lib->base + n + 1, names->path);
+ lib->next = loaded;
+ loaded = lib;
+ }
+ init:
+ return (*libf)(names->path, disc, names->type);
+}
+
+/*
+ * return method pointer for <id,name,version>
+ */
+
+void*
+dllmeth(const char* id, const char* name, unsigned long version)
+{
+ Dllnames_t names;
+
+ return dll_lib(dllnames(id, name, &names), version, 0, 0);
+}
diff --git a/src/lib/libdll/dllcheck.c b/src/lib/libdll/dllcheck.c
new file mode 100644
index 0000000..c18f83e
--- /dev/null
+++ b/src/lib/libdll/dllcheck.c
@@ -0,0 +1,85 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include "dlllib.h"
+
+/*
+ * return plugin version for dll
+ * 0 if there is none
+ * path!=0 enables library level diagnostics
+ */
+
+extern unsigned long
+dllversion(void* dll, const char* path)
+{
+ Dll_plugin_version_f pvf;
+
+ if (pvf = (Dll_plugin_version_f)dlllook(dll, "plugin_version"))
+ return (*pvf)();
+ if (path)
+ {
+ state.error = 1;
+ sfsprintf(state.errorbuf, sizeof(state.errorbuf), "plugin_version() not found");
+ errorf("dll", NiL, 1, "%s: %s", path, state.errorbuf);
+ }
+ return 0;
+}
+
+/*
+ * check if dll on path has plugin version >= ver
+ * 1 returned on success, 0 on failure
+ * path!=0 enables library level diagnostics
+ * cur!=0 gets actual version
+ */
+
+extern int
+dllcheck(void* dll, const char* path, unsigned long ver, unsigned long* cur)
+{
+ unsigned long v;
+ Dll_plugin_version_f pvf;
+
+ state.error = 0;
+ if (ver || cur)
+ {
+ v = dllversion(dll, path);
+ if (cur)
+ *cur = v;
+ }
+ if (!ver)
+ return 1;
+ if (!v)
+ return 0;
+ if (v < ver)
+ {
+ if (path)
+ {
+ state.error = 1;
+ sfsprintf(state.errorbuf, sizeof(state.errorbuf), "plugin version %lu older than caller %lu", v, ver);
+ errorf("dll", NiL, 1, "%s: %s", path, state.errorbuf);
+ }
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/lib/libdll/dllerror.c b/src/lib/libdll/dllerror.c
new file mode 100644
index 0000000..dd0278d
--- /dev/null
+++ b/src/lib/libdll/dllerror.c
@@ -0,0 +1,52 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include "dlllib.h"
+
+Dllstate_t state;
+
+/*
+ * return error message from last failed dl*() call
+ * retain==0 resets the last dl*() error
+ */
+
+extern char*
+dllerror(int retain)
+{
+ char* s;
+
+ if (state.error)
+ {
+ state.error = retain;
+ return state.errorbuf;
+ }
+ s = dlerror();
+ if (retain)
+ {
+ state.error = retain;
+ sfsprintf(state.errorbuf, sizeof(state.errorbuf), "%s", s);
+ }
+ return s;
+}
diff --git a/src/lib/libdll/dllfind.c b/src/lib/libdll/dllfind.c
new file mode 100644
index 0000000..6446663
--- /dev/null
+++ b/src/lib/libdll/dllfind.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <dlldefs.h>
+#include <error.h>
+
+/*
+ * find and load library name with optional version ver and dlopen() flags
+ * at least one dlopen() is called to initialize dlerror()
+ * if path!=0 then library path up to size chars copied to path with trailing 0
+ * if name contains a directory prefix then library search is limited to the dir and siblings
+ */
+
+extern void*
+dllfind(const char* lib, const char* ver, int flags, char* path, size_t size)
+{
+ char* id;
+ void* dll;
+
+ if ((id = error_info.id) && (dll = dllplug(id, lib, ver, flags, path, size)))
+ return dll;
+ return dllplug(NiL, lib, ver, flags, path, size);
+}
diff --git a/src/lib/libdll/dlllib.h b/src/lib/libdll/dlllib.h
new file mode 100644
index 0000000..c5fb1ab
--- /dev/null
+++ b/src/lib/libdll/dlllib.h
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <dlldefs.h>
+#include <error.h>
+
+#define state _dll_state
+
+typedef struct Dllstate_s
+{
+ int error;
+ char errorbuf[128];
+} Dllstate_t;
+
+extern Dllstate_t state;
diff --git a/src/lib/libdll/dlllook.c b/src/lib/libdll/dlllook.c
new file mode 100644
index 0000000..10928a6
--- /dev/null
+++ b/src/lib/libdll/dlllook.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <dlldefs.h>
+
+/*
+ * dlsym() with `_' weak fallback
+ */
+
+void*
+dlllook(void* dll, const char* name)
+{
+ register void* addr;
+ char buf[256];
+
+ if (!(addr = dlsym(dll, name)) && strlen(name) < (sizeof(buf) - 2))
+ {
+ buf[0] = '_';
+ strcpy(buf + 1, name);
+ addr = dlsym(dll, buf);
+ }
+ return addr;
+}
diff --git a/src/lib/libdll/dllnext.c b/src/lib/libdll/dllnext.c
new file mode 100644
index 0000000..9e81c4a
--- /dev/null
+++ b/src/lib/libdll/dllnext.c
@@ -0,0 +1,223 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__ 1
+#endif
+
+#include <ast.h>
+#include <dlldefs.h>
+
+#if _hdr_rld_interface
+#include <rld_interface.h>
+#endif
+
+/*
+ * return a handle for the next layer down,
+ * i.e., the next layer that has symbols covered
+ * by the main prog and dll's loaded so far
+ *
+ * intentionally light on external lib calls
+ * so this routine can be used early in process
+ * startup
+ */
+
+#ifdef _DLL_RLD_SYM
+
+#define DEBUG 1
+
+#if DEBUG
+
+typedef ssize_t (*Write_f)(int, const void*, size_t);
+
+#endif
+
+#undef dllnext
+
+void*
+_dll_next(int flags, _DLL_RLD_SYM_TYPE* here)
+{
+ register char* vp;
+ register void* lp;
+ register int found = 0;
+ char* s;
+ char* b;
+ char* e;
+ char dummy[256];
+#if DEBUG
+ Write_f wr = 0;
+ Write_f xr;
+ char buf[1024];
+#endif
+
+#if DEBUG
+ if (getenv("DLL_DEBUG") && (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME)))
+ {
+ do
+ {
+ if (strcmp(vp, "MAIN") && (lp = dllopen(vp, flags)))
+ {
+ if (xr = (Write_f)dlsym(lp, "write"))
+ wr = xr;
+ }
+ } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME));
+ }
+#endif
+ if (vp = (char*)_rld_new_interface(_RLD_FIRST_PATHNAME))
+ {
+ do
+ {
+ if (lp = dllopen(strcmp(vp, "MAIN") ? vp : (char*)0, flags))
+ {
+ if (found)
+ {
+ b = e = 0;
+ s = vp;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ break;
+ case '/':
+ b = s;
+ e = 0;
+ continue;
+ case '.':
+ if (!e)
+ e = s - 1;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ if (b && e)
+ {
+ s = dummy;
+ *s++ = '_';
+ *s++ = '_';
+ while (b < e)
+ *s++ = *b++;
+ b = "_dummy";
+ while (*s++ = *b++);
+ if (dlsym(lp, dummy))
+ {
+ dlclose(lp);
+ lp = 0;
+ }
+ }
+ if (lp)
+ {
+#if DEBUG
+ if (wr)
+ (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: next %s\n", vp));
+#endif
+ return lp;
+ }
+#if DEBUG
+ else if (wr)
+ (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: skip %s\n", vp));
+#endif
+ }
+ else if ((_DLL_RLD_SYM_TYPE*)dlsym(lp, _DLL_RLD_SYM_STR) == here)
+ {
+#if DEBUG
+ if (wr)
+ (*wr)(2, buf, sfsprintf(buf, sizeof(buf), "dll: this %s\n", vp));
+#endif
+ found = 1;
+ }
+ }
+ } while (vp = (char*)_rld_new_interface(_RLD_NEXT_PATHNAME));
+ }
+ return dllnext(flags);
+}
+
+#endif
+
+#ifndef RTLD_NEXT
+#if _dll_DYNAMIC
+
+#include <link.h>
+
+extern struct link_dynamic _DYNAMIC;
+
+#endif
+#endif
+
+void*
+dllnext(int flags)
+{
+ register void* dll;
+#ifndef RTLD_NEXT
+#if _dll_DYNAMIC
+ register struct link_map* map;
+ register char* s;
+ register char* b;
+#endif
+ register char* ver;
+ char* path;
+
+ static char next[] = { _DLL_NEXT_PATH };
+#endif
+
+#ifdef RTLD_NEXT
+ dll = RTLD_NEXT;
+#else
+ path = next;
+#if _dll_DYNAMIC
+ for (map = _DYNAMIC.ld_un.ld_1->ld_loaded; map; map = map->lm_next)
+ {
+ b = 0;
+ s = map->lm_name;
+ while (*s)
+ if (*s++ == '/')
+ b = s;
+ if (b && b[0] == 'l' && b[1] == 'i' && b[2] == 'b' && b[3] == 'c' && b[4] == '.')
+ {
+ path = map->lm_name;
+ break;
+ }
+ }
+#endif
+ ver = path + strlen(path);
+ while (!(dll = dllopen(path, flags)))
+ {
+ do
+ {
+ if (ver <= path)
+ return 0;
+ } while (*--ver != '.');
+ if (*(ver + 1) <= '0' || *(ver + 1) >= '9')
+ return 0;
+ *ver = 0;
+ }
+#endif
+ return dll;
+}
diff --git a/src/lib/libdll/dllopen.c b/src/lib/libdll/dllopen.c
new file mode 100644
index 0000000..0fac2d0
--- /dev/null
+++ b/src/lib/libdll/dllopen.c
@@ -0,0 +1,93 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * at&t research
+ */
+
+#include "dlllib.h"
+
+#if 0
+
+/*
+ * dlopen() wrapper that properly initializes LIBPATH
+ * with the path of the dll to be opened
+ *
+ * 2009-04-15 -- if ld.so re-checked the env this would work ...
+ */
+
+void*
+dllopen(const char* name, int mode)
+{
+ void* dll;
+ Dllinfo_t* info;
+ char* olibpath;
+ char* path;
+ char* oenv;
+ char* nenv[2];
+ char* dir;
+ char* base;
+ int len;
+
+ if (!environ)
+ {
+ nenv[0] = nenv[1] = 0;
+ environ = nenv;
+ }
+ info = dllinfo();
+ oenv = environ[0];
+ olibpath = getenv(info->env);
+ if (base = strrchr(name, '/'))
+ {
+ dir = (char*)name;
+ len = ++base - dir;
+ }
+ else
+ {
+ dir = "./";
+ len = 2;
+ base = (char*)name;
+ }
+ path = sfprints("%-.*s%s%c%s=%-.*s%s%s", len, dir, base, 0, info->env, len, dir, olibpath ? ":" : "", olibpath ? olibpath : "");
+ environ[0] = path + strlen(path) + 1;
+ state.error = 0;
+ dll = dlopen(path, mode);
+ if (environ == nenv)
+ environ = 0;
+ else
+ environ[0] = oenv;
+ return dll;
+}
+
+#else
+
+/*
+ * dlopen() wrapper -- waiting for prestidigitaions
+ */
+
+void*
+dllopen(const char* name, int mode)
+{
+ state.error = 0;
+ return dlopen(name, mode);
+}
+
+#endif
diff --git a/src/lib/libdll/dllplug.c b/src/lib/libdll/dllplug.c
new file mode 100644
index 0000000..3854762
--- /dev/null
+++ b/src/lib/libdll/dllplug.c
@@ -0,0 +1,126 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include "dlllib.h"
+
+/*
+ * find and load lib plugin/module library name with optional version ver and dlopen() flags
+ * at least one dlopen() is called to initialize dlerror()
+ * if path!=0 then library path up to size chars copied to path with trailing 0
+ * if name contains a directory prefix then library search is limited to the dir and siblings
+ */
+
+extern void*
+dllplugin(const char* lib, const char* name, const char* ver, unsigned long rel, unsigned long* cur, int flags, char* path, size_t size)
+{
+ void* dll;
+ int err;
+ int hit;
+ Dllscan_t* dls;
+ Dllent_t* dle;
+
+ err = hit = 0;
+ for (;;)
+ {
+ if (dls = dllsopen(lib, name, ver))
+ {
+ while (dle = dllsread(dls))
+ {
+ hit = 1;
+#if 0
+ again:
+#endif
+ if (dll = dllopen(dle->path, flags|RTLD_GLOBAL|RTLD_PARENT))
+ {
+ if (!dllcheck(dll, dle->path, rel, cur))
+ {
+ err = state.error;
+ dlclose(dll);
+ dll = 0;
+ continue;
+ }
+ if (path && size)
+ strlcpy(path, dle->path, size);
+ break;
+ }
+ else
+ {
+#if 0
+ /*
+ * dlopen() should load implicit libraries
+ * this code does that
+ * but it doesn't help on galadriel
+ */
+
+ char* s;
+ char* e;
+
+ if ((s = dllerror(1)) && (e = strchr(s, ':')))
+ {
+ *e = 0;
+ error(1, "AHA %s implicit", s);
+ dll = dllplugin(lib, s, 0, 0, 0, flags, path, size);
+ *e = ':';
+ if (dll)
+ {
+ error(1, "AHA implicit %s => %s", s, path);
+ goto again;
+ }
+ }
+#endif
+ errorf("dll", NiL, 1, "%s: dlopen failed: %s", dle->path, dllerror(1));
+ err = state.error;
+ }
+ }
+ dllsclose(dls);
+ }
+ if (hit)
+ {
+ if (!dll)
+ state.error = err;
+ return dll;
+ }
+ if (!lib)
+ break;
+ lib = 0;
+ }
+ if (dll = dllopen(name, flags))
+ {
+ if (!dllcheck(dll, name, rel, cur))
+ {
+ dlclose(dll);
+ dll = 0;
+ }
+ else if (path && size)
+ strlcpy(path, name, size);
+ }
+ return dll;
+}
+
+extern void*
+dllplug(const char* lib, const char* name, const char* ver, int flags, char* path, size_t size)
+{
+ return dllplugin(lib, name, ver, 0, NiL, flags, path, size);
+}
diff --git a/src/lib/libdll/dllscan.c b/src/lib/libdll/dllscan.c
new file mode 100644
index 0000000..1c8f5a5
--- /dev/null
+++ b/src/lib/libdll/dllscan.c
@@ -0,0 +1,525 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1997-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#define _DLLINFO_PRIVATE_ \
+ char* sib[3]; \
+ char sibbuf[64]; \
+ char envbuf[64];
+
+#define _DLLSCAN_PRIVATE_ \
+ Dllent_t entry; \
+ Uniq_t* uniq; \
+ int flags; \
+ Vmalloc_t* vm; \
+ Dt_t* dict; \
+ Dtdisc_t disc; \
+ FTS* fts; \
+ FTSENT* ent; \
+ Sfio_t* tmp; \
+ char** sb; \
+ char** sp; \
+ char* pb; \
+ char* pp; \
+ char* pe; \
+ int off; \
+ int prelen; \
+ int suflen; \
+ char** lib; \
+ char nam[64]; \
+ char pat[64]; \
+ char buf[64];
+
+#define DLL_MATCH_DONE 0x8000
+#define DLL_MATCH_NAME 0x4000
+#define DLL_MATCH_VERSION 0x2000
+
+#include <ast.h>
+#include <cdt.h>
+#include <ctype.h>
+#include <error.h>
+#include <fts.h>
+#include <vmalloc.h>
+
+typedef struct Uniq_s
+{
+ Dtlink_t link;
+ char name[1];
+} Uniq_t;
+
+#include <dlldefs.h>
+
+static char bin[] = "bin";
+static char lib[] = "lib";
+
+/*
+ * we need a sibling dir in PATH to search for dlls
+ * the confstr LIBPATH provides the local info
+ *
+ * <sibling-dir>[:<env-var>[:<host-pattern>]][,...]
+ *
+ * if <host-pattern> is present then it must match confstr HOSTTYPE
+ */
+
+Dllinfo_t*
+dllinfo(void)
+{
+ register char* s;
+ register char* h;
+ char* d;
+ char* v;
+ char* p;
+ int dn;
+ int vn;
+ int pn;
+ char pat[256];
+
+ static Dllinfo_t info;
+
+ if (!info.sibling)
+ {
+ info.sibling = info.sib;
+ if (*(s = astconf("LIBPATH", NiL, NiL)))
+ {
+ while (*s == ':' || *s == ',')
+ s++;
+ if (*s)
+ {
+ h = 0;
+ for (;;)
+ {
+ for (d = s; *s && *s != ':' && *s != ','; s++);
+ if (!(dn = s - d))
+ d = 0;
+ if (*s == ':')
+ {
+ for (v = ++s; *s && *s != ':' && *s != ','; s++);
+ if (!(vn = s - v))
+ v = 0;
+ if (*s == ':')
+ {
+ for (p = ++s; *s && *s != ':' && *s != ','; s++);
+ if (!(pn = s - p))
+ p = 0;
+ }
+ else
+ p = 0;
+ }
+ else
+ {
+ v = 0;
+ p = 0;
+ }
+ while (*s && *s++ != ',');
+ if (!*s || !p || !h && !*(h = astconf("HOSTTYPE", NiL, NiL)))
+ break;
+ if (pn >= sizeof(pat))
+ pn = sizeof(pat) - 1;
+ memcpy(pat, p, pn);
+ pat[pn] = 0;
+ if (strmatch(h, pat))
+ break;
+ }
+ if (d && dn < sizeof(info.sibbuf))
+ {
+ memcpy(info.sibbuf, d, dn);
+ info.sibling[0] = info.sibbuf;
+ }
+ if (v && vn < sizeof(info.envbuf))
+ {
+ memcpy(info.envbuf, v, vn);
+ info.env = info.envbuf;
+ }
+ }
+ }
+ if (!info.sibling[0] || streq(info.sibling[0], bin))
+ info.sibling[0] = bin;
+ if (!streq(info.sibling[0], lib))
+ info.sibling[1] = lib;
+ if (!info.env)
+ info.env = "LD_LIBRARY_PATH";
+ info.prefix = astconf("LIBPREFIX", NiL, NiL);
+ info.suffix = astconf("LIBSUFFIX", NiL, NiL);
+ if (streq(info.suffix, ".dll"))
+ info.flags |= DLL_INFO_PREVER;
+ else
+ info.flags |= DLL_INFO_DOTVER;
+ }
+ return &info;
+}
+
+/*
+ * fts version sort order
+ * higher versions appear first
+ */
+
+static int
+vercmp(FTSENT* const* ap, FTSENT* const* bp)
+{
+ register unsigned char* a = (unsigned char*)(*ap)->fts_name;
+ register unsigned char* b = (unsigned char*)(*bp)->fts_name;
+ register int n;
+ register int m;
+ char* e;
+
+ for (;;)
+ {
+ if (isdigit(*a) && isdigit(*b))
+ {
+ m = strtol((char*)a, &e, 10);
+ a = (unsigned char*)e;
+ n = strtol((char*)b, &e, 10);
+ b = (unsigned char*)e;
+ if (n -= m)
+ return n;
+ }
+ if (n = *a - *b)
+ return n;
+ if (!*a++)
+ return *b ? 0 : -1;
+ if (!*b++)
+ return 1;
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * open a scan stream
+ */
+
+Dllscan_t*
+dllsopen(const char* lib, const char* name, const char* version)
+{
+ register char* s;
+ register char* t;
+ Dllscan_t* scan;
+ Dllinfo_t* info;
+ Vmalloc_t* vm;
+ int i;
+ int j;
+ int k;
+ char buf[32];
+
+ if (!(vm = vmopen(Vmdcheap, Vmlast, 0)))
+ return 0;
+ if (lib && *lib && (*lib != '-' || *(lib + 1)))
+ {
+ /*
+ * grab the local part of the library id
+ */
+
+ if (s = strrchr(lib, ':'))
+ lib = (const char*)(s + 1);
+ i = 2 * sizeof(char**) + strlen(lib) + 5;
+ }
+ else
+ {
+ lib = 0;
+ i = 0;
+ }
+ if (version && (!*version || *version == '-' && !*(version + 1)))
+ version = 0;
+ if (!(scan = vmnewof(vm, 0, Dllscan_t, 1, i)) || !(scan->tmp = sfstropen()))
+ {
+ vmclose(vm);
+ return 0;
+ }
+ scan->vm = vm;
+ info = dllinfo();
+ scan->flags = info->flags;
+ if (lib)
+ {
+ scan->lib = (char**)(scan + 1);
+ s = *scan->lib = (char*)(scan->lib + 2);
+ sfsprintf(s, i, "lib/%s", lib);
+ if (!version && streq(info->suffix, ".dylib"))
+ version = "0.0";
+ }
+ if (!name || !*name || *name == '-' && !*(name + 1))
+ {
+ name = (const char*)"?*";
+ scan->flags |= DLL_MATCH_NAME;
+ }
+ else if (t = strrchr(name, '/'))
+ {
+ if (!(scan->pb = vmnewof(vm, 0, char, t - (char*)name, 2)))
+ goto bad;
+ memcpy(scan->pb, name, t - (char*)name);
+ name = (const char*)(t + 1);
+ }
+ if (name)
+ {
+ i = strlen(name);
+ j = strlen(info->prefix);
+ if (!j || i > j && strneq(name, info->prefix, j))
+ {
+ k = strlen(info->suffix);
+ if (i > k && streq(name + i - k, info->suffix))
+ {
+ i -= j + k;
+ if (!(t = vmnewof(vm, 0, char, i, 1)))
+ goto bad;
+ memcpy(t, name + j, i);
+ t[i] = 0;
+ name = (const char*)t;
+ }
+ }
+ if (!version)
+ for (t = (char*)name; *t; t++)
+ if ((*t == '-' || *t == '.' || *t == '?') && isdigit(*(t + 1)))
+ {
+ if (*t != '-')
+ scan->flags |= DLL_MATCH_VERSION;
+ version = t + 1;
+ if (!(s = vmnewof(vm, 0, char, t - (char*)name, 1)))
+ goto bad;
+ memcpy(s, name, t - (char*)name);
+ name = (const char*)s;
+ break;
+ }
+ }
+ if (!version)
+ {
+ scan->flags |= DLL_MATCH_VERSION;
+ sfsprintf(scan->nam, sizeof(scan->nam), "%s%s%s", info->prefix, name, info->suffix);
+ }
+ else if (scan->flags & DLL_INFO_PREVER)
+ {
+ sfprintf(scan->tmp, "%s%s", info->prefix, name);
+ for (s = (char*)version; *s; s++)
+ if (isdigit(*s))
+ sfputc(scan->tmp, *s);
+ sfprintf(scan->tmp, "%s", info->suffix);
+ if (!(s = sfstruse(scan->tmp)))
+ goto bad;
+ sfsprintf(scan->nam, sizeof(scan->nam), "%s", s);
+ }
+ else
+ sfsprintf(scan->nam, sizeof(scan->nam), "%s%s%s.%s", info->prefix, name, info->suffix, version);
+ if (scan->flags & (DLL_MATCH_NAME|DLL_MATCH_VERSION))
+ {
+ if (scan->flags & DLL_INFO_PREVER)
+ {
+ if (!version)
+ version = "*([0-9_])";
+ else
+ {
+ t = buf;
+ for (s = (char*)version; *s; s++)
+ if (isdigit(*s) && t < &buf[sizeof(buf)-1])
+ *t++ = *s;
+ *t = 0;
+ version = (const char*)buf;
+ }
+ sfsprintf(scan->pat, sizeof(scan->pat), "%s%s%s%s", info->prefix, name, version, info->suffix);
+ }
+ else if (version)
+ sfsprintf(scan->pat, sizeof(scan->pat), "%s%s@(%s([-.])%s%s|%s.%s)", info->prefix, name, strchr(version, '.') ? "@" : "?", version, info->suffix, info->suffix, version);
+ else
+ {
+ version = "*([0-9.])";
+ sfsprintf(scan->pat, sizeof(scan->pat), "%s%s@(?([-.])%s%s|%s%s)", info->prefix, name, version, info->suffix, info->suffix, version);
+ }
+ }
+ scan->sp = scan->sb = (scan->lib ? scan->lib : info->sibling);
+ scan->prelen = strlen(info->prefix);
+ scan->suflen = strlen(info->suffix);
+ return scan;
+ bad:
+ dllsclose(scan);
+ return 0;
+}
+
+/*
+ * close a scan stream
+ */
+
+int
+dllsclose(Dllscan_t* scan)
+{
+ if (!scan)
+ return -1;
+ if (scan->fts)
+ fts_close(scan->fts);
+ if (scan->dict)
+ dtclose(scan->dict);
+ if (scan->tmp)
+ sfclose(scan->tmp);
+ if (scan->vm)
+ vmclose(scan->vm);
+ return 0;
+}
+
+/*
+ * return the next scan stream entry
+ */
+
+Dllent_t*
+dllsread(register Dllscan_t* scan)
+{
+ register char* p;
+ register char* b;
+ register char* t;
+ register Uniq_t* u;
+ register int n;
+ register int m;
+
+ if (scan->flags & DLL_MATCH_DONE)
+ return 0;
+ again:
+ do
+ {
+ while (!scan->ent || !(scan->ent = scan->ent->fts_link))
+ {
+ if (scan->fts)
+ {
+ fts_close(scan->fts);
+ scan->fts = 0;
+ }
+ if (!scan->pb)
+ scan->pb = pathbin();
+ else if (!*scan->sp)
+ {
+ scan->sp = scan->sb;
+ if (!*scan->pe++)
+ return 0;
+ scan->pb = scan->pe;
+ }
+ for (p = scan->pp = scan->pb; *p && *p != ':'; p++)
+ if (*p == '/')
+ scan->pp = p;
+ scan->pe = p;
+ if (*scan->sp == bin)
+ scan->off = sfprintf(scan->tmp, "%-.*s", scan->pe - scan->pb, scan->pb);
+ else
+ scan->off = sfprintf(scan->tmp, "%-.*s/%s", scan->pp - scan->pb, scan->pb, *scan->sp);
+ scan->sp++;
+ if (!(scan->flags & DLL_MATCH_NAME))
+ {
+ sfprintf(scan->tmp, "/%s", scan->nam);
+ if (!(p = sfstruse(scan->tmp)))
+ return 0;
+ if (!eaccess(p, R_OK))
+ {
+ b = scan->nam;
+ goto found;
+ }
+ if (errno != ENOENT)
+ continue;
+ }
+ if (scan->flags & (DLL_MATCH_NAME|DLL_MATCH_VERSION))
+ {
+ sfstrseek(scan->tmp, scan->off, SEEK_SET);
+ if (!(t = sfstruse(scan->tmp)))
+ return 0;
+ if ((scan->fts = fts_open((char**)t, FTS_LOGICAL|FTS_NOPOSTORDER|FTS_ONEPATH, vercmp)) && (scan->ent = fts_read(scan->fts)) && (scan->ent = fts_children(scan->fts, FTS_NOSTAT)))
+ break;
+ }
+ }
+ } while (!strmatch(scan->ent->fts_name, scan->pat));
+ b = scan->ent->fts_name;
+ sfstrseek(scan->tmp, scan->off, SEEK_SET);
+ sfprintf(scan->tmp, "/%s", b);
+ if (!(p = sfstruse(scan->tmp)))
+ return 0;
+ found:
+ b = scan->buf + sfsprintf(scan->buf, sizeof(scan->buf), "%s", b + scan->prelen);
+ if (!(scan->flags & DLL_INFO_PREVER))
+ while (b > scan->buf)
+ {
+ if (!isdigit(*(b - 1)) && *(b - 1) != '.')
+ break;
+ b--;
+ }
+ b -= scan->suflen;
+ if (b > (scan->buf + 2) && (*(b - 1) == 'g' || *(b - 1) == 'O') && *(b - 2) == '-')
+ b -= 2;
+ n = m = 0;
+ for (t = b; t > scan->buf; t--)
+ if (isdigit(*(t - 1)))
+ n = 1;
+ else if (*(t - 1) != m)
+ {
+ if (*(t - 1) == '.' || *(t - 1) == '-' || *(t - 1) == '_')
+ {
+ n = 1;
+ if (m)
+ {
+ m = -1;
+ t--;
+ break;
+ }
+ m = *(t - 1);
+ }
+ else
+ break;
+ }
+ if (n)
+ {
+ if (isdigit(t[0]) && isdigit(t[1]) && !isdigit(t[2]))
+ n = (t[0] - '0') * 10 + (t[1] - '0');
+ else if (isdigit(t[1]) && isdigit(t[2]) && !isdigit(t[3]))
+ n = (t[1] - '0') * 10 + (t[2] - '0');
+ else
+ n = 0;
+ if (n && !(n & (n - 1)))
+ {
+ if (!isdigit(t[0]))
+ t++;
+ m = *(t += 2);
+ }
+ if (m || (scan->flags & DLL_INFO_PREVER))
+ b = t;
+ }
+ *b = 0;
+ if (!*(b = scan->buf))
+ goto again;
+ if (scan->uniq)
+ {
+ if (!scan->dict)
+ {
+ scan->disc.key = offsetof(Uniq_t, name);
+ scan->disc.size = 0;
+ scan->disc.link = offsetof(Uniq_t, link);
+ if (!(scan->dict = dtopen(&scan->disc, Dtset)))
+ return 0;
+ dtinsert(scan->dict, scan->uniq);
+ }
+ if (dtmatch(scan->dict, b))
+ goto again;
+ if (!(u = vmnewof(scan->vm, 0, Uniq_t, 1, strlen(b))))
+ return 0;
+ strcpy(u->name, b);
+ dtinsert(scan->dict, u);
+ }
+ else if (!(scan->flags & DLL_MATCH_NAME))
+ scan->flags |= DLL_MATCH_DONE;
+ else if (!(scan->uniq = vmnewof(scan->vm, 0, Uniq_t, 1, strlen(b))))
+ return 0;
+ else
+ strcpy(scan->uniq->name, b);
+ scan->entry.name = b;
+ scan->entry.path = p;
+ return &scan->entry;
+}
diff --git a/src/lib/libdll/features/dll b/src/lib/libdll/features/dll
new file mode 100644
index 0000000..691012f
--- /dev/null
+++ b/src/lib/libdll/features/dll
@@ -0,0 +1,263 @@
+set prototyped
+hdr dl,dlfcn,dll,rld_interface,mach-o/dyld
+sys ldr
+lib dlopen -ldl
+lib dllload,loadbind,shl_load -ldl
+tst dll_DYNAMIC link{
+ #include <sys/types.h>
+ #include <link.h>
+ extern struct link_dynamic _DYNAMIC;
+ int
+ main()
+ {
+ return _DYNAMIC.ld_version;
+ }
+}end
+tst run{
+ lib=
+ for d in /shlib /usr/shlib /lib /usr/lib
+ do if test -d $d
+ then for s in "*.*" "*[!a]*"
+ do for b in libc
+ do for i in $d/$b.$s
+ do if test -f $i
+ then lib=$i
+ fi
+ done
+ case $lib in
+ ?*) break 3 ;;
+ esac
+ done
+ done
+ fi
+ done
+ case $lib in
+ *.[0-9]*.[0-9]*)
+ i=`echo $lib | sed 's,\([^0-9]*[0-9]*\).*,\1,'`
+ if test -f $i
+ then lib=$i
+ fi
+ ;;
+ esac
+ # some run time linkers barf with /lib/xxx if
+ # /usr/lib/xxx is there
+ case $lib in
+ /usr*) ;;
+ *) if test -f /usr$lib
+ then lib=/usr$lib
+ fi
+ ;;
+ esac
+ case $lib in
+ "") lib=/lib/libc.so.1 ;;
+ esac
+ case $lib in
+ /usr/lib/*)
+ case `package` in
+ sgi.mips3)
+ abi=/lib32
+ ;;
+ sgi.mips4)
+ abi=/lib64
+ ;;
+ *) abi=
+ ;;
+ esac
+ case $abi in
+ ?*) if test -d $abi
+ then lib=`echo $lib | sed 's,/usr/lib/,,'`
+ lib=$abi/$lib
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ echo "#define _DLL_NEXT_PATH \"$lib\""
+}end
+tst - output{
+ #if defined(__MVS__) && !defined(__SUSV3)
+ #define __SUSV3 1
+ #endif
+ #if _hdr_dlfcn && _lib_dlopen
+ #include <dlfcn.h>
+ #endif
+ #if _hdr_rld_interface
+ #include <rld_interface.h>
+ #endif
+ int
+ main()
+ {
+ int i;
+ #if _hdr_rld_interface
+ void* dll;
+ static char* local[] = { "__elf_header", "_call_add_gp_range", "_etext" };
+ #endif
+ printf("\n");
+ printf("#if defined(__MVS__) && !defined(__SUSV3)\n");
+ printf("#define __SUSV3 1\n");
+ printf("#endif\n");
+ #if _hdr_dlfcn && _lib_dlopen
+ printf("#include <dlfcn.h>\n");
+ #endif
+ #ifndef RTLD_LAZY
+ i = 0;
+ printf("\n");
+ printf("#define RTLD_LAZY 1\n");
+ #else
+ i = 1;
+ #endif
+ #ifndef RTLD_NOW
+ if (i)
+ {
+ i = 0;
+ printf("\n");
+ }
+ printf("#define RTLD_NOW 2\n");
+ #endif
+ #ifndef RTLD_GLOBAL
+ if (i)
+ {
+ i = 0;
+ printf("\n");
+ }
+ printf("#define RTLD_GLOBAL 0\n");
+ #endif
+ #ifndef RTLD_LOCAL
+ if (i)
+ {
+ i = 0;
+ printf("\n");
+ }
+ printf("#define RTLD_LOCAL 0\n");
+ #endif
+ #ifndef RTLD_PARENT
+ if (i)
+ {
+ i = 0;
+ printf("\n");
+ }
+ printf("#define RTLD_PARENT 0\n");
+ #endif
+ #if defined(_hdr_mach_o_dyld) && !defined(RTLD_NEXT)
+ if (i)
+ {
+ i = 0;
+ printf("\n");
+ }
+ printf("#define RTLD_NEXT ((void*)16)\n");
+ #endif
+ #if _hdr_rld_interface
+ if (!(dll = dlopen(0, RTLD_LAZY)))
+ i = -1;
+ else
+ {
+ for (i = 0; i < sizeof(local) / sizeof(local[0]); i++)
+ if (dlsym(dll, local[i]))
+ break;
+ if (i >= sizeof(local) / sizeof(local[0]))
+ i = -1;
+ }
+ if (i >= 0)
+ {
+ printf("\n");
+ printf("#define _DLL_RLD_SYM %s\n", local[i]);
+ printf("#define _DLL_RLD_SYM_STR \"%s\"\n", local[i]);
+ printf("#define _DLL_RLD_SYM_TYPE void*\n");
+ }
+ #endif
+ printf("\n");
+ printf("#define DLL_INFO_PREVER 0x0001 /* pre-suffix style version */\n");
+ printf("#define DLL_INFO_DOTVER 0x0002 /* post-suffix style version */\n");
+ printf("\n");
+ printf("typedef unsigned long (*Dll_plugin_version_f)(void);\n");
+ printf("typedef int (*Dllerror_f)(void*, void*, int, ...);\n");
+ printf("\n");
+ printf("typedef struct Dllinfo_s\n");
+ printf("{\n");
+ printf(" char** sibling; /* sibling dirs on $PATH */\n");
+ printf(" char* prefix; /* library name prefix */\n");
+ printf(" char* suffix; /* library name suffix */\n");
+ printf(" char* env; /* library path env var */\n");
+ printf(" int flags; /* DLL_INFO_* flags */\n");
+ printf("#ifdef _DLLINFO_PRIVATE_\n");
+ printf(" _DLLINFO_PRIVATE_\n");
+ printf("#endif\n");
+ printf("} Dllinfo_t;\n");
+ printf("\n");
+ printf("typedef struct Dllnames_s\n");
+ printf("{\n");
+ printf(" char* id;\n");
+ printf(" char* name;\n");
+ printf(" char* base;\n");
+ printf(" char* type;\n");
+ printf(" char* opts;\n");
+ printf(" char* path;\n");
+ printf(" char data[1024];\n");
+ printf("} Dllnames_t;\n");
+ printf("\n");
+ printf("typedef struct Dllent_s\n");
+ printf("{\n");
+ printf(" char* path;\n");
+ printf(" char* name;\n");
+ printf("#ifdef _DLLENT_PRIVATE_\n");
+ printf(" _DLLENT_PRIVATE_\n");
+ printf("#endif\n");
+ printf("} Dllent_t;\n");
+ printf("\n");
+ printf("typedef struct Dllscan_s\n");
+ printf("{\n");
+ printf(" void* pad;\n");
+ printf("#ifdef _DLLSCAN_PRIVATE_\n");
+ printf(" _DLLSCAN_PRIVATE_\n");
+ printf("#endif\n");
+ printf("} Dllscan_t;\n");
+ #if !_hdr_dlfcn || !_lib_dlopen
+ printf("\n");
+ printf("extern void* dlopen(const char*, int);\n");
+ printf("extern void* dlsym(void*, const char*);\n");
+ printf("extern int dlclose(void*);\n");
+ printf("extern char* dlerror(void);\n");
+ #endif
+ printf("\n");
+ printf("#if _BLD_dll && defined(__EXPORT__)\n");
+ printf("#define extern __EXPORT__\n");
+ printf("#endif\n");
+ printf("\n");
+ printf("extern Dllinfo_t* dllinfo(void);\n");
+ printf("extern void* dllplugin(const char*, const char*, const char*, unsigned long, unsigned long*, int, char*, size_t);\n");
+ printf("extern void* dllplug(const char*, const char*, const char*, int, char*, size_t);\n");
+ printf("extern void* dllfind(const char*, const char*, int, char*, size_t);\n");
+ printf("extern Dllnames_t* dllnames(const char*, const char*, Dllnames_t*);\n");
+ printf("extern void* dll_lib(Dllnames_t*, unsigned long, Dllerror_f, void*);\n");
+ printf("extern void* dllmeth(const char*, const char*, unsigned long);\n");
+ printf("extern void* dllopen(const char*, int);\n");
+ printf("extern void* dllnext(int);\n");
+ printf("extern void* dlllook(void*, const char*);\n");
+ printf("extern int dllcheck(void*, const char*, unsigned long, unsigned long*);\n");
+ printf("extern unsigned long dllversion(void*, const char*);\n");
+ printf("extern char* dllerror(int);\n");
+ #if _hdr_rld_interface
+ if (i >= 0)
+ {
+ printf("\n");
+ printf("extern void* _dll_next(int, _DLL_RLD_SYM_TYPE*);\n");
+ printf("#define dllnext(f) _dll_next(f, &_DLL_RLD_SYM)\n");
+ }
+ #endif
+ printf("\n");
+ printf("extern Dllscan_t* dllsopen(const char*, const char*, const char*);\n");
+ printf("extern Dllent_t* dllsread(Dllscan_t*);\n");
+ printf("extern int dllsclose(Dllscan_t*);\n");
+ printf("\n");
+ printf("#undef extern\n");
+ #if _hdr_rld_interface
+ if (i >= 0)
+ {
+ printf("\n");
+ printf("extern _DLL_RLD_SYM_TYPE _DLL_RLD_SYM;\n");
+ }
+ #endif
+ printf("\n");
+ return 0;
+ }
+}end