Blob Blame History Raw
Index: libgamin/gam_api.c
===================================================================
RCS file: /cvs/gnome/gamin/libgamin/gam_api.c,v
retrieving revision 1.39
diff -u -p -r1.39 gam_api.c
--- libgamin/gam_api.c	5 Aug 2005 14:06:49 -0000	1.39
+++ libgamin/gam_api.c	16 Aug 2006 14:59:27 -0000
@@ -744,7 +744,6 @@ retry:
     return(0);
 
 failed:
-    close(fd);
     return (-1);
 }
 
@@ -891,39 +890,38 @@ gamin_try_reconnect(GAMDataPtr conn, int
     /*
      * try to reopen a connection to the server
      */
-    close(fd);
     newfd = gamin_connect_unix_socket(socket_name);
-
     free(socket_name);
     if (newfd < 0) {
         return (-1);
     }
 
-    if (newfd != fd) {
-	/*
-	 * reuse the same descriptor
-	 */
-	ret = dup2(newfd, fd);
-	if (ret < 0) {
-	    gam_error(DEBUG_INFO,
-	              "Failed to reuse descriptor %d on reconnect\n",
-		      fd);
-	    close(newfd);
-	    return (-1);
-	}
-    }
-
     /*
      * seems we managed to rebuild a connection to the server.
      * start the authentication again and resubscribe all existing
      * monitoring commands.
      */
-    ret = gamin_write_credential_byte(fd);
+    ret = gamin_write_credential_byte(newfd);
     if (ret != 0) {
-        close(fd);
+        close(newfd);
         return (-1);
     }
 
+    /*
+     * reuse the same descriptor. We never close the original fd, dup2
+     * atomically overwrites it and closes the original. This way we
+     * never leave the original fd closed, since that can cause trouble
+     * if the app keeps the fd around.
+     */
+    ret = dup2(newfd, fd);
+    close(newfd);
+    if (ret < 0) {
+	gam_error(DEBUG_INFO,
+		  "Failed to reuse descriptor %d on reconnect\n",
+		  fd);
+	return (-1);
+    }
+    
     nb_req = gamin_data_reset(conn, &reqs);
     if (reqs != NULL) {
 	for (i = 0; i < nb_req;i++) {