aboutsummaryrefslogtreecommitdiff
path: root/shared/unstable/loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared/unstable/loader.c')
-rw-r--r--shared/unstable/loader.c220
1 files changed, 152 insertions, 68 deletions
diff --git a/shared/unstable/loader.c b/shared/unstable/loader.c
index 91b7ff3..4872500 100644
--- a/shared/unstable/loader.c
+++ b/shared/unstable/loader.c
@@ -1,12 +1,10 @@
-/* Copyright (c) 1997-2003 Miller Puckette, krzYszcz, and others.
+/* Copyright (c) 1997-2005 Miller Puckette, krzYszcz, and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/* This is just a not-yet-in-the-API-sys_load_lib() duplication
(modulo differentiating the error return codes). LATER use the original. */
-#include "loader.h"
-
#ifdef __linux__
#include <dlfcn.h>
#endif
@@ -22,8 +20,11 @@
#include <mach-o/dyld.h>
#endif
#include <string.h>
-#include "m_pd.h"
#include <stdio.h>
+#include "m_pd.h"
+#include "common/loud.h"
+#include "common/os.h"
+#include "loader.h"
typedef void (*t_xxx)(void);
@@ -48,92 +49,175 @@ static char sys_dllextent[] =
".dll";
#endif
-int unstable_load_lib(char *dirname, char *classname)
+static int unstable_doload_lib(char *dirname, char *classname)
{
- char symname[MAXPDSTRING], filename[MAXPDSTRING], dirbuf[MAXPDSTRING],
- *nameptr, *lastdot;
+ char symname[MAXPDSTRING], filename[MAXPDSTRING], *lastdot;
void *dlobj;
t_xxx makeout;
- int fd;
#ifdef NT
HINSTANCE ntdll;
#endif
-#if 0
- fprintf(stderr, "lib %s %s\n", dirname, classname);
-#endif
- if ((fd = open_via_path(dirname, classname, sys_dllextent,
- dirbuf, &nameptr, MAXPDSTRING, 1)) < 0)
- {
- return (LOADER_NOFILE);
- }
- else
- {
- close(fd);
- /* refabricate the pathname */
- strcpy(filename, dirbuf);
- strcat(filename, "/");
- strcat(filename, nameptr);
- /* extract the setup function name */
- if (lastdot = strrchr(nameptr, '.'))
- *lastdot = 0;
+ /* refabricate the pathname */
+ strcpy(filename, dirname);
+ strcat(filename, "/");
+ strcat(filename, classname);
+ /* extract the setup function name */
+ if (lastdot = strrchr(classname, '.'))
+ *lastdot = 0;
#ifdef MACOSX
- strcpy(symname, "_");
- strcat(symname, nameptr);
+ strcpy(symname, "_");
+ strcat(symname, classname);
#else
- strcpy(symname, nameptr);
+ strcpy(symname, classname);
#endif
- /* if the last character is a tilde, replace with "_tilde" */
- if (symname[strlen(symname) - 1] == '~')
- strcpy(symname + (strlen(symname) - 1), "_tilde");
- /* and append _setup to form the C setup function name */
- strcat(symname, "_setup");
+ /* if the last character is a tilde, replace with "_tilde" */
+ if (symname[strlen(symname) - 1] == '~')
+ strcpy(symname + (strlen(symname) - 1), "_tilde");
+ /* and append _setup to form the C setup function name */
+ strcat(symname, "_setup");
#ifdef __linux__
- dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
- if (!dlobj)
- {
- post("%s: %s", filename, dlerror());
- return (LOADER_BADFILE);
- }
- makeout = (t_xxx)dlsym(dlobj, symname);
+ dlobj = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
+ if (!dlobj)
+ {
+ post("%s: %s", filename, dlerror());
+ return (LOADER_BADFILE);
+ }
+ makeout = (t_xxx)dlsym(dlobj, symname);
#endif
#ifdef NT
- sys_bashfilename(filename, filename);
- ntdll = LoadLibrary(filename);
- if (!ntdll)
- {
+ sys_bashfilename(filename, filename);
+ ntdll = LoadLibrary(filename);
+ if (!ntdll)
+ {
+ post("%s: couldn't load", filename);
+ return (LOADER_BADFILE);
+ }
+ makeout = (t_xxx)GetProcAddress(ntdll, symname);
+#endif
+#ifdef MACOSX
+ {
+ NSObjectFileImage image;
+ void *ret;
+ NSSymbol s;
+ if ( NSCreateObjectFileImageFromFile( filename, &image) != NSObjectFileImageSuccess )
+ {
post("%s: couldn't load", filename);
return (LOADER_BADFILE);
}
- makeout = (t_xxx)GetProcAddress(ntdll, symname);
-#endif
-#ifdef MACOSX
- {
- NSObjectFileImage image;
- void *ret;
- NSSymbol s;
- if ( NSCreateObjectFileImageFromFile( filename, &image) != NSObjectFileImageSuccess )
- {
- post("%s: couldn't load", filename);
- return (LOADER_BADFILE);
- }
- ret = NSLinkModule( image, filename,
- NSLINKMODULE_OPTION_BINDNOW
- + NSLINKMODULE_OPTION_PRIVATE);
+ ret = NSLinkModule( image, filename,
+ NSLINKMODULE_OPTION_BINDNOW
+ + NSLINKMODULE_OPTION_PRIVATE);
- s = NSLookupSymbolInModule(ret, symname);
+ s = NSLookupSymbolInModule(ret, symname);
- if (s)
- makeout = (t_xxx)NSAddressOfSymbol( s);
- else makeout = 0;
- }
-#endif
+ if (s)
+ makeout = (t_xxx)NSAddressOfSymbol( s);
+ else makeout = 0;
}
+#endif
if (!makeout)
{
- post("load_object: Symbol \"%s\" not found", symname);
- return (LOADER_NOENTRY);
+ post("load_object: Symbol \"%s\" not found", symname);
+ return (LOADER_NOENTRY);
}
(*makeout)();
return (LOADER_OK);
}
+
+/* start searching from dirname, then search the path */
+int unstable_load_lib(char *dirname, char *classname)
+{
+ char dirbuf[MAXPDSTRING], *nameptr;
+ int fd;
+ if ((fd = open_via_path(dirname, classname, sys_dllextent,
+ dirbuf, &nameptr, MAXPDSTRING, 1)) < 0)
+ {
+ return (LOADER_NOFILE);
+ }
+ else
+ {
+ close(fd);
+ return (unstable_doload_lib(dirbuf, nameptr));
+ }
+}
+
+/* only dirname is searched */
+int unstable_dirload_lib(char *dirname, char *classname)
+{
+ if (strlen(dirname) + strlen(classname) + strlen(sys_dllextent) + 3 <
+ MAXPDSTRING)
+ {
+ char namebuf[MAXPDSTRING], *slash, *nameptr;
+ strcpy(namebuf, dirname);
+ if (*dirname && namebuf[strlen(namebuf)-1] != '/')
+ strcat(namebuf, "/");
+ strcat(namebuf, classname);
+ strcat(namebuf, sys_dllextent);
+ slash = strrchr(namebuf, '/');
+ if (slash)
+ {
+ *slash = 0;
+ nameptr = slash + 1;
+ }
+ else nameptr = namebuf;
+ return (unstable_doload_lib(namebuf, nameptr));
+ }
+ else return (LOADER_FAILED);
+}
+
+/* return the number of successfully loaded libraries, or -1 on error */
+int unstable_dirload_all(char *dirname, int beloud, int withclasses)
+{
+ t_osdir *dp = osdir_open(dirname);
+ if (dp)
+ {
+ int result = 0;
+ char namebuf[MAXPDSTRING], *name;
+ osdir_setmode(dp, OSDIR_FILEMODE);
+ while (name = osdir_next(dp))
+ {
+ int namelen = strlen(name), extlen = strlen(sys_dllextent);
+ if ((namelen -= extlen) > 0 &&
+ strcmp(name + namelen, sys_dllextent) == 0)
+ {
+ strncpy(namebuf, name, namelen);
+ namebuf[namelen] = 0;
+ if (zgetfn(&pd_objectmaker, gensym(namebuf)))
+ {
+ if (beloud)
+ loud_warning(0, "xeq", "plugin \"%s\" already loaded",
+ namebuf);
+ }
+ else
+ {
+ int err;
+ if (beloud)
+ post("loading xeq plugin \"%s\"", namebuf);
+ err = unstable_dirload_lib(dirname, namebuf);
+ if (err == LOADER_NOFILE)
+ {
+ if (beloud)
+ loud_error(0, "xeq plugin \"%s\" disappeared",
+ namebuf);
+ }
+ else if (!zgetfn(&pd_objectmaker, gensym(namebuf)))
+ {
+ if (beloud)
+ loud_error(0, "library \"%s\" not compatible",
+ namebuf);
+ }
+ else result++;
+ }
+ }
+ }
+ osdir_close(dp);
+ return (result);
+ }
+ else
+ {
+ if (beloud)
+ loud_syserror(0, "cannot open \"%s\"", dirname);
+ return (-1);
+ }
+}