/* Cheesy hack to work around ZendOptimizer.so unloading itself
 * with dlclose. Use at own risk :) Walter Doekes, 2009.
 * Compile: gcc -Wall -D_GNU_SOURCE -fPIC -ldl -shared -o \
 *   ZendOptimizerFix.so ZendOptimizerFix.c
 * Append: export LD_PRELOAD=/path/to/ZendOptimizerFix.so
 *   to /etc/apache2/envvars. */
#include <assert.h>
#include <dlfcn.h>
#include <string.h>

static void *zendopt = NULL;
static void *(*real_dlopen)(char const*, int) = NULL;
static int (*real_dlclose)(void*) = NULL;

__attribute__((constructor)) void init() {
	real_dlopen = dlsym(RTLD_NEXT, "dlopen");
	real_dlclose = dlsym(RTLD_NEXT, "dlclose");
}

void *dlopen(char const *filename, int flag) {
	if (real_dlopen) {
		void *handle = real_dlopen(filename, flag);
		if (handle != NULL && strstr(filename, "ZendOptimizer.so")
				!= NULL) {
			assert(zendopt == NULL || zendopt == handle);
			zendopt = handle;
		}
		return handle;
	}
	return 0;
}

int dlclose(void *handle) {
	if (real_dlclose) {
		if (handle == zendopt) {
			/* Don't unload on the first call */
			zendopt = NULL;
			return 0;
		} else {
			return real_dlclose(handle);
		}
	}
	return -1;
}
/* http://forums.zend.com/viewtopic.php?f=57&t=1242 */
