All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/14] daemon-win32
@ 2010-01-15 21:30 Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 01/14] mingw: add network-wrappers for daemon Erik Faye-Lund
                   ` (14 more replies)
  0 siblings, 15 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

Here's the long overdue v2 of my daemon-win32 attempt. A lot
has happened since v1. Most importantly, I abandoned using
the async API to replace fork(), and went for explicitly
spawning child process that handle the connection.

The patches are on top of the current version of Junio's
master-branch.

When talking about patch numbers here, I'm referring to the numbers
from the previous round.

Patch 1 has been adjusted to work on top of Martin's ipv6 patches.

Patch 2 has been dropped, because it was made obsolete by the
changes to patch 3.

Patch 3 has been simplified as suggested by Hannes. The problem with
reporting IPv6 addresses should still be there in theory, but I
haven't been able to trigger it. I'm having a feeling that it's better
to do a case-by-case patch of the code that reports for this one.

Patch 4 and 5 are unchanged.

Patch 6 and 7 were dropped, in favour of a new approach.

Patch 8 has been updated as suggested.

Patch 9 has been rewritten to spawn a separate child process that
serves the client.

Patch 10 is unchanged

Patch 11 has been updated as suggested.

In addition, I've added a patch that add some needed support in
our waitpid()-emulation, a (very limited) kill()-emulation, a patch
that uses real PIDs on Windows (instead of process-local kernel-handles),
a patch that changes the code to use select() instead of poll() to wait
for socket-action (due to our limited poll-emulation). And there's a
patch that makes sure connections are reported from the root-process.

In addition, I've attached an updated version of the getaddrinfo()-fix
that Martin sent me privately. I removed Hannes sign-off (as requested by
Martin, due to the update)

The branch can also be found here:
http://repo.or.cz/w/git/kusma.git daemon-win32-v2

Puuuh, I hope I didn't miss anything important.


Erik Faye-Lund (10):
  inet_ntop: fix a couple of old-style decls
  mingw: support waitpid with pid > 0 and WNOHANG
  mingw: use real pid
  mingw: add kill emulation
  daemon: use explicit file descriptor
  daemon: use run-command api for async serving
  daemon: use full buffered mode for stderr
  mingw: compile git-daemon
  daemon: use select() instead of poll()
  daemon: report connection from root-process

Martin Storsjö (1):
  Improve the mingw getaddrinfo stub to handle more use cases

Mike Pape (3):
  mingw: add network-wrappers for daemon
  mingw: implement syslog
  compat: add inet_pton and inet_ntop prototypes

 Makefile           |   10 +-
 compat/inet_ntop.c |   22 ++----
 compat/inet_pton.c |    8 +-
 compat/mingw.c     |  141 +++++++++++++++++++++++++++++--
 compat/mingw.h     |   80 +++++++++++++++++-
 daemon.c           |  236 ++++++++++++++++++++++++++++------------------------
 git-compat-util.h  |    9 ++
 7 files changed, 361 insertions(+), 145 deletions(-)

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH v2 01/14] mingw: add network-wrappers for daemon
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 02/14] mingw: implement syslog Erik Faye-Lund
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Mike Pape, Erik Faye-Lund

From: Mike Pape <dotzenlabs@gmail.com>

git-daemon requires some socket-functionality that is not yet
supported in the Windows-port. This patch adds said functionality,
and makes sure WSAStartup gets called by socket(), since it is the
first network-call in git-daemon. In addition, a check is added to
prevent WSAStartup (and WSACleanup, though atexit) from being
called more than once, since git-daemon calls both socket() and
gethostbyname().

Signed-off-by: Mike Pape <dotzenlabs@gmail.com>
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/mingw.c |   43 ++++++++++++++++++++++++++++++++++++++++++-
 compat/mingw.h |   16 ++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index 0d73f15..42ef9e2 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1095,7 +1095,10 @@ int mingw_getnameinfo(const struct sockaddr *sa, socklen_t salen,
 int mingw_socket(int domain, int type, int protocol)
 {
 	int sockfd;
-	SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0);
+	SOCKET s;
+
+	ensure_socket_initialization();
+	s = WSASocket(domain, type, protocol, NULL, 0, 0);
 	if (s == INVALID_SOCKET) {
 		/*
 		 * WSAGetLastError() values are regular BSD error codes
@@ -1125,6 +1128,44 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
 	return connect(s, sa, sz);
 }
 
+#undef bind
+int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz)
+{
+	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
+	return bind(s, sa, sz);
+}
+
+#undef setsockopt
+int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen)
+{
+	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
+	return setsockopt(s, lvl, optname, (const char*)optval, optlen);
+}
+
+#undef listen
+int mingw_listen(int sockfd, int backlog)
+{
+	SOCKET s = (SOCKET)_get_osfhandle(sockfd);
+	return listen(s, backlog);
+}
+
+#undef accept
+int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
+{
+	int sockfd2;
+
+	SOCKET s1 = (SOCKET)_get_osfhandle(sockfd1);
+	SOCKET s2 = accept(s1, sa, sz);
+
+	/* convert into a file descriptor */
+	if ((sockfd2 = _open_osfhandle(s2, O_RDWR|O_BINARY)) < 0) {
+		closesocket(s2);
+		return error("unable to make a socket file descriptor: %s",
+			strerror(errno));
+	}
+	return sockfd2;
+}
+
 #undef rename
 int mingw_rename(const char *pold, const char *pnew)
 {
diff --git a/compat/mingw.h b/compat/mingw.h
index b3d299f..07513bb 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -6,6 +6,7 @@
  */
 
 typedef int pid_t;
+typedef int socklen_t;
 #define hstrerror strerror
 
 #define S_IFLNK    0120000 /* Symbolic link */
@@ -34,6 +35,9 @@ typedef int pid_t;
 #define F_SETFD 2
 #define FD_CLOEXEC 0x1
 
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define ECONNABORTED WSAECONNABORTED
+
 struct passwd {
 	char *pw_name;
 	char *pw_gecos;
@@ -197,6 +201,18 @@ int mingw_socket(int domain, int type, int protocol);
 int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz);
 #define connect mingw_connect
 
+int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz);
+#define bind mingw_bind
+
+int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen);
+#define setsockopt mingw_setsockopt
+
+int mingw_listen(int sockfd, int backlog);
+#define listen mingw_listen
+
+int mingw_accept(int sockfd, struct sockaddr *sa, socklen_t *sz);
+#define accept mingw_accept
+
 int mingw_rename(const char*, const char*);
 #define rename mingw_rename
 
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 02/14] mingw: implement syslog
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 01/14] mingw: add network-wrappers for daemon Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:57   ` [msysGit] " Janos Laube
  2010-01-15 21:30 ` [PATCH v2 03/14] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Mike Pape, Erik Faye-Lund

From: Mike Pape <dotzenlabs@gmail.com>

Syslog does not usually exist on Windows, so we implement our own
using Window's ReportEvent mechanism.

Signed-off-by: Mike Pape <dotzenlabs@gmail.com>
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/mingw.c    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 compat/mingw.h    |   15 +++++++++++++++
 daemon.c          |    2 --
 git-compat-util.h |    1 +
 4 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index 42ef9e2..54be905 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1351,6 +1351,55 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out)
 	return 0;
 }
 
+static HANDLE ms_eventlog;
+
+void openlog(const char *ident, int logopt, int facility)
+{
+	if (ms_eventlog)
+		return;
+	ms_eventlog = RegisterEventSourceA(NULL, ident);
+}
+
+void syslog(int priority, const char *fmt, const char *arg)
+{
+	WORD logtype;
+
+	if (strcmp(fmt, "%s")) {
+		warning("format string of syslog() not implemented");
+		return;
+	}
+
+	switch (priority) {
+		case LOG_EMERG:
+		case LOG_ALERT:
+		case LOG_CRIT:
+		case LOG_ERR:
+			logtype = EVENTLOG_ERROR_TYPE;
+			break;
+
+		case LOG_WARNING:
+			logtype = EVENTLOG_WARNING_TYPE;
+			break;
+
+		case LOG_NOTICE:
+		case LOG_INFO:
+		case LOG_DEBUG:
+		default:
+			logtype = EVENTLOG_INFORMATION_TYPE;
+			break;
+	}
+
+	ReportEventA(ms_eventlog,
+	    logtype,
+	    0,
+	    0,
+	    NULL,
+	    1,
+	    0,
+	    (const char **)&arg,
+	    NULL);
+}
+
 #undef signal
 sig_handler_t mingw_signal(int sig, sig_handler_t handler)
 {
diff --git a/compat/mingw.h b/compat/mingw.h
index 07513bb..d934e56 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -38,6 +38,19 @@ typedef int socklen_t;
 #define EAFNOSUPPORT WSAEAFNOSUPPORT
 #define ECONNABORTED WSAECONNABORTED
 
+#define LOG_PID     0x01
+
+#define LOG_EMERG   0
+#define LOG_ALERT   1
+#define LOG_CRIT    2
+#define LOG_ERR     3
+#define LOG_WARNING 4
+#define LOG_NOTICE  5
+#define LOG_INFO    6
+#define LOG_DEBUG   7
+
+#define LOG_DAEMON  (3<<3)
+
 struct passwd {
 	char *pw_name;
 	char *pw_gecos;
@@ -166,6 +179,8 @@ struct passwd *getpwuid(int uid);
 int setitimer(int type, struct itimerval *in, struct itimerval *out);
 int sigaction(int sig, struct sigaction *in, struct sigaction *out);
 int link(const char *oldpath, const char *newpath);
+void openlog(const char *ident, int logopt, int facility);
+void syslog(int priority, const char *fmt, const char *arg);
 
 /*
  * replacements of existing functions
diff --git a/daemon.c b/daemon.c
index 918e560..79ba1aa 100644
--- a/daemon.c
+++ b/daemon.c
@@ -4,8 +4,6 @@
 #include "run-command.h"
 #include "strbuf.h"
 
-#include <syslog.h>
-
 #ifndef HOST_NAME_MAX
 #define HOST_NAME_MAX 256
 #endif
diff --git a/git-compat-util.h b/git-compat-util.h
index 5c59687..30e6240 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -105,6 +105,7 @@
 #include <netdb.h>
 #include <pwd.h>
 #include <inttypes.h>
+#include <syslog.h>
 #if defined(__CYGWIN__)
 #undef _XOPEN_SOURCE
 #include <grp.h>
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 03/14] compat: add inet_pton and inet_ntop prototypes
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 01/14] mingw: add network-wrappers for daemon Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 02/14] mingw: implement syslog Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 04/14] inet_ntop: fix a couple of old-style decls Erik Faye-Lund
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Mike Pape, Erik Faye-Lund

From: Mike Pape <dotzenlabs@gmail.com>

Windows doesn't have inet_pton and inet_ntop, so
add prototypes in git-compat-util.h for them.

At the same time include git-compat-util.h in
the sources for these functions, so they use the
network-wrappers from there on Windows.

Signed-off-by: Mike Pape <dotzenlabs@gmail.com>
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 Makefile           |    2 ++
 compat/inet_ntop.c |    6 +++---
 compat/inet_pton.c |    8 +++++---
 git-compat-util.h  |    8 ++++++++
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index ebaa75c..d81b392 100644
--- a/Makefile
+++ b/Makefile
@@ -1289,9 +1289,11 @@ endif
 endif
 ifdef NO_INET_NTOP
 	LIB_OBJS += compat/inet_ntop.o
+	BASIC_CFLAGS += -DNO_INET_NTOP
 endif
 ifdef NO_INET_PTON
 	LIB_OBJS += compat/inet_pton.o
+	BASIC_CFLAGS += -DNO_INET_PTON
 endif
 
 ifdef NO_ICONV
diff --git a/compat/inet_ntop.c b/compat/inet_ntop.c
index f444982..e5b46a0 100644
--- a/compat/inet_ntop.c
+++ b/compat/inet_ntop.c
@@ -17,9 +17,9 @@
 
 #include <errno.h>
 #include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+
+#include "../git-compat-util.h"
+
 #include <stdio.h>
 #include <string.h>
 
diff --git a/compat/inet_pton.c b/compat/inet_pton.c
index 4078fc0..2ec995e 100644
--- a/compat/inet_pton.c
+++ b/compat/inet_pton.c
@@ -17,9 +17,9 @@
 
 #include <errno.h>
 #include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+
+#include "../git-compat-util.h"
+
 #include <stdio.h>
 #include <string.h>
 
@@ -41,7 +41,9 @@
  */
 
 static int inet_pton4(const char *src, unsigned char *dst);
+#ifndef NO_IPV6
 static int inet_pton6(const char *src, unsigned char *dst);
+#endif
 
 /* int
  * inet_pton4(src, dst)
diff --git a/git-compat-util.h b/git-compat-util.h
index 30e6240..937fb1b 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -341,6 +341,14 @@ static inline char *gitstrchrnul(const char *s, int c)
 }
 #endif
 
+#ifdef NO_INET_PTON
+int inet_pton(int af, const char *src, void *dst);
+#endif
+
+#ifdef NO_INET_NTOP
+const char *inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+
 extern void release_pack_memory(size_t, int);
 
 extern char *xstrdup(const char *str);
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 04/14] inet_ntop: fix a couple of old-style decls
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (2 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 03/14] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG Erik Faye-Lund
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/inet_ntop.c |   16 +++-------------
 1 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/compat/inet_ntop.c b/compat/inet_ntop.c
index e5b46a0..ea249c6 100644
--- a/compat/inet_ntop.c
+++ b/compat/inet_ntop.c
@@ -50,10 +50,7 @@
  *	Paul Vixie, 1996.
  */
 static const char *
-inet_ntop4(src, dst, size)
-	const u_char *src;
-	char *dst;
-	size_t size;
+inet_ntop4(const u_char *src, char *dst, size_t size)
 {
 	static const char fmt[] = "%u.%u.%u.%u";
 	char tmp[sizeof "255.255.255.255"];
@@ -78,10 +75,7 @@ inet_ntop4(src, dst, size)
  *	Paul Vixie, 1996.
  */
 static const char *
-inet_ntop6(src, dst, size)
-	const u_char *src;
-	char *dst;
-	size_t size;
+inet_ntop6(const u_char *src, char *dst, size_t size)
 {
 	/*
 	 * Note that int32_t and int16_t need only be "at least" large enough
@@ -178,11 +172,7 @@ inet_ntop6(src, dst, size)
  *	Paul Vixie, 1996.
  */
 const char *
-inet_ntop(af, src, dst, size)
-	int af;
-	const void *src;
-	char *dst;
-	size_t size;
+inet_ntop(int af, const void *src, char *dst, size_t size)
 {
 	switch (af) {
 	case AF_INET:
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (3 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 04/14] inet_ntop: fix a couple of old-style decls Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:28   ` Johannes Sixt
  2010-01-15 21:30 ` [PATCH v2 06/14] mingw: use real pid Erik Faye-Lund
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/mingw.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/compat/mingw.h b/compat/mingw.h
index d934e56..3005472 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -134,8 +134,15 @@ static inline int mingw_unlink(const char *pathname)
 }
 #define unlink mingw_unlink
 
+#define WNOHANG 1
 static inline int waitpid(pid_t pid, int *status, unsigned options)
 {
+	if (pid > 0 && options & WNOHANG) {
+		if (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)pid, 0))
+			return 0;
+		options &= ~WNOHANG;
+	}
+
 	if (options == 0)
 		return _cwait(status, pid, 0);
 	errno = EINVAL;
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 06/14] mingw: use real pid
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (4 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:30   ` Johannes Sixt
  2010-01-15 21:30 ` [PATCH v2 07/14] mingw: add kill emulation Erik Faye-Lund
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

The Windows port so far used process handles as PID. However,
this does not work consistently with getpid.

Change the code to use the real PID, and use OpenProcess to
get a process-handle.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/mingw.c |    2 +-
 compat/mingw.h |   35 +++++++++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index 54be905..ce4f829 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -729,7 +729,7 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
 		return -1;
 	}
 	CloseHandle(pi.hThread);
-	return (pid_t)pi.hProcess;
+	return (pid_t)pi.dwProcessId;
 }
 
 pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env)
diff --git a/compat/mingw.h b/compat/mingw.h
index 3005472..ff4a76b 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -137,14 +137,41 @@ static inline int mingw_unlink(const char *pathname)
 #define WNOHANG 1
 static inline int waitpid(pid_t pid, int *status, unsigned options)
 {
-	if (pid > 0 && options & WNOHANG) {
-		if (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)pid, 0))
+	HANDLE h;
+
+	if (pid <= 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid);
+	if (!h) {
+		errno = ECHILD;
+		return -1;
+	}
+
+	if (options & WNOHANG) {
+		if (WaitForSingleObject(h, 0) != WAIT_OBJECT_0) {
+			CloseHandle(h);
 			return 0;
+		}
 		options &= ~WNOHANG;
 	}
 
-	if (options == 0)
-		return _cwait(status, pid, 0);
+	if (options == 0) {
+		if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
+			CloseHandle(h);
+			return 0;
+		}
+
+		if (status)
+			GetExitCodeProcess(h, (LPDWORD)status);
+
+		CloseHandle(h);
+		return pid;
+	}
+	CloseHandle(h);
+
 	errno = EINVAL;
 	return -1;
 }
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 07/14] mingw: add kill emulation
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (5 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 06/14] mingw: use real pid Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:31   ` Johannes Sixt
  2010-01-15 21:30 ` [PATCH v2 08/14] daemon: use explicit file descriptor Erik Faye-Lund
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

This is a quite limited kill-emulation; it can only handle
SIGTERM on positive pids. However, it's enough for git-daemon.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/mingw.c |   19 +++++++++++++++++++
 compat/mingw.h |    3 +++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index ce4f829..89b9b89 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -829,6 +829,25 @@ void mingw_execvp(const char *cmd, char *const *argv)
 	free_path_split(path);
 }
 
+int mingw_kill(pid_t pid, int sig)
+{
+	if (pid > 0 && sig == SIGTERM) {
+		HANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
+
+		if (TerminateProcess(h, -1)) {
+			CloseHandle(h);
+			return 0;
+		}
+
+		CloseHandle(h);
+		errno = err_win_to_posix(GetLastError());
+		return -1;
+	}
+
+	errno = EINVAL;
+	return -1;
+}
+
 static char **copy_environ(void)
 {
 	char **env;
diff --git a/compat/mingw.h b/compat/mingw.h
index ff4a76b..e72c2ee 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -176,6 +176,9 @@ static inline int waitpid(pid_t pid, int *status, unsigned options)
 	return -1;
 }
 
+#define kill mingw_kill
+int mingw_kill(pid_t pid, int sig);
+
 #ifndef NO_OPENSSL
 #include <openssl/ssl.h>
 static inline int mingw_SSL_set_fd(SSL *ssl, int fd)
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 08/14] daemon: use explicit file descriptor
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (6 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 07/14] mingw: add kill emulation Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:36   ` Johannes Sixt
  2010-01-15 21:30 ` [PATCH v2 09/14] daemon: use run-command api for async serving Erik Faye-Lund
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

This patch adds support to specify an explicit file
descriotor for communication with the client, instead
of using stdin/stdout.

This will be useful for the Windows port, because it
will use threads instead of fork() to serve multiple
clients, making it impossible to reuse stdin/stdout.

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

diff --git a/daemon.c b/daemon.c
index 79ba1aa..b42792f 100644
--- a/daemon.c
+++ b/daemon.c
@@ -218,7 +218,7 @@ static char *path_ok(char *directory)
 	return NULL;		/* Fallthrough. Deny by default */
 }
 
-typedef int (*daemon_service_fn)(void);
+typedef int (*daemon_service_fn)(int [2]);
 struct daemon_service {
 	const char *name;
 	const char *config_name;
@@ -242,7 +242,7 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
 	return 0;
 }
 
-static int run_service(char *dir, struct daemon_service *service)
+static int run_service(int fd[2], char *dir, struct daemon_service *service)
 {
 	const char *path;
 	int enabled = service->enabled;
@@ -295,7 +295,7 @@ static int run_service(char *dir, struct daemon_service *service)
 	 */
 	signal(SIGTERM, SIG_IGN);
 
-	return service->fn();
+	return service->fn(fd);
 }
 
 static void copy_to_log(int fd)
@@ -319,7 +319,7 @@ static void copy_to_log(int fd)
 	fclose(fp);
 }
 
-static int run_service_command(const char **argv)
+static int run_service_command(int fd[2], const char **argv)
 {
 	struct child_process cld;
 
@@ -327,37 +327,36 @@ static int run_service_command(const char **argv)
 	cld.argv = argv;
 	cld.git_cmd = 1;
 	cld.err = -1;
+	cld.in = fd[0];
+	cld.out = fd[1];
 	if (start_command(&cld))
 		return -1;
 
-	close(0);
-	close(1);
-
 	copy_to_log(cld.err);
 
 	return finish_command(&cld);
 }
 
-static int upload_pack(void)
+static int upload_pack(int fd[2])
 {
 	/* Timeout as string */
 	char timeout_buf[64];
 	const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
 
 	snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
-	return run_service_command(argv);
+	return run_service_command(fd, argv);
 }
 
-static int upload_archive(void)
+static int upload_archive(int fd[2])
 {
 	static const char *argv[] = { "upload-archive", ".", NULL };
-	return run_service_command(argv);
+	return run_service_command(fd, argv);
 }
 
-static int receive_pack(void)
+static int receive_pack(int fd[2])
 {
 	static const char *argv[] = { "receive-pack", ".", NULL };
-	return run_service_command(argv);
+	return run_service_command(fd, argv);
 }
 
 static struct daemon_service daemon_service[] = {
@@ -487,7 +486,7 @@ static void parse_host_arg(char *extra_args, int buflen)
 }
 
 
-static int execute(struct sockaddr *addr)
+static int execute(int fd[2], struct sockaddr *addr)
 {
 	static char line[1000];
 	int pktlen, len, i;
@@ -520,7 +519,7 @@ static int execute(struct sockaddr *addr)
 	}
 
 	alarm(init_timeout ? init_timeout : timeout);
-	pktlen = packet_read_line(0, line, sizeof(line));
+	pktlen = packet_read_line(fd[0], line, sizeof(line));
 	alarm(0);
 
 	len = strlen(line);
@@ -552,7 +551,7 @@ static int execute(struct sockaddr *addr)
 			 * Note: The directory here is probably context sensitive,
 			 * and might depend on the actual service being performed.
 			 */
-			return run_service(line + namelen + 5, s);
+			return run_service(fd, line + namelen + 5, s);
 		}
 	}
 
@@ -652,6 +651,7 @@ static void check_dead_children(void)
 
 static void handle(int incoming, struct sockaddr *addr, int addrlen)
 {
+	int fd[2];
 	pid_t pid;
 
 	if (max_connections && live_children >= max_connections) {
@@ -676,11 +676,9 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
 		return;
 	}
 
-	dup2(incoming, 0);
-	dup2(incoming, 1);
-	close(incoming);
-
-	exit(execute(addr));
+	fd[0] = incoming;
+	fd[1] = dup(incoming);
+	exit(execute(fd, addr));
 }
 
 static void child_handler(int signo)
@@ -1107,6 +1105,7 @@ int main(int argc, char **argv)
 		    base_path);
 
 	if (inetd_mode) {
+		int fd[2] = { 0, 1 };
 		struct sockaddr_storage ss;
 		struct sockaddr *peer = (struct sockaddr *)&ss;
 		socklen_t slen = sizeof(ss);
@@ -1117,7 +1116,7 @@ int main(int argc, char **argv)
 		if (getpeername(0, peer, &slen))
 			peer = NULL;
 
-		return execute(peer);
+		return execute(fd, peer);
 	}
 
 	if (detach) {
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 09/14] daemon: use run-command api for async serving
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (7 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 08/14] daemon: use explicit file descriptor Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:42   ` Johannes Sixt
  2010-01-15 21:30 ` [PATCH v2 10/14] daemon: use full buffered mode for stderr Erik Faye-Lund
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

fork() is only available on POSIX, so to support git-daemon
on Windows we have to use something else. Conveniently
enough, we have an API for async operation already.

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

diff --git a/daemon.c b/daemon.c
index b42792f..2d63cbc 100644
--- a/daemon.c
+++ b/daemon.c
@@ -583,17 +583,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))
@@ -602,19 +602,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".
@@ -623,14 +610,14 @@ static void remove_child(pid_t pid)
  */
 static void kill_some_child(void)
 {
-	const struct child *blanket, *next;
+	struct child *blanket, *next;
 
 	if (!(blanket = firstborn))
 		return;
 
 	for (; (next = blanket->next); blanket = next)
 		if (!addrcmp(&blanket->address, &next->address)) {
-			kill(blanket->pid, SIGTERM);
+			kill(blanket->cld.pid, SIGTERM);
 			break;
 		}
 }
@@ -640,19 +627,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;
 }
 
+char **cld_argv;
 static void handle(int incoming, struct sockaddr *addr, int addrlen)
 {
-	int fd[2];
-	pid_t pid;
+	struct child_process cld = { 0 };
 
 	if (max_connections && live_children >= max_connections) {
 		kill_some_child();
@@ -665,20 +659,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);
 
-	fd[0] = incoming;
-	fd[1] = dup(incoming);
-	exit(execute(fd, addr));
+	if (start_command(&cld))
+		logerror("unable to fork");
+	else
+		add_child(&cld, addr, addrlen);
+	close(incoming);
 }
 
 static void child_handler(int signo)
@@ -934,7 +923,7 @@ int main(int argc, char **argv)
 {
 	int listen_port = 0;
 	char *listen_addr = NULL;
-	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;
@@ -960,7 +949,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;
@@ -1104,13 +1098,13 @@ 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) {
 		int fd[2] = { 0, 1 };
 		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))
@@ -1129,5 +1123,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.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 10/14] daemon: use full buffered mode for stderr
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (8 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 09/14] daemon: use run-command api for async serving Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 11/14] mingw: compile git-daemon Erik Faye-Lund
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

Windows doesn't support line buffered mode for file
streams, so let's just use full buffered mode with
a big buffer ("4096 should be enough for everyone")
and add explicit flushing.

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

diff --git a/daemon.c b/daemon.c
index 2d63cbc..fc2c150 100644
--- a/daemon.c
+++ b/daemon.c
@@ -66,12 +66,14 @@ static void logreport(int priority, const char *err, va_list params)
 		syslog(priority, "%s", buf);
 	} else {
 		/*
-		 * Since stderr is set to linebuffered mode, the
+		 * Since stderr is set to buffered mode, the
 		 * logging of different processes will not overlap
+		 * unless they overflow the (rather big) buffers.
 		 */
 		fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid());
 		vfprintf(stderr, err, params);
 		fputc('\n', stderr);
+		fflush(stderr);
 	}
 }
 
@@ -1062,7 +1064,7 @@ int main(int argc, char **argv)
 		set_die_routine(daemon_die);
 	} else
 		/* avoid splitting a message in the middle */
-		setvbuf(stderr, NULL, _IOLBF, 0);
+		setvbuf(stderr, NULL, _IOFBF, 4096);
 
 	if (inetd_mode && (group_name || user_name))
 		die("--user and --group are incompatible with --inetd");
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 11/14] mingw: compile git-daemon
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (9 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 10/14] daemon: use full buffered mode for stderr Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 12/14] Improve the mingw getaddrinfo stub to handle more use cases Erik Faye-Lund
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

--user and --detach are disabled on Windows due to lack of
fork(), setuid(), setgid(), setsid() and initgroups().

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 Makefile       |    8 +++-----
 compat/mingw.h |    1 +
 daemon.c       |   19 ++++++++++++++-----
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index d81b392..cb6c36d 100644
--- a/Makefile
+++ b/Makefile
@@ -390,6 +390,7 @@ EXTRA_PROGRAMS =
 
 # ... and all the rest that could be moved out of bindir to gitexecdir
 PROGRAMS += $(EXTRA_PROGRAMS)
+PROGRAMS += git-daemon$X
 PROGRAMS += git-fast-import$X
 PROGRAMS += git-hash-object$X
 PROGRAMS += git-imap-send$X
@@ -986,7 +987,6 @@ ifeq ($(uname_S),Windows)
 	NO_SVN_TESTS = YesPlease
 	NO_PERL_MAKEMAKER = YesPlease
 	RUNTIME_PREFIX = YesPlease
-	NO_POSIX_ONLY_PROGRAMS = YesPlease
 	NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
 	NO_NSEC = YesPlease
 	USE_WIN32_MMAP = YesPlease
@@ -1037,7 +1037,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_SVN_TESTS = YesPlease
 	NO_PERL_MAKEMAKER = YesPlease
 	RUNTIME_PREFIX = YesPlease
-	NO_POSIX_ONLY_PROGRAMS = YesPlease
 	NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
 	NO_NSEC = YesPlease
 	USE_WIN32_MMAP = YesPlease
@@ -1047,6 +1046,8 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_REGEX = YesPlease
 	BLK_SHA1 = YesPlease
 	NO_PYTHON = YesPlease
+	NO_INET_PTON = YesPlease
+	NO_INET_NTOP = YesPlease
 	COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch
 	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
 	COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o
@@ -1141,9 +1142,6 @@ ifdef ZLIB_PATH
 endif
 EXTLIBS += -lz
 
-ifndef NO_POSIX_ONLY_PROGRAMS
-	PROGRAMS += git-daemon$X
-endif
 ifndef NO_OPENSSL
 	OPENSSL_LIBSSL = -lssl
 	ifdef OPENSSLDIR
diff --git a/compat/mingw.h b/compat/mingw.h
index e72c2ee..173bec5 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -7,6 +7,7 @@
 
 typedef int pid_t;
 typedef int socklen_t;
+typedef unsigned int gid_t;
 #define hstrerror strerror
 
 #define S_IFLNK    0120000 /* Symbolic link */
diff --git a/daemon.c b/daemon.c
index fc2c150..cdf5c72 100644
--- a/daemon.c
+++ b/daemon.c
@@ -589,7 +589,7 @@ static struct child {
 	struct sockaddr_storage address;
 } *firstborn;
 
-static void add_child(struct child_process *cld, struct sockaddr *addr, int addrlen)
+static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen)
 {
 	struct child *newborn, **cradle;
 
@@ -646,7 +646,7 @@ static void check_dead_children(void)
 }
 
 char **cld_argv;
-static void handle(int incoming, struct sockaddr *addr, int addrlen)
+static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
 {
 	struct child_process cld = { 0 };
 
@@ -847,7 +847,7 @@ static int service_loop(int socknum, int *socklist)
 		for (i = 0; i < socknum; i++) {
 			if (pfd[i].revents & POLLIN) {
 				struct sockaddr_storage ss;
-				unsigned int sslen = sizeof(ss);
+				socklen_t sslen = sizeof(ss);
 				int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
 				if (incoming < 0) {
 					switch (errno) {
@@ -879,6 +879,7 @@ static void sanitize_stdfds(void)
 
 static void daemonize(void)
 {
+#ifndef WIN32
 	switch (fork()) {
 		case 0:
 			break;
@@ -893,6 +894,9 @@ static void daemonize(void)
 	close(1);
 	close(2);
 	sanitize_stdfds();
+#else
+	die("--detach is not supported on Windows");
+#endif
 }
 
 static void store_pid(const char *path)
@@ -913,10 +917,12 @@ static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t
 		die("unable to allocate any listen sockets on host %s port %u",
 		    listen_addr, listen_port);
 
+#ifndef WIN32
 	if (pass && gid &&
 	    (initgroups(pass->pw_name, gid) || setgid (gid) ||
 	     setuid(pass->pw_uid)))
 		die("cannot drop privileges");
+#endif
 
 	return service_loop(socknum, socklist);
 }
@@ -929,7 +935,6 @@ int main(int argc, char **argv)
 	const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
 	int detach = 0;
 	struct passwd *pass = NULL;
-	struct group *group;
 	gid_t gid = 0;
 	int i;
 
@@ -1078,6 +1083,7 @@ int main(int argc, char **argv)
 		die("--group supplied without --user");
 
 	if (user_name) {
+#ifndef WIN32
 		pass = getpwnam(user_name);
 		if (!pass)
 			die("user not found - %s", user_name);
@@ -1085,12 +1091,15 @@ int main(int argc, char **argv)
 		if (!group_name)
 			gid = pass->pw_gid;
 		else {
-			group = getgrnam(group_name);
+			struct group *group = getgrnam(group_name);
 			if (!group)
 				die("group not found - %s", group_name);
 
 			gid = group->gr_gid;
 		}
+#else
+		die("--user is not supported on Windows");
+#endif
 	}
 
 	if (strict_paths && (!ok_paths || !*ok_paths))
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 12/14] Improve the mingw getaddrinfo stub to  handle more use cases
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (10 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 11/14] mingw: compile git-daemon Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 21:30 ` [PATCH v2 13/14] daemon: use select() instead of poll() Erik Faye-Lund
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Martin Storsjö

