On Tue, Jun 17, 2003 at 05:52:43PM -0400, Brad Chapman wrote:
> (sorry about the long URL).
There really should be a universal clipboard system that non-X programs
could use too, but in the meanwhile: http://tinyurl.com/
> The short of it is that they are
> working on the update, but it's not there yet because it is a big
> job due to all the other software which depends on it.
I don't see a single problem in providing 1.4 (perhaps with a different
name if that would break the package system) in some non-default path.
Even cygwin provides both 1.4.3 and 1.5. (But unfortunately uses some
autoconf-dependant wrapper kludge to detect which to use.)
> Is this a case where I am stuck until FreeBSD gets up to date, or is
> using 1.3.4 an easy task?
I have attached modules.c from 20030601, it should work by just
copying it over the current one and should not use the iteration
functions. You still need CF_LTDL_ANCIENT for lt_dlinsertsearchdir in
readconfig.c, though. (Apparently the flag is useless after all as I
changed the rest of the code to refer to 1.4 functions so I don't
have to duplicate code.)
--
Tuomo
/*
* ion/ioncore/modules.c
*
* Copyright (c) Tuomo Valkonen 1999-2003.
*
* Ion is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*/
#include <ltdl.h>
#include <string.h>
#include <ctype.h>
#include "common.h"
#include "modules.h"
#include "readconfig.h"
#include "../version.h"
INTRSTRUCT(Module);
DECLSTRUCT(Module){
lt_dlhandle handle;
char *name;
Module *next, *prev;
};
static Module *modules=NULL;
/*{{{ Loading and initialization code */
static bool check_version(lt_dlhandle handle, char *name)
{
char *p=scat(name, "_module_ion_version");
char *versionstr;
if(p==NULL){
warn_err();
return FALSE;
}
versionstr=(char*)lt_dlsym(handle, p);
free(p);
if(versionstr==NULL)
return FALSE;
return (strcmp(versionstr, ION_VERSION)==0);
}
static bool call_init(lt_dlhandle handle, char *name)
{
char *p=scat(name, "_module_init");
bool (*initfn)(void);
if(p==NULL){
warn_err();
return FALSE;
}
initfn=(bool (*)())lt_dlsym(handle, p);
free(p);
if(initfn==NULL)
return TRUE;
return initfn();
}
bool init_module_support()
{
#ifdef CF_PRELOAD_MODULES
LTDL_SET_PRELOADED_SYMBOLS();
#endif
if(lt_dlinit()!=0){
warn("lt_dlinit: %s", lt_dlerror());
return FALSE;
}
return TRUE;
}
/*EXTL_DOC
* Attempt to load module \var{modname}. Ion will use libltdl to search
* library path (the default setting is \file{\~{}/.ion-devel/libs} and
* \file{\$PREFIX/lib/ion-devel}) and also try diffent extensions so only
* the module name should usually be necessary to give here.
*/
EXTL_EXPORT
bool load_module(const char *modname)
{
lt_dlhandle handle=NULL;
Module *m;
const char *p;
char *n;
size_t l;
if(modname==NULL)
return FALSE;
handle=lt_dlopenext(modname);
if(handle==NULL){
warn("Failed to load module %s: %s", modname, lt_dlerror());
return FALSE;
}
for(m=modules; m!=NULL; m=m->next){
if(m->handle==handle)
return TRUE;
}
/* Get the module name without directory or extension */
p=strrchr(modname, '/');
if(p!=NULL)
modname=p+1;
for(p=modname; *p!='\0'; p++){
if(!isalnum(*p) && *p!='_')
break;
}
n=ALLOC_N(char, p-modname+1);
if(n==NULL){
warn_err();
goto err1;
}
memcpy(n, modname, p-modname);
n[p-modname]='\0';
/* Allocate space for module info */
m=ALLOC(Module);
if(m==NULL){
warn_err();
goto err2;
}
m->name=n;
m->handle=handle;
m->next=NULL;
/* initialize */
if(!check_version(handle, n)){
warn_obj(modname, "Module version information not found or version "
"mismatch. Refusing to use.");
goto err3;
}
if(!call_init(handle, n))
goto err3;
LINK_ITEM(modules, m, next, prev);
return TRUE;
err3:
free(m);
err2:
free(n);
err1:
lt_dlclose(handle);
return FALSE;
}
/*EXTL_EXPORT
bool load_module(const char *name)
{
char *name2=NULL;
bool ret=FALSE;
if(strchr(name, '/')!=NULL)
return do_load_module(name);
if(strchr(name, '.')==NULL){
name2=scat(name, ".la");
if(name2==NULL){
warn_err();
return FALSE;
}
ret=load_module(name2);
free(name2);
return ret;
}
name2=find_module(name);
if(name2!=NULL){
ret=do_load_module(name2);
free(name2);
}
return ret;
}*/
/*}}}*/
/*{{{ Deinit */
static void call_deinit(lt_dlhandle handle, char *name)
{
char *p=scat(name, "_module_deinit");
void (*deinitfn)(void);
if(p==NULL){
warn_err();
return;
}
deinitfn=(void (*)())lt_dlsym(handle, p);
free(p);
if(deinitfn!=NULL)
deinitfn();
}
static void do_unload_module(Module *m)
{
call_deinit(m->handle, m->name);
lt_dlclose(m->handle);
if(m->name!=NULL)
free(m->name);
free(m);
}
void unload_modules()
{
Module *m;
while(modules!=NULL){
m=modules->prev;
UNLINK_ITEM(modules, m, next, prev);
do_unload_module(m);
}
}
/*}}}*/