Index: trunk/test/t-0000683.c
===================================================================
--- trunk/test/t-0000683.c	(Revision 0)
+++ trunk/test/t-0000683.c	(Revision 0)
@@ -0,0 +1,67 @@
+#include "/inc/base.inc"
+
+#include "/sys/configuration.h"
+
+/* These functions are for the clone (the player object). */
+int sleeping;
+
+void start_client()
+{
+    net_connect("127.0.0.1", query_mud_port());
+    sleeping = 1;
+}
+
+int logon(int flag)
+{
+    set_prompt("");
+    if(!sleeping)
+    {
+        object me;
+
+        configure_interactive(this_object(), IC_MAX_WRITE_BUFFER_SIZE, 0);
+        set_buffer_size(0);
+
+        /* 100 MB should be enough. */
+        foreach(int i: 10240)
+            write("*"*10240+"\n");
+
+        me = clone_object(this_object());
+        exec(me, this_object());
+        write("Done.\n");
+    }
+
+    return 1;
+}
+
+/* Here comes the master. */
+
+object connect()
+{
+    set_prompt("");
+    return clone_object(this_object());
+}
+
+void run_test()
+{
+    msg("\nRunning test for #0000683:\n"
+          "--------------------------\n");
+
+    /* Waiting until LDMud is ready for users. */
+    call_out("run_test2", 0);
+}
+
+void run_test2()
+{
+    object dummy;
+
+    call_out(#'shutdown, __ALARM_TIME__ * 2, 0);
+
+    dummy = clone_object(this_object());
+    dummy->start_client();
+}
+
+string *epilog(int eflag)
+{
+    run_test();
+    return 0;
+}
Index: trunk/test/inc/base.inc
===================================================================
--- trunk/test/inc/base.inc	(Revision 2764)
+++ trunk/test/inc/base.inc	(Arbeitskopie)
@@ -38,6 +38,13 @@
 }
 #endif
 