From: Martin Storsjö <martin@martin.st>

Allow the node parameter to be null, which is used for getting
the default bind address.

Also allow the hints parameter to be null, to improve standard
conformance of the stub implementation a little.

Signed-off-by: Martin Storsjo <martin@martin.st>
---
 compat/mingw.c |   28 +++++++++++++++++++++-------
 1 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index 89b9b89..02d411a 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -932,19 +932,22 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service,
 				   const struct addrinfo *hints,
 				   struct addrinfo **res)
 {
-	struct hostent *h = gethostbyname(node);
+	struct hostent *h = NULL;
 	struct addrinfo *ai;
 	struct sockaddr_in *sin;
 
-	if (!h)
-		return WSAGetLastError();
+	if (node) {
+		h = gethostbyname(node);
+		if (!h)
+			return WSAGetLastError();
+	}
 
 	ai = xmalloc(sizeof(struct addrinfo));
 	*res = ai;
 	ai->ai_flags = 0;
 	ai->ai_family = AF_INET;
-	ai->ai_socktype = hints->ai_socktype;
-	switch (hints->ai_socktype) {
+	ai->ai_socktype = hints ? hints->ai_socktype : 0;
+	switch (ai->ai_socktype) {
 	case SOCK_STREAM:
 		ai->ai_protocol = IPPROTO_TCP;
 		break;
@@ -956,14 +959,25 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service,
 		break;
 	}
 	ai->ai_addrlen = sizeof(struct sockaddr_in);
-	ai->ai_canonname = strdup(h->h_name);
+	if (hints && (hints->ai_flags & AI_CANONNAME))
+		ai->ai_canonname = h ? strdup(h->h_name) : NULL;
+	else
+		ai->ai_canonname = NULL;
 
 	sin = xmalloc(ai->ai_addrlen);
 	memset(sin, 0, ai->ai_addrlen);
 	sin->sin_family = AF_INET;
+	/* Note: getaddrinfo is supposed to allow service to be a string,
+	 * which should be looked up using getservbyname. This is
+	 * currently not implemented */
 	if (service)
 		sin->sin_port = htons(atoi(service));
-	sin->sin_addr = *(struct in_addr *)h->h_addr;
+	if (h)
+		sin->sin_addr = *(struct in_addr *)h->h_addr;
+	else if (hints && (hints->ai_flags & AI_PASSIVE))
+		sin->sin_addr.s_addr = INADDR_ANY;
+	else
+		sin->sin_addr.s_addr = INADDR_LOOPBACK;
 	ai->ai_addr = (struct sockaddr *)sin;
 	ai->ai_next = 0;
 	return 0;
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (11 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 12/14] Improve the mingw getaddrinfo stub to handle more use cases Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:49   ` Johannes Sixt
  2010-01-15 21:30 ` [PATCH v2 14/14] daemon: report connection from root-process Erik Faye-Lund
  2010-01-15 22:27 ` [PATCH v2 00/14] daemon-win32 Johannes Sixt
  14 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

Windows doesn't have poll(), and the poll-emulation in
compat/mingw.c doesn't support checking multiple sockets.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---
 compat/mingw.h |    7 +++++++
 daemon.c       |   27 ++++++++++++---------------
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/compat/mingw.h b/compat/mingw.h
index 173bec5..e515726 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -269,6 +269,13 @@ int mingw_accept(int sockfd, struct sockaddr *sa, socklen_t *sz);
 int mingw_rename(const char*, const char*);
 #define rename mingw_rename
 
+#undef FD_SET
+#define FD_SET(fd, set) do { \
+	((fd_set*)(set))->fd_array[((fd_set *)(set))->fd_count++] = _get_osfhandle(fd); \
+	} while(0)
+#undef FD_ISSET
+#define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set *)(set))
+
 #if defined(USE_WIN32_MMAP) || defined(_MSC_VER)
 int mingw_getpagesize(void);
 #define getpagesize mingw_getpagesize
diff --git a/daemon.c b/daemon.c
index cdf5c72..95cf299 100644
--- a/daemon.c
+++ b/daemon.c
@@ -818,26 +818,23 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 
 static int service_loop(int socknum, int *socklist)
 {
-	struct pollfd *pfd;
-	int i;
-
-	pfd = xcalloc(socknum, sizeof(struct pollfd));
-
-	for (i = 0; i < socknum; i++) {
-		pfd[i].fd = socklist[i];
-		pfd[i].events = POLLIN;
-	}
-
 	signal(SIGCHLD, child_handler);
 
 	for (;;) {
-		int i;
+		int i, maxfd = 0;
+		fd_set fds;
 
 		check_dead_children();
 
-		if (poll(pfd, socknum, -1) < 0) {
+		FD_ZERO(&fds);
+		for (i = 0; i < socknum; i++) {
+			FD_SET(socklist[i], &fds);
+			maxfd = socklist[i] > maxfd ? socklist[i] : maxfd;
+		}
+
+		if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 0) {
 			if (errno != EINTR) {
-				logerror("Poll failed, resuming: %s",
+				logerror("select() failed, resuming: %s",
 				      strerror(errno));
 				sleep(1);
 			}
@@ -845,10 +842,10 @@ static int service_loop(int socknum, int *socklist)
 		}
 
 		for (i = 0; i < socknum; i++) {
-			if (pfd[i].revents & POLLIN) {
+			if (FD_ISSET(socklist[i], &fds)) {
 				struct sockaddr_storage ss;
 				socklen_t sslen = sizeof(ss);
-				int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
+				int incoming = accept(socklist[i], (struct sockaddr *)&ss, &sslen);
 				if (incoming < 0) {
 					switch (errno) {
 					case EAGAIN:
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* [PATCH v2 14/14] daemon: report connection from  root-process
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (12 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 13/14] daemon: use select() instead of poll() Erik Faye-Lund
@ 2010-01-15 21:30 ` Erik Faye-Lund
  2010-01-15 22:27 ` [PATCH v2 00/14] daemon-win32 Johannes Sixt
  14 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 21:30 UTC (permalink / raw)
  To: msysgit; +Cc: git, j6t, Erik Faye-Lund

Report incoming connections from the process that
accept() the connection instead of the handling
process.

This enables "Connection from"-reporting on
Windows, where getpeername(0, ...) consistently
fails.

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

diff --git a/daemon.c b/daemon.c
index 95cf299..3423ffa 100644
--- a/daemon.c
+++ b/daemon.c
@@ -493,33 +493,6 @@ static int execute(int fd[2], struct sockaddr *addr)
 	static char line[1000];
 	int pktlen, len, i;
 
-	if (addr) {
-		char addrbuf[256] = "";
-		int port = -1;
-
-		if (addr->sa_family == AF_INET) {
-			struct sockaddr_in *sin_addr = (void *) addr;
-			inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
-			port = ntohs(sin_addr->sin_port);
-#ifndef NO_IPV6
-		} else if (addr && addr->sa_family == AF_INET6) {
-			struct sockaddr_in6 *sin6_addr = (void *) addr;
-
-			char *buf = addrbuf;
-			*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
-			inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
-			strcat(buf, "]");
-
-			port = ntohs(sin6_addr->sin6_port);
-#endif
-		}
-		loginfo("Connection from %s:%d", addrbuf, port);
-		setenv("REMOTE_ADDR", addrbuf, 1);
-	}
-	else {
-		unsetenv("REMOTE_ADDR");
-	}
-
 	alarm(init_timeout ? init_timeout : timeout);
 	pktlen = packet_read_line(fd[0], line, sizeof(line));
 	alarm(0);
@@ -645,10 +618,35 @@ static void check_dead_children(void)
 			cradle = &blanket->next;
 }
 
+static char *get_addrstr(int *port, struct sockaddr *addr)
+{
+	static char addrbuf[256] = "";
+	if (addr->sa_family == AF_INET) {
+		struct sockaddr_in *sin_addr = (void *) addr;
+		inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
+		*port = ntohs(sin_addr->sin_port);
+#ifndef NO_IPV6
+	} else if (addr && addr->sa_family == AF_INET6) {
+		struct sockaddr_in6 *sin6_addr = (void *) addr;
+
+		char *buf = addrbuf;
+		*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
+		inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
+		strcat(buf, "]");
+
+		*port = ntohs(sin6_addr->sin6_port);
+#endif
+	}
+	return addrbuf;
+}
+
 char **cld_argv;
 static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
 {
 	struct child_process cld = { 0 };
+	char *addrstr, envbuf[300] = "REMOTE_ADDR=";
+	char *env[] = { envbuf, NULL };
+	int port = -1;
 
 	if (max_connections && live_children >= max_connections) {
 		kill_some_child();
@@ -661,14 +659,21 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
 		}
 	}
 
+	addrstr = get_addrstr(&port, addr);
+	strcat(envbuf, addrstr);
+
+	cld.env = (const char **)env;
 	cld.argv = (const char **)cld_argv;
 	cld.in = incoming;
 	cld.out = dup(incoming);
 
 	if (start_command(&cld))
 		logerror("unable to fork");
-	else
+	else {
+		loginfo("[%"PRIuMAX"] Connection from %s:%d",
+		    (uintmax_t)cld.pid, addrstr, port);
 		add_child(&cld, addr, addrlen);
+	}
 	close(incoming);
 }
 
@@ -1115,8 +1120,13 @@ int main(int argc, char **argv)
 		if (inetd_mode && !freopen("/dev/null", "w", stderr))
 			die_errno("failed to redirect stderr to /dev/null");
 
-		if (getpeername(0, peer, &slen))
-			peer = NULL;
+		if (!getpeername(0, peer, &slen)) {
+			int port = -1;
+			char *addrstr = get_addrstr(&port, peer);
+			setenv("REMOTE_ADDR", addrstr, 1);
+			loginfo("[%"PRIuMAX"] Connection from %s:%d",
+			    (uintmax_t)getpid(), addrstr, port);
+		}
 
 		return execute(fd, peer);
 	}
-- 
1.6.6.211.g26720

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 00/14] daemon-win32
  2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
                   ` (13 preceding siblings ...)
  2010-01-15 21:30 ` [PATCH v2 14/14] daemon: report connection from root-process Erik Faye-Lund
@ 2010-01-15 22:27 ` Johannes Sixt
  2010-01-15 22:51   ` Erik Faye-Lund
  14 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:27 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

A very nicely done series. Thank you very much!

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> Here's the long overdue v2 of my daemon-win32 attempt. A lot
> has happened since v1. Most importantly, I abandoned using
> the async API to replace fork(), and went for explicitly
> spawning child process that handle the connection.

IOW, you run git-daemon recursively in inetd mode (almost). Let's see what 
people say about this approach.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG
  2010-01-15 21:30 ` [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG Erik Faye-Lund
@ 2010-01-15 22:28   ` Johannes Sixt
  2010-01-16 21:57     ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:28 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>  static inline int waitpid(pid_t pid, int *status, unsigned options)
>  {
> +	if (pid > 0 && options & WNOHANG) {
> +		if (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)pid, 0))
> +			return 0;
> +		options &= ~WNOHANG;
> +	}
> +
>  	if (options == 0)
>  		return _cwait(status, pid, 0);
>  	errno = EINVAL;

With this change, and in particular the one in the next patch, this function 
grows too large to be 'static inline'.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-15 21:30 ` [PATCH v2 06/14] mingw: use real pid Erik Faye-Lund
@ 2010-01-15 22:30   ` Johannes Sixt
  2010-01-15 22:53     ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:30 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> @@ -729,7 +729,7 @@ static pid_t mingw_spawnve(const char *cmd, const char
> **argv, char **env, return -1;
>  	}
>  	CloseHandle(pi.hThread);
> -	return (pid_t)pi.hProcess;
> +	return (pid_t)pi.dwProcessId;
>  }

You are not using the pi.hProcess anymore, so you must close it.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 07/14] mingw: add kill emulation
  2010-01-15 21:30 ` [PATCH v2 07/14] mingw: add kill emulation Erik Faye-Lund
@ 2010-01-15 22:31   ` Johannes Sixt
  2010-01-16 21:56     ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:31 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> +int mingw_kill(pid_t pid, int sig)
> +{
> ...
> +		CloseHandle(h);
> +		errno = err_win_to_posix(GetLastError());

Set errno before CloseHandle() to get the correct error.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 08/14] daemon: use explicit file descriptor
  2010-01-15 21:30 ` [PATCH v2 08/14] daemon: use explicit file descriptor Erik Faye-Lund
@ 2010-01-15 22:36   ` Johannes Sixt
  2010-01-16 21:52     ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:36 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> This patch adds support to specify an explicit file
> descriotor for communication with the client, instead
> of using stdin/stdout.
>
> This will be useful for the Windows port, because it
> will use threads instead of fork() to serve multiple
> clients, making it impossible to reuse stdin/stdout.

This statement is a bit outdated.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 09/14] daemon: use run-command api for async serving
  2010-01-15 21:30 ` [PATCH v2 09/14] daemon: use run-command api for async serving Erik Faye-Lund
@ 2010-01-15 22:42   ` Johannes Sixt
  0 siblings, 0 replies; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:42 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> fork() is only available on POSIX, so to support git-daemon
> on Windows we have to use something else. Conveniently
> enough, we have an API for async operation already.

I had a huh?-moment when I read this statement. This patch does not use what 
we call 'async', but start_command().

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-15 21:30 ` [PATCH v2 13/14] daemon: use select() instead of poll() Erik Faye-Lund
@ 2010-01-15 22:49   ` Johannes Sixt
  2010-01-15 23:08     ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-15 22:49 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, Erik Faye-Lund

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> +#undef FD_SET
> +#define FD_SET(fd, set) do { \
> +	((fd_set*)(set))->fd_array[((fd_set *)(set))->fd_count++] =
> _get_osfhandle(fd); \ +	} while(0)
> +#undef FD_ISSET
> +#define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
> *)(set)) +

I'm worried about the internals that you have to use here. Isn't it possible 
save the original macro text and use it in the new definition, like (this is 
for exposition only):

#define ORIG_FD_SET(fd, set) FD_SET(fd, set)
#undef FD_SET
#define FD_SET(fd, set) ORIG_FD_SET(_get_osfhandle(fd), set)

Another approach would be to extend the poll emulation such that it uses 
select if all FDs to wait for are sockets, and I think this would be the case 
in this application.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 00/14] daemon-win32
  2010-01-15 22:27 ` [PATCH v2 00/14] daemon-win32 Johannes Sixt
@ 2010-01-15 22:51   ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 22:51 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Fri, Jan 15, 2010 at 11:27 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> A very nicely done series. Thank you very much!
>
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> Here's the long overdue v2 of my daemon-win32 attempt. A lot
>> has happened since v1. Most importantly, I abandoned using
>> the async API to replace fork(), and went for explicitly
>> spawning child process that handle the connection.
>
> IOW, you run git-daemon recursively in inetd mode (almost). Let's see what
> people say about this approach.
>
> -- Hannes
>

Yes. Or, a subset of the inetd-mode.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-15 22:30   ` Johannes Sixt
@ 2010-01-15 22:53     ` Erik Faye-Lund
  2010-01-16  8:03       ` Johannes Sixt
  0 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 22:53 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Fri, Jan 15, 2010 at 11:30 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> @@ -729,7 +729,7 @@ static pid_t mingw_spawnve(const char *cmd, const char
>> **argv, char **env, return -1;
>>       }
>>       CloseHandle(pi.hThread);
>> -     return (pid_t)pi.hProcess;
>> +     return (pid_t)pi.dwProcessId;
>>  }
>
> You are not using the pi.hProcess anymore, so you must close it.
>

No. If I do, the pid becomes invalid after the process is finished,
and waitpid won't work. I couldn't find anywhere were we actually were
closing the handle, even after it was finished. So I don't think we
leak any more than we already did (for non-daemon purposes).

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [msysGit] [PATCH v2 02/14] mingw: implement syslog
  2010-01-15 21:30 ` [PATCH v2 02/14] mingw: implement syslog Erik Faye-Lund
@ 2010-01-15 22:57   ` Janos Laube
  2010-01-15 23:01     ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Janos Laube @ 2010-01-15 22:57 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: msysgit, git, j6t, Mike Pape, Erik Faye-Lund

> +static HANDLE ms_eventlog;
> +
> +void openlog(const char *ident, int logopt, int facility)
> +{
> +       if (ms_eventlog)
> +               return;
> +       ms_eventlog = RegisterEventSourceA(NULL, ident);
> +}

maybe make ms_eventlog thread local?
for example:

static __thread HANDLE ms_eventlog;

this would break compilation with msvc tho.

janos

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [msysGit] [PATCH v2 02/14] mingw: implement syslog
  2010-01-15 22:57   ` [msysGit] " Janos Laube
@ 2010-01-15 23:01     ` Erik Faye-Lund
  2010-01-15 23:09       ` Janos Laube
  0 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 23:01 UTC (permalink / raw)
  To: Janos Laube; +Cc: msysgit, git, j6t, Mike Pape

On Fri, Jan 15, 2010 at 11:57 PM, Janos Laube <janos.dev@gmail.com> wrote:
>> +static HANDLE ms_eventlog;
>> +
>> +void openlog(const char *ident, int logopt, int facility)
>> +{
>> +       if (ms_eventlog)
>> +               return;
>> +       ms_eventlog = RegisterEventSourceA(NULL, ident);
>> +}
>
> maybe make ms_eventlog thread local?
> for example:
>
> static __thread HANDLE ms_eventlog;
>
> this would break compilation with msvc tho.
>
> janos
>

Since the code that use it isn't multi-threaded, I fail to see the
point. In fact even if it were, I'm not sure I see the big point...
especially since the "__thread"-keyword isn't used (AFAICT) at all in
the git source code so far.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-15 22:49   ` Johannes Sixt
@ 2010-01-15 23:08     ` Erik Faye-Lund
  2010-01-15 23:23       ` Erik Faye-Lund
  2010-01-16  8:08       ` Johannes Sixt
  0 siblings, 2 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 23:08 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Fri, Jan 15, 2010 at 11:49 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> +#undef FD_SET
>> +#define FD_SET(fd, set) do { \
>> +     ((fd_set*)(set))->fd_array[((fd_set *)(set))->fd_count++] =
>> _get_osfhandle(fd); \ +       } while(0)
>> +#undef FD_ISSET
>> +#define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
>> *)(set)) +
>
> I'm worried about the internals that you have to use here. Isn't it possible
> save the original macro text and use it in the new definition, like (this is
> for exposition only):
>
> #define ORIG_FD_SET(fd, set) FD_SET(fd, set)
> #undef FD_SET
> #define FD_SET(fd, set) ORIG_FD_SET(_get_osfhandle(fd), set)
>

