Skip to content

Commit

Permalink
FIXME removal: cleaned up GUI plugin loading and dlopen() abstraction.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Dec 9, 2006
1 parent 09dfd3b commit dbfaa21
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 48 deletions.
3 changes: 3 additions & 0 deletions fileio.c
@@ -1,3 +1,6 @@
#include <sys/stat.h> // !!! FIXME: unix dependency for stat().
#include <limits.h> // !!! FIXME: unix dependency for realpath().

#include "fileio.h"
#include "platform.h"

Expand Down
57 changes: 18 additions & 39 deletions gui.c
Expand Up @@ -8,7 +8,6 @@

typedef struct S_PLUGINLIST
{
char *filename;
void *lib;
const MojoGui *gui;
MojoGuiPluginPriority priority;
Expand Down Expand Up @@ -83,16 +82,12 @@ static void deleteGuiPlugin(PluginList *plugin)
plugin->gui->deinit();
if (plugin->lib)
MojoPlatform_dlclose(plugin->lib);
if (plugin->filename)
MojoPlatform_unlink(plugin->filename);
free(plugin->filename);
free(plugin);
} // if
} // deleteGuiPlugin


static boolean tryGuiPlugin(PluginList *plugins, const char *fname,
MojoGuiEntryPoint entry)
static boolean tryGuiPlugin(PluginList *plugins, MojoGuiEntryPoint entry)
{
boolean retval = false;
const MojoGui *gui = entry(MOJOGUI_INTERFACE_REVISION, &GEntryPoints);
Expand All @@ -102,7 +97,6 @@ static boolean tryGuiPlugin(PluginList *plugins, const char *fname,
plug->lib = NULL;
plug->gui = gui;
plug->priority = calcGuiPriority(gui);
plug->filename = ((fname != NULL) ? xstrdup(fname) : NULL);
plug->next = plugins->next;
plugins->next = plug;
retval = true;
Expand All @@ -116,52 +110,37 @@ static void loadStaticGuiPlugins(PluginList *plugins)
{
int i;
for (i = 0; staticGui[i] != NULL; i++)
tryGuiPlugin(plugins, NULL, staticGui[i]);
tryGuiPlugin(plugins, staticGui[i]);
} // loadStaticGuiPlugins


static boolean loadDynamicGuiPlugin(PluginList *plugins, MojoArchive *ar)
{
char fname[128] = { 0 };
boolean rc = false;
void *lib = NULL;
boolean rc;
MojoInput *io = ar->openCurrentEntry(ar);
if (io == NULL)
return false;

STUBBED("Don't copy if it's a physical file already?");

STUBBED("Filename creation has to change");
if (io != NULL)
{
struct timeval tv;
gettimeofday(&tv, NULL);
snprintf(fname, sizeof (fname), "/tmp/mojosetup-gui-%ld.so", tv.tv_sec);
}

rc = mojoInputToPhysicalFile(io, fname);
io->close(io);
const uint32 imglen = (uint32) io->length(io);
uint8 *img = (uint8 *) xmalloc(imglen);
const uint32 br = io->read(io, img, imglen);
io->close(io);
if (br == imglen)
lib = MojoPlatform_dlopen(img, imglen);
free(img);
} // if

if (rc)
if (lib != NULL)
{
rc = false;
lib = MojoPlatform_dlopen(fname);
if (lib != NULL)
void *addr = MojoPlatform_dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
{
void *addr = MojoPlatform_dlsym(lib, MOJOGUI_ENTRY_POINT_STR);
MojoGuiEntryPoint entry = (MojoGuiEntryPoint) addr;
if (entry != NULL)
rc = tryGuiPlugin(plugins, fname, entry);
if ((rc = tryGuiPlugin(plugins, entry)) == false)
MojoPlatform_dlclose(lib);
} // if
} // if

if (!rc)
{
if (lib != NULL)
MojoPlatform_dlclose(lib);
if (fname[0])
MojoPlatform_unlink(fname);
} // if

return rc;
} // loadDynamicGuiPlugin

Expand Down
11 changes: 8 additions & 3 deletions platform.h
Expand Up @@ -26,8 +26,13 @@ void MojoPlatform_die(void);
// on failure.
boolean MojoPlatform_unlink(const char *fname);

// Wrappers for Unix dlopen/dlsym/dlclose ...
void *MojoPlatform_dlopen(const char *fname);
// Wrappers for Unix dlopen/dlsym/dlclose, sort of. Instead of a filename,
// these take a memory buffer for the library. If you can't load this
// directly in RAM, the platform should write it to a temporary file first,
// and deal with cleanup in MojoPlatform_dlclose(). The memory buffer must be
// dereferenced in MojoPlatform_dlopen(), as the caller may free() it upon
// return. Everything else works like the usual Unix calls.
void *MojoPlatform_dlopen(const uint8 *img, size_t len);
void *MojoPlatform_dlsym(void *lib, const char *sym);
void MojoPlatform_dlclose(void *lib);

Expand All @@ -48,7 +53,7 @@ boolean MojoPlatform_osVersion(char *buf, size_t len);
#elif PLATFORM_UNIX
#define PLATFORM_NAME "unix"
#else
#error Unknown processor architecture.
#error Unknown platform.
#endif

// Basic architecture detection.
Expand Down
70 changes: 64 additions & 6 deletions platform/unix.c
Expand Up @@ -4,12 +4,12 @@
#undef false
#endif

#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <time.h>
#include <unistd.h>
#include <dlfcn.h>

#include "../platform.h"
Expand Down Expand Up @@ -206,12 +206,70 @@ boolean MojoPlatform_unlink(const char *fname)
#define USE_LEGACY_MACOSX_DLOPEN 1
#endif

void *MojoPlatform_dlopen(const char *fname)
static boolean testTmpDir(const char *dname, char *buf,
size_t len, const char *tmpl)
{
#if USE_LEGACY_MACOSX_DLOPEN
#error !!! FIXME Write me.
boolean retval = false;
if ( (dname != NULL) && (access(dname, R_OK | W_OK | X_OK) == 0) )
{
struct stat statbuf;
if ( (stat(dname, &statbuf) == 0) && (S_ISDIR(statbuf.st_mode)) )
{
const size_t rc = snprintf(buf, len, "%s/%s", dname, tmpl);
if (rc < len)
retval = true;
} // if
} // if

return retval;
} // testTmpDir


static inline boolean chooseTempFile(char *fname, size_t len, const char *tmpl)
{
#ifndef P_tmpdir // glibc defines this, maybe others.
#define P_tmpdir NULL
#endif
return dlopen(fname, RTLD_NOW | RTLD_GLOBAL);

if (!testTmpDir(getenv("TMPDIR"), fname, len, tmpl))
{
if (!testTmpDir(P_tmpdir, fname, len, tmpl))
{
if (!testTmpDir("/tmp", fname, len, tmpl))
return false;
} // if
} // if

return true;
} // chooseTempFile


void *MojoPlatform_dlopen(const uint8 *img, size_t len)
{
// Write the image to a temporary file, dlopen() it, and delete it
// immediately. The inode will be kept around by the Unix kernel until
// we either dlclose() it or the process terminates, but we don't have
// to worry about polluting the /tmp directory or cleaning this up later.

void *retval = NULL;
char fname[PATH_MAX];
if (chooseTempFile(fname, sizeof (fname), "mojosetup-gui-plugin-XXXXXX"))
{
const int fd = mkstemp(fname);
if (fd != -1)
{
const size_t bw = write(fd, img, len);
const int rc = close(fd);
#if USE_LEGACY_MACOSX_DLOPEN
#error !!! FIXME Write me.
#endif
if ((bw == len) && (rc != -1))
retval = dlopen(fname, RTLD_NOW | RTLD_GLOBAL);
unlink(fname);
} // if
} // if

return retval;
} // MojoPlatform_dlopen


Expand Down

0 comments on commit dbfaa21

Please sign in to comment.