+#ifndef OWN_VALID_EXEC
+mixed valid_exec(string prog, object ob, object obfrom)
+{
+    return 1;
+}
+#endif
+
 #ifndef OWN_PREPARE_DESTRUCT
 mixed prepare_destruct (object obj)
 {
Index: trunk/src/comm.c
===================================================================
--- trunk/src/comm.c	(Revision 2764)
+++ trunk/src/comm.c	(Arbeitskopie)
@@ -428,7 +428,7 @@
   /* The backend::current_time when urgent_data was set last.
    */
 
-static object_t *first_player_for_flush = NULL;
+static interactive_t *first_player_for_flush = NULL;
   /* First interactive user object to flush. Marks the head
    * of the list formed by interactive.{next,previous}_player_for_flush
    */
@@ -786,10 +786,10 @@
       putc('\n', stderr);
     fprintf(stderr, "  .message_length:    %d (%p)\n", ip->message_length, ip->message_buf+ip->message_length);
     fprintf(stderr, "  .next_for_flush:    %p", ip->next_player_for_flush);
-      if (ip->next_player_for_flush) fprintf(stderr, " (%s)", get_txt(ip->next_player_for_flush->name));
+      if (ip->next_player_for_flush) fprintf(stderr, " (%s)", get_txt(ip->next_player_for_flush->ob->name));
       putc('\n', stderr);
     fprintf(stderr, "  .prev_for_flush:    %p", ip->previous_player_for_flush);
-      if (ip->previous_player_for_flush) fprintf(stderr, " (%s)", get_txt(ip->previous_player_for_flush->name));
+      if (ip->previous_player_for_flush) fprintf(stderr, " (%s)", get_txt(ip->previous_player_for_flush->ob->name));
       putc('\n', stderr);
     fprintf(stderr, "  .access_class:      %ld\n", ip->access_class);
     fprintf(stderr, "  .charset:          ");
@@ -2075,16 +2075,15 @@
  */
 
 {
-    if ( ip->previous_player_for_flush || first_player_for_flush == ip->ob)
+    if ( ip->previous_player_for_flush || first_player_for_flush == ip)
         return;
 
     if ( NULL != (ip->next_player_for_flush = first_player_for_flush) )
     {
-        O_GET_INTERACTIVE(first_player_for_flush)->
-          previous_player_for_flush = ip->ob;
+        first_player_for_flush->previous_player_for_flush = ip;
     }
     ip->previous_player_for_flush = NULL;
-    first_player_for_flush = ip->ob;
+    first_player_for_flush = ip;
 } /* add_flush_entry() */
 
 /*-------------------------------------------------------------------------*/
@@ -2106,17 +2105,17 @@
 
     if ( ip->previous_player_for_flush )
     {
-        O_GET_INTERACTIVE(ip->previous_player_for_flush)->next_player_for_flush
+        ip->previous_player_for_flush->next_player_for_flush
           = ip->next_player_for_flush;
     }
-    else if (first_player_for_flush == ip->ob)
+    else if (first_player_for_flush == ip)
     {
         first_player_for_flush = ip->next_player_for_flush;
     }
 
     if ( ip->next_player_for_flush )
     {
-        O_GET_INTERACTIVE(ip->next_player_for_flush)->previous_player_for_flush
+        ip->next_player_for_flush->previous_player_for_flush
           = ip->previous_player_for_flush;
     }
 
@@ -2134,16 +2133,14 @@
  */
 
 {
-    object_t *p, *np;
-    interactive_t *ip;
+    interactive_t *ip, *nip;
     object_t *save = command_giver;
 
-    for ( p = first_player_for_flush; p != NULL; p = np)
+    for ( ip = first_player_for_flush; ip != NULL; ip = nip)
     {
-        ip = O_GET_INTERACTIVE(p);
-        np = ip->next_player_for_flush;
-          /* add_message() will clobber (p)->next_player_for_flush! */
-        command_giver = p;
+        nip = ip->next_player_for_flush;
+          /* add_message() will clobber (ip)->next_player_for_flush! */
+        command_giver = ip->ob;
         add_message(message_flush);
 
         if(ip->msg_discarded == DM_SEND_INFO)
@@ -3348,6 +3345,8 @@
         static unsigned char erq_welcome[] = { IAC, TELOPT_BINARY };
 
         add_message(message_flush);
+        remove_flush_entry(interactive); /* To be sure */
+
         erq_demon = interactive->socket;
         erq_proto_demon = -1;
         socket_write(erq_demon, erq_welcome, sizeof erq_welcome);
Index: trunk/src/comm.h
===================================================================
--- trunk/src/comm.h	(Revision 2764)
+++ trunk/src/comm.h	(Arbeitskopie)
@@ -236,8 +236,8 @@
                                    as name prefix. NULL traces everything. */
     int message_length;         /* Current length of message in message_buf[] */
 
-    object_t *next_player_for_flush;
-    object_t *previous_player_for_flush;
+    interactive_t *next_player_for_flush;
+    interactive_t *previous_player_for_flush;
       /* Double linked list of all active user objects with data pending
        * in message_buf[].
        */
Index: trunk/CHANGELOG
===================================================================
--- trunk/CHANGELOG	(Revision 2770)
+++ trunk/CHANGELOG	(Arbeitskopie)
@@ -1,6 +1,12 @@
 This file lists all changes made to the game driver in all glory detail.
 See the file HISTORY for a user-oriented summary of all the changes.
 
+21-Oct-2009 (Gnomi)
+  - Let the player_for_flush list point to interactive_t* directly.
+    This avoids inconsistencies between objects and their interactive
+    structure caused when exec()ing. (Bug #683)
+    (comm.c)
+
 18-Oct-2009 (Gnomi)
   - Free the xml buffer after xml reader and writer, because they might
     use it when cleaning up. (maybe #683)
