1
0
mirror of https://github.com/irssi/irssi.git synced 2024-10-06 04:53:38 -04:00

Merge pull request #1206 from aquanight/selfunload-fix

Fix crash from self-unloading script
This commit is contained in:
ailin-nemui 2020-07-14 03:14:47 +02:00 committed by GitHub
commit e55f1f5cea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 8 deletions

View File

@ -6,7 +6,7 @@
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
#define IRSSI_ABI_VERSION 30
#define IRSSI_ABI_VERSION 31
#define DEFAULT_SERVER_ADD_PORT 6667
#define DEFAULT_SERVER_ADD_TLS_PORT 6697

View File

@ -65,10 +65,6 @@ static void perl_script_destroy_package(PERL_SCRIPT_REC *script)
static void perl_script_destroy(PERL_SCRIPT_REC *script)
{
perl_scripts = g_slist_remove(perl_scripts, script);
perl_signal_remove_script(script);
perl_source_remove_script(script);
signal_emit("script destroyed", 1, script);
@ -277,6 +273,7 @@ static PERL_SCRIPT_REC *script_load(char *name, const char *path,
script->package = g_strdup_printf("Irssi::Script::%s", name);
script->path = g_strdup(path);
script->data = g_strdup(data);
script->refcount = 1;
perl_scripts = g_slist_append(perl_scripts, script);
signal_emit("script created", 1, script);
@ -311,9 +308,36 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data)
/* Unload perl script */
void perl_script_unload(PERL_SCRIPT_REC *script)
{
GSList *link;
g_return_if_fail(script != NULL);
perl_script_destroy_package(script);
perl_signal_remove_script(script);
perl_source_remove_script(script);
link = g_slist_find(perl_scripts, script);
if (link != NULL) {
perl_scripts = g_slist_remove_link(perl_scripts, link);
g_slist_free(link);
perl_script_unref(script);
}
}
/* Enter a perl script (signal or input source) */
void perl_script_ref(PERL_SCRIPT_REC *script)
{
g_return_if_fail(script != NULL);
script->refcount++;
}
void perl_script_unref(PERL_SCRIPT_REC *script)
{
g_return_if_fail(script != NULL);
script->refcount--;
if (!script->refcount)
perl_script_destroy(script);
}

View File

@ -8,6 +8,7 @@ typedef struct {
/* Script can be loaded from a file, or from some data in memory */
char *path; /* FILE: full path for file */
char *data; /* DATA: data used for the script */
int refcount; /* 0 = destroy */
} PERL_SCRIPT_REC;
extern GSList *perl_scripts;
@ -26,6 +27,11 @@ PERL_SCRIPT_REC *perl_script_load_data(const char *data);
/* Unload perl script */
void perl_script_unload(PERL_SCRIPT_REC *script);
/* Mark a script as entered */
void perl_script_ref(PERL_SCRIPT_REC *script);
/* Mark a script as exited */
void perl_script_unref(PERL_SCRIPT_REC *script);
/* Find loaded script by name */
PERL_SCRIPT_REC *perl_script_find(const char *name);
/* Find loaded script by package */

View File

@ -414,13 +414,17 @@ static void sig_func(const void *p1, const void *p2,
const void *p5, const void *p6)
{
PERL_SIGNAL_REC *rec;
PERL_SCRIPT_REC *script;
const void *args[SIGNAL_MAX_ARGUMENTS];
args[0] = p1; args[1] = p2; args[2] = p3;
args[3] = p4; args[4] = p5; args[5] = p6;
rec = signal_get_user_data();
perl_call_signal(rec->script, rec->func, signal_get_emitted_id(), args);
script = rec->script;
perl_script_ref(script);
perl_call_signal(script, rec->func, signal_get_emitted_id(), args);
perl_script_unref(script);
}
static void perl_signal_add_full_int(const char *signal, SV *func,

View File

@ -78,6 +78,7 @@ static int perl_source_event(PERL_SOURCE_REC *rec)
PUTBACK;
perl_source_ref(rec);
perl_script_ref(rec->script);
perl_call_sv(rec->func, G_EVAL|G_DISCARD);
if (SvTRUE(ERRSV)) {
@ -86,6 +87,8 @@ static int perl_source_event(PERL_SOURCE_REC *rec)
g_free(error);
}
perl_script_unref(rec->script);
if (perl_source_unref(rec) && rec->once)
perl_source_destroy(rec);