On 06/26/2012 10:37 AM, Jakub Filak wrote:
run event on dir uses callbacks for processing messages produced by event command process. logging_callback and post_run_callback are still in run_event_state because this callbacks are used in Python API. run event on dir uses "observer" in order to allow better logging perforemed by run event on dir callers --- src/include/run_event.h | 134 ++++++++++++++- src/lib/run_event.c | 440 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 496 insertions(+), 78 deletions(-)diff --git a/src/include/run_event.h b/src/include/run_event.h index 43730ce..32ad089 100644 --- a/src/include/run_event.h +++ b/src/include/run_event.h @@ -27,17 +27,20 @@ extern "C" { struct dump_dir; +typedef int (*res_post_run_callback)(const char *dump_dir_name, void *param); +typedef char* (*res_logging_callback)(char *log_line, void *param); + struct run_event_state { int children_count; /* Used only for post-create dup detection. TODO: document its API */ - int (*post_run_callback)(const char *dump_dir_name, void *param); + res_post_run_callback post_run_callback; void *post_run_param; /* Can take ownership of log_line, which is malloced. In this case, return NULL. * Otherwise should return log_line (it will be freed by caller) */ - char* (*logging_callback)(char *log_line, void *param); + res_logging_callback logging_callback; void *logging_param; /* Internal data for async command execution */ @@ -49,6 +52,130 @@ struct run_event_state { struct run_event_state *new_run_event_state(void); void free_run_event_state(struct run_event_state *state); +/* + * Kill child's command process if is running + * + * @param A not NULL pointer to run_event_state + */ +void run_event_state_kill_command(struct run_event_state *state); + +/* + * This structured holds a callbacks used during process of event run. + */ +struct run_event_impl +{ + /* + * Called when child command proced an alert + * + * Must not be NULL + * + * @param msg An alert message produced byt child command + * @param args An implementor args + */ + void (* alert)(const char *msg, void *args); + + /* + * Called when child ask for some input. A callee + * should return a text whithout any new line character. + * + * Must not be NULL + * + * @param msg An ask message produced by child command + * @param args An implementor args + * @return Must allways return string without new lines. + */ + char *(* ask)(const char *msg, void *args); + + /* + * Called when child wants to know yes/no decision. + * + * Must not be NULL + * + * @param msg An ask message produced by child command + * @param args An implementor args + * @return Return 0 if an answer is NO, otherwise return nonzero value. + */ + int (* ask_yes_no)(const char *msg, void *args); + + /* + * Called when child wants to know yes/no decision. + * + * Must not be NULL + * + * @param msg An ask message produced by child command + * @param password A password value, can be NULL if nobody is interested in. + * @param args An implementor args + * @return Return nonzero if a password was obtained, otherwise return 0. + */ + int (* ask_password)(const char *msg, char **password, void *args); + + /* + * Implementor's custom data. + */ + void *args; +}; + + +struct run_event_observer +{ + /* + * Push observer method called after child command starts + * + * @param pid Child's command process pid + * @param args An implementor args + */ + void (* command_started)(pid_t pid, void *args); + + /* + * Push observer method called after processing of output line from command + * + * @param msg A line without formatting defined by communication protocol + * @param raw_output Whole line read from command output + * @param response A response sent back to a command + * @param args An implementor args + */ + void (* command_msg_processed)(const char *msg, const char *raw_output, const char *response, void *args); + + /* + * Push observer method called after child command finish + * + * @param retval Child's command process return value + * @param status Child's command process status + * @param err_msg An error message generated by runtime (not OS nor child command). + * @param args An implementor args + */ + void (* command_finished)(int retval, int status, const char *err_msg, void *args); + + /* + * Implementor's custom data. + */ + void *args; +};
I think it would be simpler if all these callbacks will be in one structure. As a user, I would be confused having three structs with function ptrs.
+struct run_event_impl *new_text_run_event_impl();
(in C, func() means "function with unknown params". Use func(void) to indicate "function with no params"). Just expose standard text callbacks in *.h file and let user assign them to the function pointers.
+/* + * Initializes and returns a implementation of run event observer. + * All function calls are passed to a wrapped implementation. + * This implementation stores communication between command process and + * parent process in problem event log. + */ +struct run_event_observer *new_command_log_run_event_observer(char *dump_dir_name, const struct run_event_observer *wrapped_impl);
Why is it needed? It's easier to see the need for it if you would add the user in the same patch. -- vda
