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