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);
         }
     }
 
