aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jan Kanis <jan.code@jankanis.nl>2012-12-19 15:56:19 +0100
committerGravatar Jan Kanis <jan.code@jankanis.nl>2012-12-20 16:11:46 +0100
commit1f0ae8b06d7e10d2a12cfd28efb3032af7b4d2f1 (patch)
tree2bfdc97c97b9c10ea62060a4ca2430fe84c5767a
parentaa477195d44b156cafaae098776ecddedfb9911e (diff)
fixed #449, added test
-rw-r--r--event.cpp78
-rw-r--r--tests/test9.err0
-rw-r--r--tests/test9.in25
-rw-r--r--tests/test9.out2
-rw-r--r--tests/test9.status1
5 files changed, 70 insertions, 36 deletions
diff --git a/event.cpp b/event.cpp
index 7f996eee..e4f452e0 100644
--- a/event.cpp
+++ b/event.cpp
@@ -25,8 +25,6 @@
#include "event.h"
#include "signal.h"
-FILE *checkfile;
-FILE *tracefile;
/**
Number of signals that can be queued before an overflow occurs
@@ -134,7 +132,7 @@ static int event_match(const event_t *classv, const event_t *instance)
/**
This should never be reached
*/
- debug(1, "Warning: Unreachable code reached in event_match in event.cpp\n");
+ debug(0, "Warning: Unreachable code reached in event_match in event.cpp\n");
return 0;
}
@@ -244,47 +242,63 @@ static void show_all_handlers(void)
static wcstring event_type_str(const event_t *event) {
wcstring res;
- char const *temp;
+ wchar_t const *temp;
int sig;
switch(event->type) {
case EVENT_ANY:
- res += L"EVENT_ANY";
+ res = L"EVENT_ANY";
break;
case EVENT_VARIABLE:
if(event->str_param1.c_str()) {
- res += format_string(L"EVENT_VARIABLE($%ls)", event->str_param1.c_str());
+ res = format_string(L"EVENT_VARIABLE($%ls)", event->str_param1.c_str());
} else {
- res += L"EVENT_VARIABLE([any])";
+ res = L"EVENT_VARIABLE([any])";
}
break;
case EVENT_SIGNAL:
sig = event->param1.signal;
if(sig == EVENT_ANY_SIGNAL) {
- temp = "[all signals]";
+ temp = L"[all signals]";
} else if(sig == 0) {
- temp = "not set";
+ temp = L"not set";
} else {
- temp = strsignal(sig);
+ temp = sig2wcs(sig);
}
- res += format_string(L"EVENT_SIGNAL(%d: %s)", sig, temp);
+ res = format_string(L"EVENT_SIGNAL(%ls)", temp);
break;
case EVENT_EXIT:
if(event->param1.pid == EVENT_ANY_PID) {
- res += L"EVENT_EXIT([all child processes])";
+ res = wcstring(L"EVENT_EXIT([all child processes])");
+ } else if (event->param1.pid > 0) {
+ res = format_string(L"EVENT_EXIT(pid %d)", event->param1.pid);
} else {
- res += format_string(L"EVENT_EXIT(pid %d)", event->param1.pid);
+ job_t *j = job_get_from_pid(-event->param1.pid);
+ if (j)
+ res = format_string(L"EVENT_EXIT(jobid %d: \"%ls\")", j->job_id, j->command_wcstr());
+ else
+ res = format_string(L"EVENT_EXIT(pgid %d)", -event->param1.pid);
}
break;
case EVENT_JOB_ID:
- res += format_string(L"EVENT_JOB_ID(%d)", event->param1.job_id);
+ {
+ job_t *j = job_get(event->param1.job_id);
+ if (j)
+ res = format_string(L"EVENT_JOB_ID(job %d: \"%ls\")", j->job_id, j->command_wcstr());
+ else
+ res = format_string(L"EVENT_JOB_ID(jobid %d)", event->param1.job_id);
break;
+ }
case EVENT_GENERIC:
- res += format_string(L"EVENT_GENERIC(%ls)", event->str_param1.c_str());
+ res = format_string(L"EVENT_GENERIC(%ls)", event->str_param1.c_str());
break;
default:
- res += format_string(L"unknown/illegal event(%x)", event->type);
+ res = format_string(L"unknown/illegal event(%x)", event->type);
+ }
+ if(event->function_name.size()) {
+ return format_string(L"%ls: \"%ls\"", res.c_str(), event->function_name.c_str());
+ } else {
+ return res;
}
- return format_string(L"%ls: \"%ls\"", res.c_str(), event->function_name.c_str());
}
@@ -293,7 +307,8 @@ void event_add_handler(const event_t *event)
event_t *e;
CHECK(event,);
- fprintf(tracefile, "register: %ls\n", event_type_str(event).c_str());
+ if(debug_level >= 3)
+ debug(3, "register: %ls\n", event_type_str(event).c_str());
e = event_copy(event, 0);
@@ -315,7 +330,8 @@ void event_remove(event_t *criterion)
event_list_t new_list;
CHECK(criterion,);
- fprintf(tracefile, "unregister: %ls\n", event_type_str(criterion).c_str());
+ if(debug_level >= 3)
+ debug(3, "unregister: %ls\n", event_type_str(criterion).c_str());
/*
Because of concurrency issues (env_remove could remove an event
@@ -422,13 +438,6 @@ static int event_is_killed(event_t *e)
return std::find(killme.begin(), killme.end(), e) != killme.end();
}
-void event_print_all(FILE *f, const wcstring& header, const std::vector<event_t *> &events) {
- fprintf(f, "%ls", header.c_str());
- for(uint i=0; i<events.size(); i++) {
- fprintf(f, " %u: %ls\n", i, event_type_str(events.at(i)).c_str());
- }
-}
-
/**
Perform the specified event. Since almost all event firings will
not be matched by even a single event handler, we make sure to
@@ -442,9 +451,11 @@ static void event_fire_internal(const event_t *event)
event_list_t fire;
/*
- First we free all events that have been removed
+ First we free all events that have been removed, but only if this
+ invocation of event_fire_internal is not a recursive call.
*/
- event_free_kills();
+ if(is_event <= 1)
+ event_free_kills();
if (events.empty())
return;
@@ -475,9 +486,6 @@ static void event_fire_internal(const event_t *event)
if (fire.empty())
return;
- event_print_all(tracefile, format_string(L"firing matches for %ls\n", event_type_str(event).c_str()), fire);
-
-
/*
Iterate over our list of matching events
*/
@@ -508,7 +516,7 @@ static void event_fire_internal(const event_t *event)
}
}
- debug( 1, L"Event handler fires command '%ls'", buffer.c_str() );
+ // debug( 1, L"Event handler fires command '%ls'", buffer.c_str() );
/*
Event handlers are not part of the main flow of code, so
@@ -529,7 +537,8 @@ static void event_fire_internal(const event_t *event)
/*
Free killed events
*/
- event_free_kills();
+ if(is_event <= 1)
+ event_free_kills();
}
@@ -662,9 +671,6 @@ void event_fire(event_t *event)
void event_init()
{
- tracefile = fdopen(4, "w");
- checkfile = fopen("/dev/null", "w");
- setbuf(tracefile, NULL);
}
void event_destroy()
diff --git a/tests/test9.err b/tests/test9.err
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/test9.err
diff --git a/tests/test9.in b/tests/test9.in
new file mode 100644
index 00000000..688dfb3f
--- /dev/null
+++ b/tests/test9.in
@@ -0,0 +1,25 @@
+# Test events.
+
+# This pattern caused a crash; github issue #449
+
+set -g var before
+
+function test1 --on-event test
+ set -g var $var:test1
+ functions -e test2
+end
+
+function test2 --on-event test
+ # this should not run, as test2 gets removed before it has a chance of running
+ set -g var $var:test2a
+end
+emit test
+
+echo $var
+
+
+function test3 --on-event test3
+ echo received event test3 with args: $argv
+end
+
+emit test3 foo bar
diff --git a/tests/test9.out b/tests/test9.out
new file mode 100644
index 00000000..863e82f5
--- /dev/null
+++ b/tests/test9.out
@@ -0,0 +1,2 @@
+before:test1
+received event test3 with args:
diff --git a/tests/test9.status b/tests/test9.status
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/tests/test9.status
@@ -0,0 +1 @@
+0