Redefining it is indeed fishy - I guess I should also have noted that
I even stripped the code down slightly (compared to the original).

I'm no preprocessor wizard, but I'll give it a stab.

> Another approach would be to extend the poll emulation such that it uses
> select if all FDs to wait for are sockets, and I think this would be the case
> in this application.
>

The problem with that is differentiating between pipes and sockets.
GetFileType() returns FILE_TYPE_PIPE for sockets (ugh). I did find
some code in gnulib that used WSAEnumNetworkEvents() to differentiate
between them, but I find this quite hacky.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [msysGit] [PATCH v2 02/14] mingw: implement syslog
  2010-01-15 23:01     ` Erik Faye-Lund
@ 2010-01-15 23:09       ` Janos Laube
  0 siblings, 0 replies; 49+ messages in thread
From: Janos Laube @ 2010-01-15 23:09 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git, j6t, Mike Pape

> Since the code that use it isn't multi-threaded, I fail to see the
> point. In fact even if it were, I'm not sure I see the big point...
> especially since the "__thread"-keyword isn't used (AFAICT) at all in
> the git source code so far.

that's why i have put a question mark behind my sentence. it was just
an idea :-). it would allow different threads to be an own event
source. but yes, i wasn't sure how much git makes use of threads. if
it doesn't, it does not make much sense at the moment, indeed.

