View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000534 | LDMud 3.3 | Runtime | public | 2008-03-05 09:38 | 2018-01-29 21:57 |
Reporter | Gnomi | Assigned To | Gnomi | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | i686 | OS | Debian GNU/Linux | OS Version | 3.1 |
Product Version | 3.3.713 | ||||
Fixed in Version | 3.3.717 | ||||
Summary | 0000534: set_noecho calls the driver hooks with external==TRUE | ||||
Description | set_noecho calls the driver hooks with secure_callback_lambda, which is meant for reactions to external events. But set_noecho is sometimes also called from within an LPC program (with input_to or remove_input_to). So if that's the case and there is an error within the driver hook the eval_cost will get cleared (due to external==TRUE) and the calling program gets all its eval ticks back. But if there is a catch(), the eval count can even get below zero, which effectively aborts this thread (no catch holds, no error handling can happen). Greetings, Gnomi. | ||||
Tags | No tags attached. | ||||
Attached Files | external_noecho.diff (8,231 bytes)
Index: trunk/src/comm.c =================================================================== --- trunk/src/comm.c (Revision 2382) +++ trunk/src/comm.c (Arbeitskopie) @@ -4055,7 +4055,7 @@ /*-------------------------------------------------------------------------*/ void -set_noecho (interactive_t *ip, char noecho, Bool local_change) +set_noecho (interactive_t *ip, char noecho, Bool local_change, Bool external) /* Change the input mode <i>->noecho to the given <noecho>, performing all * necessary telnet negotiations. If the driverhook H_NOECHO is set, @@ -4105,7 +4105,7 @@ push_ref_valid_object(inter_sp, ob, "set_no_echo"); push_number(inter_sp, local_change ? 1 : 0); if (driver_hook[H_NOECHO].type == T_STRING) - secure_apply(driver_hook[H_NOECHO].u.str, ob, 3); + secure_apply_ob(driver_hook[H_NOECHO].u.str, ob, 3, external); else { if (driver_hook[H_NOECHO].x.closure_type == CLOSURE_LAMBDA) @@ -4115,7 +4115,7 @@ driver_hook[H_NOECHO].u.lambda->ob = ref_object(ob, "set_noecho"); } - secure_callback_lambda(&driver_hook[H_NOECHO], 3); + secure_call_lambda(&driver_hook[H_NOECHO], 3, external); } if (~confirm & old & CHARMODE_MASK) { @@ -4346,7 +4346,8 @@ { /* Sorry, the object has selfdestructed ! */ set_noecho(i, it->next ? it->next->noecho : 0 - , it->next ? it->next->local : MY_FALSE); + , it->next ? it->next->local : MY_FALSE + , MY_TRUE); i->input_to = it->next; free_input_to(it); return MY_FALSE; @@ -4356,7 +4357,8 @@ && load_ob_from_swap(ob) < 0) { set_noecho(i, it->next ? it->next->noecho : 0 - , it->next ? it->next->local : MY_FALSE); + , it->next ? it->next->local : MY_FALSE + , MY_TRUE); i->input_to = it->next; free_input_to(it); errorf("Out of memory: unswap object '%s'.\n", get_txt(ob->name)); @@ -4413,7 +4415,8 @@ if (i->noecho & NOECHO_STALE) { set_noecho(i, i->input_to ? i->input_to->noecho : 0 - , i->input_to ? i->input_to->local : MY_FALSE); + , i->input_to ? i->input_to->local : MY_FALSE + , MY_TRUE); } /* Done */ @@ -4469,7 +4472,7 @@ ip->set_input_to = MY_TRUE; if (noecho || ip->noecho) - set_noecho(ip, noecho, local_change); + set_noecho(ip, noecho, local_change, MY_FALSE); return MY_TRUE; } /* set_call() */ @@ -6523,7 +6526,8 @@ { set_noecho(all_players[i] , it->next ? it->next->noecho : 0 - , it->next ? it->next->local : MY_FALSE); + , it->next ? it->next->local : MY_FALSE + , MY_TRUE); all_players[i]->input_to = it->next; } else @@ -8092,6 +8096,7 @@ ip->noecho |= NOECHO_STALE; set_noecho(ip, ip->input_to ? ip->input_to->noecho : ip->noecho , ip->input_to ? ip->input_to->local : MY_FALSE + , MY_FALSE ); } Index: trunk/src/comm.h =================================================================== --- trunk/src/comm.h (Revision 2382) +++ trunk/src/comm.h (Arbeitskopie) @@ -410,7 +410,7 @@ extern void flush_all_player_mess(void); extern Bool get_message(char *buff); extern void remove_interactive(object_t *ob, Bool force); -extern void set_noecho(interactive_t *i, char noecho, Bool local_change); +extern void set_noecho(interactive_t *i, char noecho, Bool local_change, Bool external); extern int find_no_bang (interactive_t *ip); extern Bool call_function_interactive(interactive_t *i, char *str); extern void remove_all_players(void); Index: trunk/src/interpret.c =================================================================== --- trunk/src/interpret.c (Revision 2382) +++ trunk/src/interpret.c (Arbeitskopie) @@ -17251,22 +17251,31 @@ /*-------------------------------------------------------------------------*/ svalue_t * -secure_apply (string_t *fun, object_t *ob, int num_arg) +secure_apply_ob (string_t *fun, object_t *ob, int num_arg, Bool external) -/* Call function <fun> in <ob>ject with <num_arg> arguments pushed +/* Aliases: + * secure_apply(fun, ob, num_arg) == secure_apply_ob(fun, ob, num_arg, FALSE) + * secure_callback(fun, ob, num_arg) == secure_apply_ob(fun, ob, num_arg, TRUE) + * + * Call function <fun> in <ob>ject with <num_arg> arguments pushed * onto the stack (<inter_sp> points to the last one). static and protected * functions can't be called from the outside. - * secure_apply() takes care of calling shadows where necessary. + * secure_apply_ob() takes care of calling shadows where necessary. * - * secure_apply() returns a pointer to the function result when the call was - * successfull, or NULL on failure. The arguments are popped in any case. + * If <external> is TRUE, it means that this call is due to some external + * event (like an ERQ message) instead of being caused by a running program. + * The effect of this flag is that the error handling is like for a normal + * function call (clearing the eval costs before calling runtime_error()). + * + * secure_apply_ob() returns a pointer to the function result when the call + * was successfull, or NULL on failure. The arguments are popped in any case. * The result pointer, if returned, points to a static area which will be - * overwritten with the next secure_apply(). + * overwritten with the next secure_apply_ob(). * * The function call will swap in the object and also unset its reset status. * * Errors during the execution are caught (this is the big difference - * to sapply()/apply()) and cause secure_apply() to return NULL. + * to sapply()/apply()) and cause secure_apply_ob() to return NULL. */ { @@ -17285,7 +17294,7 @@ save_csp = csp; if (setjmp(error_recovery_info.con.text)) { - secure_apply_error(save_sp - num_arg, save_csp, MY_FALSE); + secure_apply_error(save_sp - num_arg, save_csp, external); result = NULL; } else @@ -17294,7 +17303,7 @@ } rt_context = error_recovery_info.rt.last; return result; -} /* secure_apply() */ +} /* secure_apply_ob() */ /*-------------------------------------------------------------------------*/ svalue_t * Index: trunk/src/interpret.h =================================================================== --- trunk/src/interpret.h (Revision 2382) +++ trunk/src/interpret.h (Arbeitskopie) @@ -173,8 +173,11 @@ extern string_t *dump_trace(Bool how, vector_t **rvec); extern int get_line_number_if_any(string_t **name); extern void reset_machine(Bool first); -extern svalue_t *secure_apply(string_t *fun, object_t *ob, int num_arg); extern void secure_apply_error(svalue_t *save_sp, struct control_stack *save_csp, Bool clear_costs); +extern svalue_t *secure_apply_ob(string_t *fun, object_t *ob, int num_arg, Bool external); +#define secure_apply(fun, ob, num_arg) secure_apply_ob(fun, ob, num_arg, MY_FALSE) +#define secure_callback(fun, ob, num_arg) secure_apply_ob(fun, ob, num_arg, MY_TRUE) + extern svalue_t *apply_master_ob(string_t *fun, int num_arg, Bool external); #define apply_master(fun, num_arg) apply_master_ob(fun, num_arg, MY_FALSE) #define callback_master(fun, num_arg) apply_master_ob(fun, num_arg, MY_TRUE) Index: trunk/src/simulate.c =================================================================== --- trunk/src/simulate.c (Revision 2382) +++ trunk/src/simulate.c (Arbeitskopie) @@ -1154,7 +1154,7 @@ if (O_SET_INTERACTIVE(i, current_interactive) && i->noecho & NOECHO_STALE) { - set_noecho(i, 0, MY_FALSE); + set_noecho(i, 0, MY_FALSE, MY_FALSE); } } | ||||
|
I added a patch that adds an external flag to set_noecho and also to secure_apply (renaming it to secure_apply_ob and making an alias secure_apply without that parameter), so that the later is consistent to apply_master(_ob). |
|
Committed as r2391. |
Date Modified | Username | Field | Change |
---|---|---|---|
2008-03-05 09:38 | Gnomi | New Issue | |
2008-06-30 03:03 | Gnomi | Status | new => assigned |
2008-06-30 03:03 | Gnomi | Assigned To | => Gnomi |
2008-07-02 02:42 | Gnomi | Relationship added | related to 0000476 |
2008-07-11 02:21 | Gnomi | Status | assigned => confirmed |
2008-07-11 03:21 | Gnomi | File Added: external_noecho.diff | |
2008-07-11 03:23 | Gnomi | Note Added: 0000723 | |
2008-07-17 01:01 | Gnomi | Status | confirmed => resolved |
2008-07-17 01:01 | Gnomi | Fixed in Version | => 3.3.717 |
2008-07-17 01:01 | Gnomi | Resolution | open => fixed |
2008-07-17 01:01 | Gnomi | Note Added: 0000741 | |
2009-04-14 12:14 | zesstra | Project | LDMud => LDMud 3.3 |
2010-11-16 09:42 | Gnomi | Source_changeset_attached | => ldmud.git master 3c532cb8 |
2018-01-29 18:59 | Gnomi | Source_changeset_attached | => ldmud.git master 3c532cb8 |
2018-01-29 21:57 | Gnomi | Source_changeset_attached | => ldmud.git master 3c532cb8 |