git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/2] daemon: graceful shutdown of client connection

From
Kim Gybels <kgybels@infogroep.be>
Date
Apr 12, 2018, 21:07 UTC
Message-ID
<20180412210757.7792-3-kgybels@infogroep.be>
In-Reply-To
<20180412210757.7792-1-kgybels@infogroep.be>

On Windows, a connection is shutdown when the last open handle to it is closed. When that last open handle is stdout of our child process, an abortive shutdown is triggered when said process exits. Ensure a graceful shutdown of the client connection by keeping an open handle until we detect our child process has finished. This allows all the data to be sent to the client, instead of being discarded.

Fixes https://github.com/git-for-windows/git/issues/304
Signed-off-by: Kim Gybels <kgybels@infogroep.be>
---
 daemon.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/daemon.c b/daemon.c
index 6dc95c1b2f..97fadd62d1 100644
--- a/daemon.c
+++ b/daemon.c
@@ -834,9 +834,10 @@ static struct child {
 	struct child *next;
 	struct child_process cld;
 	struct sockaddr_storage address;
+	int connection;
 } *firstborn;
 
-static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen)
+static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen, int connection)
 {
 	struct child *newborn, **cradle;
 
@@ -844,6 +845,7 @@ static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_
 	live_children++;
 	memcpy(&newborn->cld, cld, sizeof(*cld));
 	memcpy(&newborn->address, addr, addrlen);
+	newborn->connection = connection;
 	for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
 		if (!addrcmp(&(*cradle)->address, &newborn->address))
 			break;
@@ -888,6 +890,7 @@ static void check_dead_children(void)
 			*cradle = blanket->next;
 			live_children--;
 			child_process_clear(&blanket->cld);
+			close(blanket->connection);
 			free(blanket);
 		} else
 			cradle = &blanket->next;
@@ -928,13 +931,13 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
 	}
 
 	cld.argv = cld_argv.argv;
-	cld.in = incoming;
+	cld.in = dup(incoming);
 	cld.out = dup(incoming);
 
 	if (start_command(&cld))
 		logerror("unable to fork");
 	else
-		add_child(&cld, addr, addrlen);
+		add_child(&cld, addr, addrlen, incoming);
 }
 
 static void child_handler(int signo)
-- 
2.17.0.windows.1
Previous: Junio C HamanoNext: Johannes Schindelin
Message 12 of 15 in “Fix early EOF with GfW daemon”
  1. 0/2 Fix early EOF with GfW daemonKim Gybels, Apr 12, 2018
  2. 1/2 daemon: use timeout for uninterruptible pollKim Gybels, Apr 12, 2018
  3. Johannes SchindelinApr 13, 2018
  4. Kim GybelsApr 15, 2018
  5. Johannes SchindelinApr 18, 2018
  6. Junio C HamanoApr 15, 2018
  7. Junio C HamanoApr 15, 2018
  8. Johannes SchindelinApr 18, 2018
  9. Junio C HamanoApr 18, 2018
  10. Kim GybelsApr 19, 2018
  11. Junio C HamanoApr 19, 2018
  12. 2/2 daemon: graceful shutdown of client connectionKim Gybels, Apr 12, 2018
  13. Johannes SchindelinApr 13, 2018
  14. Kim GybelsApr 15, 2018
  15. Johannes SchindelinApr 18, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.