janos

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-15 23:08     ` Erik Faye-Lund
@ 2010-01-15 23:23       ` Erik Faye-Lund
  2010-01-16  8:06         ` Johannes Sixt
  2010-01-16  8:08       ` Johannes Sixt
  1 sibling, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-15 23:23 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 12:08 AM, Erik Faye-Lund
<kusmabite@googlemail.com> wrote:
> On Fri, Jan 15, 2010 at 11:49 PM, Johannes Sixt <j6t@kdbg.org> wrote:
>> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>>> +#undef FD_SET
>>> +#define FD_SET(fd, set) do { \
>>> +     ((fd_set*)(set))->fd_array[((fd_set *)(set))->fd_count++] =
>>> _get_osfhandle(fd); \ +       } while(0)
>>> +#undef FD_ISSET
>>> +#define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
>>> *)(set)) +
>>
>> I'm worried about the internals that you have to use here. Isn't it possible
>> save the original macro text and use it in the new definition, like (this is
>> for exposition only):
>>
>> #define ORIG_FD_SET(fd, set) FD_SET(fd, set)
>> #undef FD_SET
>> #define FD_SET(fd, set) ORIG_FD_SET(_get_osfhandle(fd), set)
>>
>
> Redefining it is indeed fishy - I guess I should also have noted that
> I even stripped the code down slightly (compared to the original).
>
> I'm no preprocessor wizard, but I'll give it a stab.
>

