All of lore.kernel.org
 help / color / mirror / Atom feed
From: Erik Faye-Lund <kusmabite@gmail.com>
To: git@vger.kernel.org
Cc: msysgit@googlegroups.com, j6t@kdbg.org, avarab@gmail.com,
	sunshine@sunshineco.com
Subject: [PATCH v4 08/15] daemon: use run-command api for async serving
Date: Mon, 11 Oct 2010 23:50:22 +0200	[thread overview]
Message-ID: <1286833829-5116-9-git-send-email-kusmabite@gmail.com> (raw)
In-Reply-To: <1286833829-5116-1-git-send-email-kusmabite@gmail.com>

fork() is only available on POSIX, so to support git-daemon
on Windows we have to use something else.

Instead we invent the flag --serve, which is a stripped down
version of --inetd-mode. We use start_command() to call
git-daemon with this flag appended to serve clients.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 daemon.c |   84 +++++++++++++++++++++++++++++++-------------------------------
 1 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/daemon.c b/daemon.c
index d594375..c0da052 100644
--- a/daemon.c
+++ b/daemon.c
@@ -614,17 +614,17 @@ static unsigned int live_children;
 
 static struct child {
 	struct child *next;
-	pid_t pid;
+	struct child_process cld;
 	struct sockaddr_storage address;
 } *firstborn;
 
-static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)
+static void add_child(struct child_process *cld, struct sockaddr *addr, int addrlen)
 {
 	struct child *newborn, **cradle;
 
 	newborn = xcalloc(1, sizeof(*newborn));
 	live_children++;
-	newborn->pid = pid;
+	memcpy(&newborn->cld, cld, sizeof(*cld));
 	memcpy(&newborn->address, addr, addrlen);
 	for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
 		if (!addrcmp(&(*cradle)->address, &newborn->address))
@@ -633,19 +633,6 @@ static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)
 	*cradle = newborn;
 }
 
-static void remove_child(pid_t pid)
-{
-	struct child **cradle, *blanket;
-
-	for (cradle = &firstborn; (blanket = *cradle); cradle = &blanket->next)
-		if (blanket->pid == pid) {
-			*cradle = blanket->next;
-			live_children--;
-			free(blanket);
-			break;
-		}
-}
-
 /*
  * This gets called if the number of connections grows
  * past "max_connections".
@@ -661,7 +648,7 @@ static void kill_some_child(void)
 
 	for (; (next = blanket->next); blanket = next)
 		if (!addrcmp(&blanket->address, &next->address)) {
-			kill(blanket->pid, SIGTERM);
+			kill(blanket->cld.pid, SIGTERM);
 			break;
 		}
 }
@@ -671,18 +658,26 @@ static void check_dead_children(void)
 	int status;
 	pid_t pid;
 
-	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
-		const char *dead = "";
-		remove_child(pid);
-		if (!WIFEXITED(status) || (WEXITSTATUS(status) > 0))
-			dead = " (with error)";
-		loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);
-	}
+	struct child **cradle, *blanket;
+	for (cradle = &firstborn; (blanket = *cradle);)
+		if ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) {
+			const char *dead = "";
+			if (status)
+				dead = " (with error)";
+			loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);
+
+			/* remove the child */
+			*cradle = blanket->next;
+			live_children--;
+			free(blanket);
+		} else
+			cradle = &blanket->next;
 }
 
+static char **cld_argv;
 static void handle(int incoming, struct sockaddr *addr, int addrlen)
 {
-	pid_t pid;
+	struct child_process cld = { 0 };
 
 	if (max_connections && live_children >= max_connections) {
 		kill_some_child();
@@ -695,22 +690,15 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
 		}
 	}
 
-	if ((pid = fork())) {
-		close(incoming);
-		if (pid < 0) {
-			logerror("Couldn't fork %s", strerror(errno));
-			return;
-		}
-
-		add_child(pid, addr, addrlen);
-		return;
-	}
+	cld.argv = (const char **)cld_argv;
+	cld.in = incoming;
+	cld.out = dup(incoming);
 
-	dup2(incoming, 0);
-	dup2(incoming, 1);
+	if (start_command(&cld))
+		logerror("unable to fork");
+	else
+		add_child(&cld, addr, addrlen);
 	close(incoming);
-
-	exit(execute(addr));
 }
 
 static void child_handler(int signo)
@@ -991,7 +979,7 @@ int main(int argc, char **argv)
 {
 	int listen_port = 0;
 	struct string_list listen_addr = STRING_LIST_INIT_NODUP;
-	int inetd_mode = 0;
+	int serve_mode = 0, inetd_mode = 0;
 	const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
 	int detach = 0;
 	struct passwd *pass = NULL;
@@ -1017,7 +1005,12 @@ int main(int argc, char **argv)
 				continue;
 			}
 		}
