tBug with closing of network connections fixed - clients work with old servers now (hopefully) - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit c3b35b148c21d646f8af7b12d2f0379c3154576e
 (DIR) parent 7513ce1edb65ccdca3ed99d36a9c35f8bbfc3e84
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Tue, 19 Dec 2000 03:46:44 +0000
       
       Bug with closing of network connections fixed - clients work with old servers now (hopefully)
       
       
       Diffstat:
         M src/curses_client.c                 |      17 ++++++++++-------
         M src/dopeos.h                        |       5 +++--
         M src/gtk.c                           |      17 +++++++++++++++--
         M src/gtk_client.c                    |      36 ++++++++++++++++---------------
         M src/message.c                       |       9 ++++-----
       
       5 files changed, 51 insertions(+), 33 deletions(-)
       ---
 (DIR) diff --git a/src/curses_client.c b/src/curses_client.c
       t@@ -1400,6 +1400,7 @@ static void Curses_DoGame(Player *Play) {
           char HaveWorthless;
           Player *tmp;
           struct sigaction sact;
       +   gboolean ReadOK;
        
           DisplayMode=DM_NONE;
           QuitRequest=FALSE;
       t@@ -1540,7 +1541,15 @@ static void Curses_DoGame(Player *Play) {
                 perror("bselect"); exit(1);
              }
              if (Client && FD_ISSET(Play->fd,&readfs)) {
       -         if (!ReadConnectionBufferFromWire(Play)) {
       +         ReadOK=ReadConnectionBufferFromWire(Play);
       +
       +         while ((pt=ReadFromConnectionBuffer(Play))!=NULL) {
       +            HandleClientMessage(pt,Play);
       +            g_free(pt);
       +         }
       +         if (QuitRequest) return;
       +
       +         if (!ReadOK) {
                    attrset(TextAttr);
                    clear_line(22);
                    mvaddstr(22,0,_("Connection to server lost! "
       t@@ -1548,12 +1557,6 @@ static void Curses_DoGame(Player *Play) {
                    nice_wait();
                    SwitchToSinglePlayer(Play);
                    print_status(Play,TRUE);
       -         } else {
       -            while ((pt=ReadFromConnectionBuffer(Play))!=NULL) {
       -               HandleClientMessage(pt,Play);
       -               g_free(pt);
       -            }
       -            if (QuitRequest) return;
                 }
              }
              if (Client && FD_ISSET(Play->fd,&writefs)) {
 (DIR) diff --git a/src/dopeos.h b/src/dopeos.h
       t@@ -122,6 +122,9 @@ void fcntl(SOCKET s,int fsetfl,long cmd);
        void StartNetworking();
        void StopNetworking();
        void SetReuse(SOCKET sock);
       +#define EPIPE WSAECONNRESET 
       +#define EINPROGRESS WSAEWOULDBLOCK 
       +#define EAGAIN WSAEWOULDBLOCK 
        #endif
        
        #else /* Definitions for Unix build */
       t@@ -178,8 +181,6 @@ int GetSocketError();
        void StartNetworking();
        void StopNetworking();
        void SetReuse(int sock);
       -#define WSAECONNRESET EPIPE
       -#define WSAEWOULDBLOCK EINPROGRESS
        #endif /* NETWORKING */
        
        #endif /* CYGWIN */
 (DIR) diff --git a/src/gtk.c b/src/gtk.c
       t@@ -986,6 +986,7 @@ void gtk_window_update_focus(GtkWindow *window) {
        
        void gtk_widget_realize(GtkWidget *widget) {
           GtkRequisition req;
       +   if (GTK_WIDGET_REALIZED(widget)) return;
        /* g_print("Realizing widget %p of class %s\n",widget,GTK_OBJECT(widget)->klass->Name);*/
           gtk_signal_emit(GTK_OBJECT(widget),"realize",&req);
           if (widget->hWnd) SetWindowLong(widget->hWnd,GWL_USERDATA,(LONG)widget);
       t@@ -1499,6 +1500,10 @@ void gtk_box_pack_start(GtkBox *box,GtkWidget *child,gboolean Expand,
        
           box->children = g_list_append(box->children,(gpointer)newChild);
           child->parent = GTK_WIDGET(box);
       +   if (GTK_WIDGET_REALIZED(GTK_WIDGET(box))) {
       +      gtk_widget_realize(child);
       +      gtk_widget_update(GTK_WIDGET(box),TRUE);
       +   }
        }
        
        void gtk_button_destroy(GtkWidget *widget) {
       t@@ -2360,6 +2365,10 @@ void gtk_label_realize(GtkWidget *widget) {
        void gtk_container_add(GtkContainer *container,GtkWidget *widget) {
           container->child=widget;
           widget->parent=GTK_WIDGET(container);
       +   if (GTK_WIDGET_REALIZED(GTK_WIDGET(container))) {
       +      gtk_widget_realize(widget);
       +      gtk_widget_update(GTK_WIDGET(container),TRUE);
       +   }
        }
        
        void gtk_container_set_border_width(GtkContainer *container,
       t@@ -2405,6 +2414,10 @@ void gtk_table_attach(GtkTable *table,GtkWidget *widget,
        
           table->children=g_list_append(table->children,(gpointer)newChild);
           widget->parent = GTK_WIDGET(table);
       +   if (GTK_WIDGET_REALIZED(GTK_WIDGET(table))) {
       +      gtk_widget_realize(widget);
       +      gtk_widget_update(GTK_WIDGET(table),TRUE);
       +   }
        }
        
        void gtk_table_destroy(GtkWidget *widget) {
       t@@ -3443,8 +3456,8 @@ gint gdk_input_add(gint source,GdkInputCondition condition,
           input->function=function;
           input->data=data;
           rc=WSAAsyncSelect(source,TopLevel,WM_SOCKETDATA,
       -                  (condition&GDK_INPUT_READ ? FD_READ : 0) |
       -                  (condition&GDK_INPUT_WRITE ? FD_WRITE|FD_CONNECT : 0));
       +                  (condition&GDK_INPUT_READ ? FD_READ|FD_CLOSE:0) |
       +                  (condition&GDK_INPUT_WRITE ? FD_WRITE|FD_CONNECT|FD_CLOSE:0));
           GdkInputs=g_slist_append(GdkInputs,input);
           return source;
        }
 (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
       t@@ -280,6 +280,7 @@ void ListInventory(GtkWidget *widget,gpointer data) {
        void GetClientMessage(gpointer data,gint socket,
                              GdkInputCondition condition) {
           gchar *pt;
       +   gboolean ReadOK;
           if (condition&GDK_INPUT_WRITE) {
              WriteConnectionBufferToWire(ClientData.Play);
              if (ClientData.Play->WriteBuf.DataPresent==0) {
       t@@ -287,15 +288,17 @@ void GetClientMessage(gpointer data,gint socket,
              }
           }
           if (condition&GDK_INPUT_READ) {
       -      if (ReadConnectionBufferFromWire(ClientData.Play)) {
       -         while ((pt=ReadFromConnectionBuffer(ClientData.Play))!=NULL) {
       -            HandleClientMessage(pt,ClientData.Play); g_free(pt);
       -         }
       -      } else {
       +      ReadOK=ReadConnectionBufferFromWire(ClientData.Play);
       +      while ((pt=ReadFromConnectionBuffer(ClientData.Play))!=NULL) {
       +         HandleClientMessage(pt,ClientData.Play); g_free(pt);
       +      }
       +      if (!ReadOK) {
                 if (Network) gdk_input_remove(ClientData.GdkInputTag);
       -         g_warning(_("Connection to server lost - switching to "
       -                   "single player mode"));
       -         SwitchToSinglePlayer(ClientData.Play);
       +         if (InGame) {
       +            g_warning(_("Connection to server lost - switching to "
       +                      "single player mode"));
       +            SwitchToSinglePlayer(ClientData.Play);
       +         }
              }
           }
        }
       t@@ -460,7 +463,7 @@ void AddScoreToDialog(char *Data) {
        }
        
        static void EndHighScore(GtkWidget *widget) {
       -   gtk_widget_destroy(widget);
       +/* gtk_widget_destroy(widget);*/
           EndGame();
        }
        
       t@@ -468,14 +471,13 @@ void CompleteHighScoreDialog(gboolean AtEnd) {
           GtkWidget *OKButton,*dialog;
           dialog=HiScoreDialog.dialog;
           OKButton=gtk_button_new_with_label(_("OK"));
       +   gtk_signal_connect_object(GTK_OBJECT(OKButton),"clicked",
       +                             GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                             (gpointer)dialog);
           if (AtEnd) {
       -      gtk_signal_connect_object(GTK_OBJECT(OKButton),"clicked",
       -                                GTK_SIGNAL_FUNC(EndHighScore),
       -                                (gpointer)dialog);
       -   } else {
       -      gtk_signal_connect_object(GTK_OBJECT(OKButton),"clicked",
       -                                GTK_SIGNAL_FUNC(gtk_widget_destroy),
       -                                (gpointer)dialog);
       +      InGame=FALSE;
       +      gtk_signal_connect_object(GTK_OBJECT(dialog),"destroy",
       +                                GTK_SIGNAL_FUNC(EndHighScore),NULL);
           }
           gtk_box_pack_start(GTK_BOX(HiScoreDialog.vbox),OKButton,TRUE,TRUE,0);
         
       t@@ -1418,7 +1420,7 @@ char GtkLoop(HINSTANCE hInstance,HINSTANCE hPrevInstance) {
        char GtkLoop(int *argc,char **argv[],char ReturnOnFail) {
        #endif
           GtkWidget *window,*vbox,*vbox2,*hbox,*frame,*table,*menubar,*text,
       -             *vpaned,*button,*vscroll,*clist;
       +             *vpaned,*button,*clist;
           GtkAccelGroup *accel_group;
           GtkItemFactory *item_factory;
           GtkAdjustment *adj;
 (DIR) diff --git a/src/message.c b/src/message.c
       t@@ -324,14 +324,14 @@ gboolean ReadConnectionBufferFromWire(Player *Play) {
              BytesRead=recv(Play->fd,&conn->Data[CurrentPosition],
                             conn->Length-CurrentPosition,0);
              if (BytesRead==SOCKET_ERROR) {
       -         break;
       +         if (GetSocketError()==EAGAIN) break; else return FALSE;
              } else if (BytesRead==0) {
                 return FALSE;
              } else {
                 CurrentPosition+=BytesRead;
       +         conn->DataPresent=CurrentPosition;
              }
           }
       -   conn->DataPresent=CurrentPosition;
           return TRUE;
        }
        
       t@@ -372,8 +372,7 @@ gboolean WriteConnectionBufferToWire(Player *Play) {
              BytesSent=send(Play->fd,&conn->Data[CurrentPosition],
                             conn->DataPresent-CurrentPosition,0);
              if (BytesSent==SOCKET_ERROR) {
       -         if (GetSocketError()==WSAECONNRESET) return FALSE;
       -         break;
       +         if (GetSocketError()==EAGAIN) break; else return FALSE;
              } else {
                 CurrentPosition+=BytesSent;
              }
       t@@ -706,7 +705,7 @@ char *SetupNetwork(gboolean NonBlocking) {
           if (NonBlocking) fcntl(ClientSock,F_SETFL,O_NONBLOCK);
           if (connect(ClientSock,(struct sockaddr *)&ClientAddr,
               sizeof(struct sockaddr))==-1) {
       -      if (GetSocketError()==WSAEWOULDBLOCK) return NULL;
       +      if (GetSocketError()==EINPROGRESS) return NULL;
              CloseSocket(ClientSock);
              return NoConnect;
           } else {