The following worked for me:

diff --git a/compat/mingw.h b/compat/mingw.h
index e515726..ea15967 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -269,10 +269,13 @@ int mingw_accept(int sockfd, struct sockaddr
*sa, socklen_t *sz);
 int mingw_rename(const char*, const char*);
 #define rename mingw_rename

+static inline void mingw_fd_set(int fd, fd_set *set)
+{
+	FD_SET(_get_osfhandle(fd), set);
+}
 #undef FD_SET
-#define FD_SET(fd, set) do { \
-	((fd_set*)(set))->fd_array[((fd_set *)(set))->fd_count++] =
_get_osfhandle(fd); \
-	} while(0)
+#define FD_SET(a,b) mingw_fd_set(a,b)
+
 #undef FD_ISSET
 #define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set *)(set))


-- 
Erik "kusma" Faye-Lund

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-15 22:53     ` Erik Faye-Lund
@ 2010-01-16  8:03       ` Johannes Sixt
  2010-01-16  9:12         ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-16  8:03 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> On Fri, Jan 15, 2010 at 11:30 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> > On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> >> @@ -729,7 +729,7 @@ static pid_t mingw_spawnve(const char *cmd, const
> >> char **argv, char **env, return -1;
> >>       }
> >>       CloseHandle(pi.hThread);
> >> -     return (pid_t)pi.hProcess;
> >> +     return (pid_t)pi.dwProcessId;
> >>  }
> >
> > You are not using the pi.hProcess anymore, so you must close it.
>
> No. If I do, the pid becomes invalid after the process is finished,
> and waitpid won't work. I couldn't find anywhere were we actually were
> closing the handle, even after it was finished. So I don't think we
> leak any more than we already did (for non-daemon purposes).

