python: fully delete failed plugins

This commit is contained in:
TingPing 2013-05-04 02:02:10 -03:00
parent efd21ce982
commit 46443cbd1c

View File

@ -205,6 +205,8 @@ static PyThreadState *pTempThread;
((PluginObject *)(x))->hooks = (y);
#define Plugin_SetContext(x, y) \
((PluginObject *)(x))->context = (y);
#define Plugin_SetGui(x, y) \
((PluginObject *)(x))->gui = (y);
#define HOOK_XCHAT 1
#define HOOK_UNLOAD 2
@ -1128,137 +1130,6 @@ ListItem_New(const char *listname)
} \
}
static PyObject *
Plugin_New(char *filename, PyObject *xcoobj)
{
PluginObject *plugin = NULL;
PyObject *m, *o;
#ifdef IS_PY3K
wchar_t *argv[] = { L"<hexchat>", 0 };
#else
char *argv[] = { "<hexchat>", 0 };
#endif
if (filename) {
char *old_filename = filename;
filename = Util_Expand(filename);
if (filename == NULL) {
hexchat_printf(ph, "File not found: %s", old_filename);
return NULL;
}
}
/* Allocate plugin structure. */
plugin = PyObject_New(PluginObject, &Plugin_Type);
if (plugin == NULL) {
hexchat_print(ph, "Can't create plugin object");
goto error;
}
Plugin_SetName(plugin, NULL);
Plugin_SetVersion(plugin, NULL);
Plugin_SetFilename(plugin, NULL);
Plugin_SetDescription(plugin, NULL);
Plugin_SetHooks(plugin, NULL);
Plugin_SetContext(plugin, hexchat_get_context(ph));
/* Start a new interpreter environment for this plugin. */
PyEval_AcquireThread(main_tstate);
plugin->tstate = Py_NewInterpreter();
if (plugin->tstate == NULL) {
hexchat_print(ph, "Can't create interpreter state");
goto error;
}
PySys_SetArgv(1, argv);
PySys_SetObject("__plugin__", (PyObject *) plugin);
/* Set stdout and stderr to xchatout. */
Py_INCREF(xcoobj);
PySys_SetObject("stdout", xcoobj);
Py_INCREF(xcoobj);
PySys_SetObject("stderr", xcoobj);
if (filename) {
#ifdef WIN32
char *file;
if (!g_file_get_contents_utf8(filename, &file, NULL, NULL)) {
hexchat_printf(ph, "Can't open file %s: %s\n",
filename, strerror(errno));
goto error;
}
if (PyRun_SimpleString(file) != 0) {
hexchat_printf(ph, "Error loading module %s\n",
filename);
g_free (file);
goto error;
}
plugin->filename = filename;
filename = NULL;
g_free (file);
#else
FILE *fp;
plugin->filename = filename;
/* It's now owned by the plugin. */
filename = NULL;
/* Open the plugin file. */
fp = fopen(plugin->filename, "r");
if (fp == NULL) {
hexchat_printf(ph, "Can't open file %s: %s\n",
plugin->filename, strerror(errno));
goto error;
}
/* Run the plugin. */
if (PyRun_SimpleFile(fp, plugin->filename) != 0) {
hexchat_printf(ph, "Error loading module %s\n",
plugin->filename);
fclose(fp);
goto error;
}
fclose(fp);
#endif
m = PyDict_GetItemString(PyImport_GetModuleDict(),
"__main__");
if (m == NULL) {
hexchat_print(ph, "Can't get __main__ module");
goto error;
}
GET_MODULE_DATA(name, 1);
GET_MODULE_DATA(version, 0);
GET_MODULE_DATA(description, 0);
plugin->gui = hexchat_plugingui_add(ph, plugin->filename,
plugin->name,
plugin->description,
plugin->version, NULL);
}
PyEval_ReleaseThread(plugin->tstate);
return (PyObject *) plugin;
error:
g_free(filename);
if (plugin) {
if (plugin->tstate)
{
Plugin_RemoveAllHooks((PyObject *)plugin);
/* FIXME: Handle this? */
if (plugin->tstate == PyInterpreterState_ThreadHead(plugin->tstate->interp))
Py_EndInterpreter(plugin->tstate);
}
Py_DECREF(plugin);
}
PyEval_ReleaseLock();
return NULL;
}
static PyObject *
Plugin_GetCurrent()
{
@ -1379,12 +1250,141 @@ Plugin_Delete(PyObject *plugin)
list = list->next;
}
Plugin_RemoveAllHooks(plugin);
hexchat_plugingui_remove(ph, ((PluginObject *)plugin)->gui);
if (((PluginObject *)plugin)->gui != NULL)
hexchat_plugingui_remove(ph, ((PluginObject *)plugin)->gui);
Py_DECREF(plugin);
/*PyThreadState_Swap(tstate); needed? */
Py_EndInterpreter(tstate);
}
static PyObject *
Plugin_New(char *filename, PyObject *xcoobj)
{
PluginObject *plugin = NULL;
PyObject *m, *o;
#ifdef IS_PY3K
wchar_t *argv[] = { L"<hexchat>", 0 };
#else
char *argv[] = { "<hexchat>", 0 };
#endif
if (filename) {
char *old_filename = filename;
filename = Util_Expand(filename);
if (filename == NULL) {
hexchat_printf(ph, "File not found: %s", old_filename);
return NULL;
}
}
/* Allocate plugin structure. */
plugin = PyObject_New(PluginObject, &Plugin_Type);
if (plugin == NULL) {
hexchat_print(ph, "Can't create plugin object");
goto error;
}
Plugin_SetName(plugin, NULL);
Plugin_SetVersion(plugin, NULL);
Plugin_SetFilename(plugin, NULL);
Plugin_SetDescription(plugin, NULL);
Plugin_SetHooks(plugin, NULL);
Plugin_SetContext(plugin, hexchat_get_context(ph));
Plugin_SetGui(plugin, NULL);
/* Start a new interpreter environment for this plugin. */
PyEval_AcquireThread(main_tstate);
plugin->tstate = Py_NewInterpreter();
if (plugin->tstate == NULL) {
hexchat_print(ph, "Can't create interpreter state");
goto error;
}
PySys_SetArgv(1, argv);
PySys_SetObject("__plugin__", (PyObject *) plugin);
/* Set stdout and stderr to xchatout. */
Py_INCREF(xcoobj);
PySys_SetObject("stdout", xcoobj);
Py_INCREF(xcoobj);
PySys_SetObject("stderr", xcoobj);
if (filename) {
#ifdef WIN32
char *file;
if (!g_file_get_contents_utf8(filename, &file, NULL, NULL)) {
hexchat_printf(ph, "Can't open file %s: %s\n",
filename, strerror(errno));
goto error;
}
if (PyRun_SimpleString(file) != 0) {
hexchat_printf(ph, "Error loading module %s\n",
filename);
g_free (file);
goto error;
}
plugin->filename = filename;
filename = NULL;
g_free (file);
#else
FILE *fp;
plugin->filename = filename;
/* It's now owned by the plugin. */
filename = NULL;
/* Open the plugin file. */
fp = fopen(plugin->filename, "r");
if (fp == NULL) {
hexchat_printf(ph, "Can't open file %s: %s\n",
plugin->filename, strerror(errno));
goto error;
}
/* Run the plugin. */
if (PyRun_SimpleFile(fp, plugin->filename) != 0) {
hexchat_printf(ph, "Error loading module %s\n",
plugin->filename);
fclose(fp);
goto error;
}
fclose(fp);
#endif
m = PyDict_GetItemString(PyImport_GetModuleDict(),
"__main__");
if (m == NULL) {
hexchat_print(ph, "Can't get __main__ module");
goto error;
}
GET_MODULE_DATA(name, 1);
GET_MODULE_DATA(version, 0);
GET_MODULE_DATA(description, 0);
plugin->gui = hexchat_plugingui_add(ph, plugin->filename,
plugin->name,
plugin->description,
plugin->version, NULL);
}
PyEval_ReleaseThread(plugin->tstate);
return (PyObject *) plugin;
error:
g_free(filename);
if (plugin) {
if (plugin->tstate)
Plugin_Delete((PyObject *)plugin);
else
Py_DECREF(plugin);
}
PyEval_ReleaseLock();
return NULL;
}
static void
Plugin_dealloc(PluginObject *self)
{