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++) {