Previously, this handle was closed by _cwait() (it was the "pid"), so we 
didn't leak it.

I somehow thought that you need the process ID instead of the handle for 
TerminateProcess, but now I see that this is not the case (it takes the 
handle). So I don't see the point of this change anymore. You say the process 
handle "does not work consistently with getpid", but I don't know what you 
mean. Please explain.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-15 23:23       ` Erik Faye-Lund
@ 2010-01-16  8:06         ` Johannes Sixt
  2010-01-16  9:26           ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-16  8:06 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
> +static inline void mingw_fd_set(int fd, fd_set *set)
> +{
> +	FD_SET(_get_osfhandle(fd), set);
> +}
>  #undef FD_SET
> +#define FD_SET(a,b) mingw_fd_set(a,b)
> +
>  #undef FD_ISSET
>  #define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
> *)(set))

Ah, yes, how obvious ;) You are going to do the same with FD_ISSET as well, 
aren't you?

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-15 23:08     ` Erik Faye-Lund
  2010-01-15 23:23       ` Erik Faye-Lund
@ 2010-01-16  8:08       ` Johannes Sixt
  2010-01-16  9:14         ` Erik Faye-Lund
  1 sibling, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-16  8:08 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
> The problem with that is differentiating between pipes and sockets.
> GetFileType() returns FILE_TYPE_PIPE for sockets (ugh). I did find
> some code in gnulib that used WSAEnumNetworkEvents() to differentiate
> between them, but I find this quite hacky.

Wouldn't it be possible to call getsockopt(), and if it returns ENOTSOCK 
(WSAENOTSOCK), then it is a pipe?

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-16  8:03       ` Johannes Sixt
@ 2010-01-16  9:12         ` Erik Faye-Lund
  2010-01-18 22:33           ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16  9:12 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 9:03 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> On Fri, Jan 15, 2010 at 11:30 PM, Johannes Sixt <j6t@kdbg.org> wrote:
>> > On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> >> @@ -729,7 +729,7 @@ static pid_t mingw_spawnve(const char *cmd, const
>> >> char **argv, char **env, return -1;
>> >>       }
>> >>       CloseHandle(pi.hThread);
>> >> -     return (pid_t)pi.hProcess;
>> >> +     return (pid_t)pi.dwProcessId;
>> >>  }
>> >
>> > You are not using the pi.hProcess anymore, so you must close it.
>>
>> No. If I do, the pid becomes invalid after the process is finished,
>> and waitpid won't work. I couldn't find anywhere were we actually were
>> closing the handle, even after it was finished. So I don't think we
>> leak any more than we already did (for non-daemon purposes).
>
> Previously, this handle was closed by _cwait() (it was the "pid"), so we
> didn't leak it.

Oh, I see. My planned route with this (before I looked for where the
handle was closed), was to maintain some sort of list of each started
PID and their handle, and lookup in that list instead of using
OpenProcess. I guess that would solve the problem here, but it feels a
bit nasty. Not as nasty as introducing a leak, though.

>
> I somehow thought that you need the process ID instead of the handle for
> TerminateProcess, but now I see that this is not the case (it takes the
> handle). So I don't see the point of this change anymore. You say the process
> handle "does not work consistently with getpid", but I don't know what you
> mean. Please explain.

getpid() returns the real PID, and is used for prefixing each logged
message by git-daemon. However, the root process reports whenever a
new process is started or has terminated using the PID returned by
mingw_spawnve(), and this handle does not match up with the PID that
getpid() reports. Thus it becomes impossible to tell which reported
error belongs to which client.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16  8:08       ` Johannes Sixt
@ 2010-01-16  9:14         ` Erik Faye-Lund
  2010-01-16 10:44           ` Johannes Sixt
  0 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16  9:14 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 9:08 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
>> The problem with that is differentiating between pipes and sockets.
>> GetFileType() returns FILE_TYPE_PIPE for sockets (ugh). I did find
>> some code in gnulib that used WSAEnumNetworkEvents() to differentiate
>> between them, but I find this quite hacky.
>
> Wouldn't it be possible to call getsockopt(), and if it returns ENOTSOCK
> (WSAENOTSOCK), then it is a pipe?
>
> -- Hannes
>

I read reports that this didn't work in Wine. Not that I care that
much about Wine.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16  8:06         ` Johannes Sixt
@ 2010-01-16  9:26           ` Erik Faye-Lund
  2010-01-16 10:38             ` Johannes Sixt
  0 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16  9:26 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 9:06 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