+		if (!strcmp(arg, "--serve")) {
+			serve_mode = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--inetd")) {
+			serve_mode = 1;
 			inetd_mode = 1;
 			log_syslog = 1;
 			continue;
@@ -1161,12 +1154,12 @@ int main(int argc, char **argv)
 		die("base-path '%s' does not exist or is not a directory",
 		    base_path);
 
-	if (inetd_mode) {
+	if (serve_mode) {
 		struct sockaddr_storage ss;
 		struct sockaddr *peer = (struct sockaddr *)&ss;
 		socklen_t slen = sizeof(ss);
 
-		if (!freopen("/dev/null", "w", stderr))
+		if (inetd_mode && !freopen("/dev/null", "w", stderr))
 			die_errno("failed to redirect stderr to /dev/null");
 
 		if (getpeername(0, peer, &slen))
@@ -1185,5 +1178,12 @@ int main(int argc, char **argv)
 	if (pid_file)
 		store_pid(pid_file);
 
+	/* prepare argv for serving-processes */
+	cld_argv = xmalloc(sizeof (char *) * (argc + 2));
+	for (i = 0; i < argc; ++i)
+		cld_argv[i] = argv[i];
+	cld_argv[argc] = "--serve";
+	cld_argv[argc+1] = NULL;
+
 	return serve(&listen_addr, listen_port, pass, gid);
 }
-- 
1.7.3.1.199.g72340

  parent reply	other threads:[~2010-10-11 21:52 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-11 21:50 [PATCH v4 00/15] daemon-win32 Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 01/15] mingw: add network-wrappers for daemon Erik Faye-Lund
2010-10-11 22:07   ` Jonathan Nieder
2010-10-11 21:50 ` [PATCH v4 02/15] mingw: implement syslog Erik Faye-Lund
2010-10-11 22:11   ` Jonathan Nieder
2010-10-11 22:28     ` Erik Faye-Lund
2010-10-11 22:37       ` Jonathan Nieder
2010-10-13 12:36         ` Erik Faye-Lund
2010-10-13 19:23           ` Eric Sunshine
2010-10-13 21:17             ` [msysGit] " Pat Thoyts
2010-10-14  0:47               ` Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 03/15] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 04/15] inet_ntop: fix a couple of old-style decls Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 05/15] mingw: use real pid Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 06/15] mingw: support waitpid with pid > 0 and WNOHANG Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 07/15] mingw: add kill emulation Erik Faye-Lund
2010-10-11 21:50 ` Erik Faye-Lund [this message]
2010-10-13 22:47   ` [PATCH v4 08/15] daemon: use run-command api for async serving Junio C Hamano
2010-10-14 10:18     ` Erik Faye-Lund
2010-10-17  4:43       ` Junio C Hamano
2010-10-11 21:50 ` [PATCH v4 09/15] daemon: use full buffered mode for stderr Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 10/15] Improve the mingw getaddrinfo stub to handle more use cases Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 11/15] daemon: report connection from root-process Erik Faye-Lund
2010-10-13 22:55   ` Junio C Hamano
2010-10-14 10:50     ` Erik Faye-Lund
2010-10-17  4:43       ` Junio C Hamano
2010-10-17 10:18         ` Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 12/15] mingw: import poll-emulation from gnulib Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 13/15] mingw: use " Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 14/15] daemon: use socklen_t Erik Faye-Lund
2010-10-11 21:50 ` [PATCH v4 15/15] daemon: opt-out on features that require posix Erik Faye-Lund
2010-10-13 23:02   ` Junio C Hamano
2010-10-14 11:02     ` Erik Faye-Lund
2010-10-15 21:16       ` Junio C Hamano
2010-10-18 12:05         ` Erik Faye-Lund
2010-10-18 16:31           ` Jonathan Nieder
2010-10-18 18:13             ` Andreas Schwab
2010-10-18 18:42               ` empty structs Jonathan Nieder
2010-10-21 21:16             ` [PATCH v4 15/15] daemon: opt-out on features that require posix Erik Faye-Lund
2010-10-21 22:00               ` Erik Faye-Lund
2010-10-21 22:03                 ` Jonathan Nieder
2010-10-21 22:04                 ` Erik Faye-Lund
2010-10-21 23:17                 ` Junio C Hamano
2010-10-18 19:26           ` Junio C Hamano
2010-10-21 20:37   ` Erik Faye-Lund
2010-10-21 20:39     ` Jonathan Nieder
2010-10-21 20:54       ` Erik Faye-Lund

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1286833829-5116-9-git-send-email-kusmabite@gmail.com \
    --to=kusmabite@gmail.com \
    --cc=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=j6t@kdbg.org \
    --cc=msysgit@googlegroups.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.