>> +static inline void mingw_fd_set(int fd, fd_set *set)
>> +{
>> +     FD_SET(_get_osfhandle(fd), set);
>> +}
>>  #undef FD_SET
>> +#define FD_SET(a,b) mingw_fd_set(a,b)
>> +
>>  #undef FD_ISSET
>>  #define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
>> *)(set))
>
> Ah, yes, how obvious ;) You are going to do the same with FD_ISSET as well,
> aren't you?
>
> -- Hannes
>

Do I really need to? There's already a single function for that, with
no "ugly hidden internals" there; __WSAFDIsSet() is documented in
MSDN. I mean, Sure... I could... I just don't see the point.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16  9:26           ` Erik Faye-Lund
@ 2010-01-16 10:38             ` Johannes Sixt
  2010-01-16 11:05               ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-16 10:38 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
> On Sat, Jan 16, 2010 at 9:06 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> > On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
> >> +static inline void mingw_fd_set(int fd, fd_set *set)
> >> +{
> >> +     FD_SET(_get_osfhandle(fd), set);
> >> +}
> >>  #undef FD_SET
> >> +#define FD_SET(a,b) mingw_fd_set(a,b)
> >> +
> >>  #undef FD_ISSET
> >>  #define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
> >> *)(set))
> >
> > Ah, yes, how obvious ;) You are going to do the same with FD_ISSET as
> > well, aren't you?
>
> Do I really need to? There's already a single function for that, with
> no "ugly hidden internals" there; __WSAFDIsSet() is documented in
> MSDN. I mean, Sure... I could... I just don't see the point.

__WSAFDIsSet is "ugly hidden internals" and we should not rely on it when we 
can use the official FD_ISSET for our own FD_ISSET.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16  9:14         ` Erik Faye-Lund
@ 2010-01-16 10:44           ` Johannes Sixt
  2010-01-16 10:59             ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-16 10:44 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
> On Sat, Jan 16, 2010 at 9:08 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> > Wouldn't it be possible to call getsockopt(), and if it returns ENOTSOCK
> > (WSAENOTSOCK), then it is a pipe?
>
> I read reports that this didn't work in Wine. Not that I care that
> much about Wine.

What does it mean that "it does not work"? Is it that it does not return 
ENOTSOCK, so that we mistake pipes as sockets?

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16 10:44           ` Johannes Sixt
@ 2010-01-16 10:59             ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 10:59 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 11:44 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
>> On Sat, Jan 16, 2010 at 9:08 AM, Johannes Sixt <j6t@kdbg.org> wrote:
>> > Wouldn't it be possible to call getsockopt(), and if it returns ENOTSOCK
>> > (WSAENOTSOCK), then it is a pipe?
>>
>> I read reports that this didn't work in Wine. Not that I care that
>> much about Wine.
>
> What does it mean that "it does not work"? Is it that it does not return
> ENOTSOCK, so that we mistake pipes as sockets?
>
> -- Hannes
>

Yes, according to the gnulib sources[1], getsockopt returns 0 for pipes.

[1]: http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/poll.c;h=90d99d92dca5d7ce2f31097e4b8fc06a83aae245;hb=HEAD#l80


-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16 10:38             ` Johannes Sixt
@ 2010-01-16 11:05               ` Erik Faye-Lund
  2010-01-16 11:27                 ` Andreas Schwab
  2010-01-16 12:36                 ` Johannes Sixt
  0 siblings, 2 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 11:05 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 11:38 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
>> On Sat, Jan 16, 2010 at 9:06 AM, Johannes Sixt <j6t@kdbg.org> wrote:
>> > On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
>> >> +static inline void mingw_fd_set(int fd, fd_set *set)
>> >> +{
>> >> +     FD_SET(_get_osfhandle(fd), set);
>> >> +}
>> >>  #undef FD_SET
>> >> +#define FD_SET(a,b) mingw_fd_set(a,b)
>> >> +
>> >>  #undef FD_ISSET
>> >>  #define FD_ISSET(fd, set) __WSAFDIsSet(_get_osfhandle(fd), (fd_set
>> >> *)(set))
>> >
>> > Ah, yes, how obvious ;) You are going to do the same with FD_ISSET as
>> > well, aren't you?
>>
>> Do I really need to? There's already a single function for that, with
>> no "ugly hidden internals" there; __WSAFDIsSet() is documented in
>> MSDN. I mean, Sure... I could... I just don't see the point.
>
> __WSAFDIsSet is "ugly hidden internals" and we should not rely on it when we
> can use the official FD_ISSET for our own FD_ISSET.
>
> -- Hannes
>

...but __WSAFDIsSet() seems to be every bit as official on Windows as
FD_ISSET() (documented in msdn, without any notes not to use it), so I
still don't really see the point.

However, I don't personally care one way or the other, so just doing
it is probably less work than convincing you that I don't have to ;)

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16 11:05               ` Erik Faye-Lund
@ 2010-01-16 11:27                 ` Andreas Schwab
  2010-01-16 11:43                   ` Erik Faye-Lund
  2010-01-16 12:36                 ` Johannes Sixt
  1 sibling, 1 reply; 49+ messages in thread
From: Andreas Schwab @ 2010-01-16 11:27 UTC (permalink / raw)
  To: kusmabite; +Cc: Johannes Sixt, msysgit, git

Erik Faye-Lund <kusmabite@googlemail.com> writes:

> ...but __WSAFDIsSet() seems to be every bit as official on Windows as
> FD_ISSET() (documented in msdn, without any notes not to use it), so I
> still don't really see the point.

The fact that it starts with two underscores suggests that it is kinda
internal.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16 11:27                 ` Andreas Schwab
@ 2010-01-16 11:43                   ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 11:43 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Johannes Sixt, msysgit, git

(Note: I'll argue only for the sake for the argument here, I've
already pretty much decided to follow Hannes' suggestion)

On Sat, Jan 16, 2010 at 12:27 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> The fact that it starts with two underscores suggests that it is kinda
> internal.
>

But the fact that it is documented more than suggests that it isn't.
Not any more, anyhow. This is pretty much how winapi works. Internal
stuff isn't documented, once it's documented it isn't internal
anymore. In fact, winapi doesn't really deal with "internal" and
"external" functions, it deals with documented and undocumented. Some
documented functions/features have documented compatibility issues.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16 11:05               ` Erik Faye-Lund
  2010-01-16 11:27                 ` Andreas Schwab
@ 2010-01-16 12:36                 ` Johannes Sixt
  2010-01-16 21:31                   ` Erik Faye-Lund
  1 sibling, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-16 12:36 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
> ...but __WSAFDIsSet() seems to be every bit as official on Windows as
> FD_ISSET() (documented in msdn, without any notes not to use it), so I
> still don't really see the point.

I didn't know nor check whether it is documented, but assumed from the '__' 
that it must be internal. Being documented makes a big difference. I'm fine 
with either solution.

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 13/14] daemon: use select() instead of poll()
  2010-01-16 12:36                 ` Johannes Sixt
@ 2010-01-16 21:31                   ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 21:31 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 1:36 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Samstag, 16. Januar 2010, Erik Faye-Lund wrote:
>> ...but __WSAFDIsSet() seems to be every bit as official on Windows as
>> FD_ISSET() (documented in msdn, without any notes not to use it), so I
>> still don't really see the point.
>
> I didn't know nor check whether it is documented, but assumed from the '__'
> that it must be internal. Being documented makes a big difference. I'm fine
> with either solution.
>

OK, in that case, I'll leave it as it is. The current code is slightly
more tested (I've been using it for some weeks), and I'm slightly lazy
;)

But I'll update FD_SET...

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 08/14] daemon: use explicit file descriptor
  2010-01-15 22:36   ` Johannes Sixt
@ 2010-01-16 21:52     ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 21:52 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Fri, Jan 15, 2010 at 11:36 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> This patch adds support to specify an explicit file
>> descriotor for communication with the client, instead
>> of using stdin/stdout.
>>
>> This will be useful for the Windows port, because it
>> will use threads instead of fork() to serve multiple
>> clients, making it impossible to reuse stdin/stdout.
>
> This statement is a bit outdated.
>
> -- Hannes
>

Heh, yeah. I apparently missed that this patch isn't needed at all any more.

Thanks for noticing something was off :)

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 07/14] mingw: add kill emulation
  2010-01-15 22:31   ` Johannes Sixt
@ 2010-01-16 21:56     ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 21:56 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Fri, Jan 15, 2010 at 11:31 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> +int mingw_kill(pid_t pid, int sig)
>> +{
>> ...
>> +             CloseHandle(h);
>> +             errno = err_win_to_posix(GetLastError());
>
> Set errno before CloseHandle() to get the correct error.
>
> -- Hannes
>

Thanks for pointing that out. Corrected locally.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG
  2010-01-15 22:28   ` Johannes Sixt
@ 2010-01-16 21:57     ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-16 21:57 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Fri, Jan 15, 2010 at 11:28 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>>  static inline int waitpid(pid_t pid, int *status, unsigned options)
>>  {
>> +     if (pid > 0 && options & WNOHANG) {
>> +             if (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)pid, 0))
>> +                     return 0;
>> +             options &= ~WNOHANG;
>> +     }
>> +
>>       if (options == 0)
>>               return _cwait(status, pid, 0);
>>       errno = EINVAL;
>
> With this change, and in particular the one in the next patch, this function
> grows too large to be 'static inline'.
>
> -- Hannes
>

Fixed locally.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-16  9:12         ` Erik Faye-Lund
@ 2010-01-18 22:33           ` Erik Faye-Lund
  2010-01-19 18:19             ` Johannes Sixt
  0 siblings, 1 reply; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-18 22:33 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Sat, Jan 16, 2010 at 10:12 AM, Erik Faye-Lund
<kusmabite@googlemail.com> wrote:
> On Sat, Jan 16, 2010 at 9:03 AM, Johannes Sixt <j6t@kdbg.org> wrote:
>> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>>> On Fri, Jan 15, 2010 at 11:30 PM, Johannes Sixt <j6t@kdbg.org> wrote:
>>> > On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>>> >> @@ -729,7 +729,7 @@ static pid_t mingw_spawnve(const char *cmd, const
>>> >> char **argv, char **env, return -1;
>>> >>       }
>>> >>       CloseHandle(pi.hThread);
>>> >> -     return (pid_t)pi.hProcess;
>>> >> +     return (pid_t)pi.dwProcessId;
>>> >>  }
>>> >
>>> > You are not using the pi.hProcess anymore, so you must close it.
>>>
>>> No. If I do, the pid becomes invalid after the process is finished,
>>> and waitpid won't work. I couldn't find anywhere were we actually were
>>> closing the handle, even after it was finished. So I don't think we
>>> leak any more than we already did (for non-daemon purposes).
>>
>> Previously, this handle was closed by _cwait() (it was the "pid"), so we
>> didn't leak it.
>
> Oh, I see. My planned route with this (before I looked for where the
> handle was closed), was to maintain some sort of list of each started
> PID and their handle, and lookup in that list instead of using
> OpenProcess. I guess that would solve the problem here, but it feels a
> bit nasty. Not as nasty as introducing a leak, though.
>

What I had in mind was something along these lines:

diff --git a/compat/mingw.c b/compat/mingw.c
index e2821b3..71201d0 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -638,6 +638,13 @@ static int env_compare(const void *a, const void *b)
 	return strcasecmp(*ea, *eb);
 }

+struct pid_info {
+	pid_t pid;
+	HANDLE proc;
+};
+static struct pid_info *pinfo;
+static int num_pinfo;
+
 static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
 			   int prepend_cmd)
 {
@@ -729,6 +736,13 @@ static pid_t mingw_spawnve(const char *cmd, const
char **argv, char **env,
 		return -1;
 	}
 	CloseHandle(pi.hThread);
+
+	/* store process handle */
+	num_pinfo++;
+	pinfo = xrealloc(pinfo, sizeof(struct pid_info) * num_pinfo);
+	pinfo[num_pinfo - 1].pid = pi.dwProcessId;
+	pinfo[num_pinfo - 1].proc = pi.hProcess;
+
 	return (pid_t)pi.dwProcessId;
 }

@@ -1536,6 +1550,7 @@ int waitpid(pid_t pid, int *status, unsigned options)
 	}

 	if (options == 0) {
+		int i;
 		if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
 			CloseHandle(h);
 			return 0;
@@ -1544,6 +1559,19 @@ int waitpid(pid_t pid, int *status, unsigned options)
 		if (status)
 			GetExitCodeProcess(h, (LPDWORD)status);

+		for (i = 0; i < num_pinfo; ++i)
+			if (pinfo[i].pid == pid)
+				break;
+
+		if (i < num_pinfo) {
+			CloseHandle(pinfo[i].proc);
+			memmove(pinfo + i, pinfo + i + 1,
+			    sizeof(struct pid_info) * (num_pinfo - i - 1));
+			num_pinfo--;
+			pinfo = xrealloc(pinfo,
+			    sizeof(struct pid_info) * num_pinfo);
+		}
+
 		CloseHandle(h);
 		return pid;
 	}



-- 
Erik "kusma" Faye-Lund

^ permalink raw reply related	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-18 22:33           ` Erik Faye-Lund
@ 2010-01-19 18:19             ` Johannes Sixt
  2010-01-19 19:23               ` Erik Faye-Lund
  0 siblings, 1 reply; 49+ messages in thread
From: Johannes Sixt @ 2010-01-19 18:19 UTC (permalink / raw)
  To: kusmabite; +Cc: msysgit, git

On Montag, 18. Januar 2010, Erik Faye-Lund wrote:
> On Sat, Jan 16, 2010 at 10:12 AM, Erik Faye-Lund wrote:
> > On Sat, Jan 16, 2010 at 9:03 AM, Johannes Sixt <j6t@kdbg.org> wrote:
> >> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
> >>> No. If I do, the pid becomes invalid after the process is finished,
> >>> and waitpid won't work. I couldn't find anywhere were we actually were
> >>> closing the handle, even after it was finished. So I don't think we
> >>> leak any more than we already did (for non-daemon purposes).
> >>
> >> Previously, this handle was closed by _cwait() (it was the "pid"), so we
> >> didn't leak it.
> >
> > Oh, I see. My planned route with this (before I looked for where the
> > handle was closed), was to maintain some sort of list of each started
> > PID and their handle, and lookup in that list instead of using
> > OpenProcess. I guess that would solve the problem here, but it feels a
> > bit nasty. Not as nasty as introducing a leak, though.
>
> What I had in mind was something along these lines:

Given that that the process ID is the user-visible (and system-wide unique) 
identifier of a process, this looks like the only reasonable way to go. Your 
implementation looks good as well.

> +	/* store process handle */

	/*
	 * The process ID is the human-readable identifier of the process
	 * that we want to present in log and error messages. The handle
	 * is not useful for this purpose. But we cannot close it, either,
	 * because it is not possible to turn a process ID into a process
	 * handle after the process terminated.
	 * Keep the handle in a list for waitpid.
	 */

> +	num_pinfo++;
> +	pinfo = xrealloc(pinfo, sizeof(struct pid_info) * num_pinfo);
> +	pinfo[num_pinfo - 1].pid = pi.dwProcessId;
> +	pinfo[num_pinfo - 1].proc = pi.hProcess;
> +
>  	return (pid_t)pi.dwProcessId;

-- Hannes

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH v2 06/14] mingw: use real pid
  2010-01-19 18:19             ` Johannes Sixt
@ 2010-01-19 19:23               ` Erik Faye-Lund
  0 siblings, 0 replies; 49+ messages in thread
From: Erik Faye-Lund @ 2010-01-19 19:23 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: msysgit, git

On Tue, Jan 19, 2010 at 7:19 PM, Johannes Sixt <j6t@kdbg.org> wrote:
> On Montag, 18. Januar 2010, Erik Faye-Lund wrote:
>> On Sat, Jan 16, 2010 at 10:12 AM, Erik Faye-Lund wrote:
>> > On Sat, Jan 16, 2010 at 9:03 AM, Johannes Sixt <j6t@kdbg.org> wrote:
>> >> On Freitag, 15. Januar 2010, Erik Faye-Lund wrote:
>> >>> No. If I do, the pid becomes invalid after the process is finished,
>> >>> and waitpid won't work. I couldn't find anywhere were we actually were
>> >>> closing the handle, even after it was finished. So I don't think we
>> >>> leak any more than we already did (for non-daemon purposes).
>> >>
>> >> Previously, this handle was closed by _cwait() (it was the "pid"), so we
>> >> didn't leak it.
>> >
>> > Oh, I see. My planned route with this (before I looked for where the
>> > handle was closed), was to maintain some sort of list of each started
>> > PID and their handle, and lookup in that list instead of using
>> > OpenProcess. I guess that would solve the problem here, but it feels a
>> > bit nasty. Not as nasty as introducing a leak, though.
>>
>> What I had in mind was something along these lines:
>
> Given that that the process ID is the user-visible (and system-wide unique)
> identifier of a process, this looks like the only reasonable way to go. Your
> implementation looks good as well.
>
>> +     /* store process handle */
>
>        /*
>         * The process ID is the human-readable identifier of the process
>         * that we want to present in log and error messages. The handle
>         * is not useful for this purpose. But we cannot close it, either,
>         * because it is not possible to turn a process ID into a process
>         * handle after the process terminated.
>         * Keep the handle in a list for waitpid.
>         */
>

Much better, thanks.

-- 
Erik "kusma" Faye-Lund

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2010-01-19 19:23 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-15 21:30 [PATCH v2 00/14] daemon-win32 Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 01/14] mingw: add network-wrappers for daemon Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 02/14] mingw: implement syslog Erik Faye-Lund
2010-01-15 22:57   ` [msysGit] " Janos Laube
2010-01-15 23:01     ` Erik Faye-Lund
2010-01-15 23:09       ` Janos Laube
2010-01-15 21:30 ` [PATCH v2 03/14] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 04/14] inet_ntop: fix a couple of old-style decls Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 05/14] mingw: support waitpid with pid > 0 and WNOHANG Erik Faye-Lund
2010-01-15 22:28   ` Johannes Sixt
2010-01-16 21:57     ` Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 06/14] mingw: use real pid Erik Faye-Lund
2010-01-15 22:30   ` Johannes Sixt
2010-01-15 22:53     ` Erik Faye-Lund
2010-01-16  8:03       ` Johannes Sixt
2010-01-16  9:12         ` Erik Faye-Lund
2010-01-18 22:33           ` Erik Faye-Lund
2010-01-19 18:19             ` Johannes Sixt
2010-01-19 19:23               ` Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 07/14] mingw: add kill emulation Erik Faye-Lund
2010-01-15 22:31   ` Johannes Sixt
2010-01-16 21:56     ` Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 08/14] daemon: use explicit file descriptor Erik Faye-Lund
2010-01-15 22:36   ` Johannes Sixt
2010-01-16 21:52     ` Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 09/14] daemon: use run-command api for async serving Erik Faye-Lund
2010-01-15 22:42   ` Johannes Sixt
2010-01-15 21:30 ` [PATCH v2 10/14] daemon: use full buffered mode for stderr Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 11/14] mingw: compile git-daemon Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 12/14] Improve the mingw getaddrinfo stub to handle more use cases Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 13/14] daemon: use select() instead of poll() Erik Faye-Lund
2010-01-15 22:49   ` Johannes Sixt
2010-01-15 23:08     ` Erik Faye-Lund
2010-01-15 23:23       ` Erik Faye-Lund
2010-01-16  8:06         ` Johannes Sixt
2010-01-16  9:26           ` Erik Faye-Lund
2010-01-16 10:38             ` Johannes Sixt
2010-01-16 11:05               ` Erik Faye-Lund
2010-01-16 11:27                 ` Andreas Schwab
2010-01-16 11:43                   ` Erik Faye-Lund
2010-01-16 12:36                 ` Johannes Sixt
2010-01-16 21:31                   ` Erik Faye-Lund
2010-01-16  8:08       ` Johannes Sixt
2010-01-16  9:14         ` Erik Faye-Lund
2010-01-16 10:44           ` Johannes Sixt
2010-01-16 10:59             ` Erik Faye-Lund
2010-01-15 21:30 ` [PATCH v2 14/14] daemon: report connection from root-process Erik Faye-Lund
2010-01-15 22:27 ` [PATCH v2 00/14] daemon-win32 Johannes Sixt
2010-01-15 22:51   ` Erik Faye-Lund

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.