* [PATCH/RFC 00/11] daemon-win32 @ 2009-11-26 0:39 Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund 2009-11-26 0:43 ` [PATCH/RFC 00/11] daemon-win32 Erik Faye-Lund 0 siblings, 2 replies; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund This is my stab at cleaning up Mike Pape's patches for git-daemon on Windows for submission, plus some of my own. * Patch 1-4 originate from Mike Pape, but have been cleaned up quite a lot by me. I hope Mike won't hate me. Credit have been retained, as all important code here were written by Mike. The commit messages were written mostly by me. * Patch 5 is a trivial old-style function declaration fix. * Patch 6 introduces two new functions to the run-command API, kill_async() and is_async_alive(). * Patch 7-8 removes the stdin/stdout redirection for the service functions, as redirecting won't work for the threaded version. * Patch 9 converts the daemon-code to use the run-command API. This is the patch I expect to be the most controversial. * Patch 10 is about using line-buffered mode instead of full-buffered mode for stderr. * Patch 11 finally enables compilation of git-daemon on MinGW. Let the flames begin! Erik Faye-Lund (7): inet_ntop: fix a couple of old-style decls run-command: add kill_async() and is_async_alive() run-command: support input-fd daemon: use explicit file descriptor daemon: use run-command api for async serving daemon: use full buffered mode for stderr mingw: compile git-daemon Mike Pape (4): mingw: add network-wrappers for daemon strbuf: add non-variadic function strbuf_vaddf() mingw: implement syslog compat: add inet_pton and inet_ntop prototypes Makefile | 8 ++- compat/inet_ntop.c | 22 ++------ compat/inet_pton.c | 8 ++- compat/mingw.c | 111 +++++++++++++++++++++++++++++++++++++++++-- compat/mingw.h | 32 ++++++++++++ daemon.c | 134 ++++++++++++++++++++++++++-------------------------- git-compat-util.h | 9 ++++ run-command.c | 32 ++++++++++++- run-command.h | 2 + strbuf.c | 15 ++++-- strbuf.h | 1 + 11 files changed, 274 insertions(+), 100 deletions(-) ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH/RFC 01/11] mingw: add network-wrappers for daemon 2009-11-26 0:39 [PATCH/RFC 00/11] daemon-win32 Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() Erik Faye-Lund 2009-11-26 0:43 ` [PATCH/RFC 00/11] daemon-win32 Erik Faye-Lund 1 sibling, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- compat/mingw.h | 16 ++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 10d6796..458021b 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -983,23 +983,37 @@ char **make_augmented_environ(const char *const *vars) return env; } -/* this is the first function to call into WS_32; initialize it */ -#undef gethostbyname -struct hostent *mingw_gethostbyname(const char *host) +static void wsa_init(void) { + static int initialized = 0; WSADATA wsa; + if (initialized) + return; + if (WSAStartup(MAKEWORD(2,2), &wsa)) die("unable to initialize winsock subsystem, error %d", WSAGetLastError()); atexit((void(*)(void)) WSACleanup); + initialized = 1; +} + +/* this can be the first function to call into WS_32; initialize it */ +#undef gethostbyname +struct hostent *mingw_gethostbyname(const char *host) +{ + wsa_init(); return gethostbyname(host); } +/* this can be the first function to call into WS_32; initialize it */ int mingw_socket(int domain, int type, int protocol) { + SOCKET s; int sockfd; - SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0); + + wsa_init(); + s = WSASocket(domain, type, protocol, NULL, 0, 0); if (s == INVALID_SOCKET) { /* * WSAGetLastError() values are regular BSD error codes @@ -1029,6 +1043,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 1978f8a..f362f61 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -5,6 +5,7 @@ */ typedef int pid_t; +typedef int socklen_t; #define hstrerror strerror #define S_IFLNK 0120000 /* Symbolic link */ @@ -33,6 +34,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; @@ -182,6 +186,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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() 2009-11-26 0:39 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 03/11] mingw: implement syslog Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund From: Mike Pape <dotzenlabs@gmail.com> This patch adds strbuf_vaddf, which takes a va_list as input instead of the variadic input that strbuf_addf takes. This is useful for fowarding varargs to strbuf_addf. Signed-off-by: Mike Pape <dotzenlabs@gmail.com> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> --- strbuf.c | 15 +++++++++------ strbuf.h | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/strbuf.c b/strbuf.c index a6153dc..e1833fb 100644 --- a/strbuf.c +++ b/strbuf.c @@ -190,23 +190,18 @@ void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len) strbuf_setlen(sb, sb->len + len); } -void strbuf_addf(struct strbuf *sb, const char *fmt, ...) +void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap) { int len; - va_list ap; if (!strbuf_avail(sb)) strbuf_grow(sb, 64); - va_start(ap, fmt); len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); - va_end(ap); if (len < 0) die("your vsnprintf is broken"); if (len > strbuf_avail(sb)) { strbuf_grow(sb, len); - va_start(ap, fmt); len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); - va_end(ap); if (len > strbuf_avail(sb)) { die("this should not happen, your snprintf is broken"); } @@ -214,6 +209,14 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) strbuf_setlen(sb, sb->len + len); } +void strbuf_addf(struct strbuf *sb, const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + strbuf_vaddf(sb, fmt, va); + va_end(va); +} + void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context) { diff --git a/strbuf.h b/strbuf.h index d05e056..8686bcb 100644 --- a/strbuf.h +++ b/strbuf.h @@ -119,6 +119,7 @@ extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, __attribute__((format(printf,2,3))) extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); +extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap); extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); /* XXX: if read fails, any partial read is undone */ -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 03/11] mingw: implement syslog 2009-11-26 0:39 ` [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ compat/mingw.h | 15 +++++++++++++++ daemon.c | 2 -- git-compat-util.h | 1 + 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 458021b..68116ac 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1255,6 +1255,57 @@ 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, ...) { + struct strbuf msg; + va_list va; + WORD logtype; + + strbuf_init(&msg, 0); + va_start(va, fmt); + strbuf_vaddf(&msg, fmt, va); + va_end(va); + + 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, + (WORD)NULL, + (DWORD)NULL, + NULL, + 1, + 0, + (const char **)&msg.buf, + NULL); + + strbuf_release(&msg); +} + #undef signal sig_handler_t mingw_signal(int sig, sig_handler_t handler) { diff --git a/compat/mingw.h b/compat/mingw.h index f362f61..576b1a1 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -37,6 +37,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; @@ -157,6 +170,8 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out); int link(const char *oldpath, const char *newpath); int symlink(const char *oldpath, const char *newpath); int readlink(const char *path, char *buf, size_t bufsiz); +void openlog(const char *ident, int logopt, int facility); +void syslog(int priority, const char *fmt, ...); /* * replacements of existing functions diff --git a/daemon.c b/daemon.c index 1b5ada6..07d7356 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 ef60803..33a8e33 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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes 2009-11-26 0:39 ` [PATCH/RFC 03/11] mingw: implement syslog Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 70cee6d..3b01694 100644 --- a/Makefile +++ b/Makefile @@ -1227,9 +1227,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 33a8e33..27fa601 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -340,6 +340,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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls 2009-11-26 0:39 ` [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() 2009-11-26 0:39 ` [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 07/11] run-command: support input-fd Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund These functions will aid the Windows port of git-daemon. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> --- run-command.c | 27 +++++++++++++++++++++++++++ run-command.h | 2 ++ 2 files changed, 29 insertions(+), 0 deletions(-) diff --git a/run-command.c b/run-command.c index cf2d8f7..e5a0e06 100644 --- a/run-command.c +++ b/run-command.c @@ -373,6 +373,33 @@ int finish_async(struct async *async) return ret; } +int kill_async(struct async *async) +{ +#ifndef WIN32 + return kill(async->pid, SIGTERM); +#else + DWORD ret = 0; + if (!TerminateThread(async->tid, 0)) + ret = error("killing thread failed: %lu", GetLastError()); + else if (!GetExitCodeThread(async->tid, &ret)) + ret = error("cannot get thread exit code: %lu", GetLastError()); + return ret; +#endif +} + +int is_async_alive(struct async *async) +{ +#ifndef WIN32 + int dummy; + return waitpid(async->pid, &dummy, WNOHANG); +#else + int ret = WaitForSingleObject(async->tid, 0); + if (ret == WAIT_FAILED) + return error("checking thread state failed: %lu", GetLastError()); + return ret != WAIT_OBJECT_0; +#endif +} + int run_hook(const char *index_file, const char *name, ...) { struct child_process hook; diff --git a/run-command.h b/run-command.h index fb34209..955b0bd 100644 --- a/run-command.h +++ b/run-command.h @@ -80,5 +80,7 @@ struct async { int start_async(struct async *async); int finish_async(struct async *async); +int kill_async(struct async *async); +int is_async_alive(struct async *async); #endif -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 07/11] run-command: support input-fd 2009-11-26 0:39 ` [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 08/11] daemon: use explicit file descriptor Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund This patch adds the possibility to supply a non-0 file descriptor for communucation, instead of the default-created pipe. The pipe gets duplicated, so the caller can free it's handles. This is usefull for async communication over sockets. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> --- run-command.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/run-command.c b/run-command.c index e5a0e06..98771ef 100644 --- a/run-command.c +++ b/run-command.c @@ -327,7 +327,10 @@ int start_async(struct async *async) { int pipe_out[2]; - if (pipe(pipe_out) < 0) + if (async->out) { + pipe_out[0] = dup(async->out); + pipe_out[1] = dup(async->out); + } else if (pipe(pipe_out) < 0) return error("cannot create pipe: %s", strerror(errno)); async->out = pipe_out[0]; -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 08/11] daemon: use explicit file descriptor 2009-11-26 0:39 ` [PATCH/RFC 07/11] run-command: support input-fd Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 09/11] daemon: use run-command api for async serving Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 34 ++++++++++++++++------------------ 1 files changed, 16 insertions(+), 18 deletions(-) diff --git a/daemon.c b/daemon.c index 07d7356..a0aead5 100644 --- a/daemon.c +++ b/daemon.c @@ -263,7 +263,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); struct daemon_service { const char *name; const char *config_name; @@ -287,7 +287,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, char *dir, struct daemon_service *service) { const char *path; int enabled = service->enabled; @@ -340,7 +340,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) @@ -364,7 +364,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, const char **argv) { struct child_process cld; @@ -372,37 +372,35 @@ static int run_service_command(const char **argv) cld.argv = argv; cld.git_cmd = 1; cld.err = -1; + cld.in = cld.out = fd; 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) { /* 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) { 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) { static const char *argv[] = { "receive-pack", ".", NULL }; - return run_service_command(argv); + return run_service_command(fd, argv); } static struct daemon_service daemon_service[] = { @@ -532,7 +530,7 @@ static void parse_host_arg(char *extra_args, int buflen) } -static int execute(struct sockaddr *addr) +static int execute(int fd, struct sockaddr *addr) { static char line[1000]; int pktlen, len, i; @@ -565,7 +563,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, line, sizeof(line)); alarm(0); len = strlen(line); @@ -597,7 +595,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); } } @@ -713,7 +711,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen) dup2(incoming, 1); close(incoming); - exit(execute(addr)); + exit(execute(0, addr)); } static void child_handler(int signo) @@ -1150,7 +1148,7 @@ int main(int argc, char **argv) if (getpeername(0, peer, &slen)) peer = NULL; - return execute(peer); + return execute(0, peer); } if (detach) { -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 09/11] daemon: use run-command api for async serving 2009-11-26 0:39 ` [PATCH/RFC 08/11] daemon: use explicit file descriptor Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 10/11] daemon: use full buffered mode for stderr Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 79 ++++++++++++++++++++++++++++--------------------------------- 1 files changed, 36 insertions(+), 43 deletions(-) diff --git a/daemon.c b/daemon.c index a0aead5..1b0e290 100644 --- a/daemon.c +++ b/daemon.c @@ -372,7 +372,8 @@ static int run_service_command(int fd, const char **argv) cld.argv = argv; cld.git_cmd = 1; cld.err = -1; - cld.in = cld.out = fd; + cld.in = dup(fd); + cld.out = fd; if (start_command(&cld)) return -1; @@ -609,11 +610,11 @@ static unsigned int live_children; static struct child { struct child *next; - pid_t pid; + struct async async; struct sockaddr_storage address; } *firstborn; -static void add_child(pid_t pid, struct sockaddr *addr, int addrlen) +static void add_child(struct async *async, struct sockaddr *addr, int addrlen) { struct child *newborn, **cradle; @@ -623,7 +624,7 @@ static void add_child(pid_t pid, struct sockaddr *addr, int addrlen) */ newborn = xcalloc(1, sizeof(*newborn)); live_children++; - newborn->pid = pid; + memcpy(&newborn->async, async, sizeof(struct async)); memcpy(&newborn->address, addr, addrlen); for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next) if (!memcmp(&(*cradle)->address, &newborn->address, @@ -633,19 +634,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". @@ -654,7 +642,7 @@ 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; @@ -662,28 +650,37 @@ static void kill_some_child(void) for (; (next = blanket->next); blanket = next) if (!memcmp(&blanket->address, &next->address, sizeof(next->address))) { - kill(blanket->pid, SIGTERM); + kill_async(&blanket->async); break; } } 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 (!is_async_alive(&blanket->async)) { + *cradle = blanket->next; + loginfo("Disconnected\n"); + live_children--; + close(blanket->async.out); + free(blanket); + } else + cradle = &blanket->next; +} + +int async_execute(int fd, void *data) +{ + int ret = execute(fd, data); + close(fd); + free(data); + return ret; } static void handle(int incoming, struct sockaddr *addr, int addrlen) { - pid_t pid; + struct sockaddr_storage *ss; + struct async async = { 0 }; if (max_connections && live_children >= max_connections) { kill_some_child(); @@ -696,22 +693,18 @@ 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; - } + ss = xmalloc(sizeof(*ss)); + memcpy(ss, addr, addrlen); - add_child(pid, addr, addrlen); - return; - } + async.proc = async_execute; + async.data = ss; + async.out = incoming; - dup2(incoming, 0); - dup2(incoming, 1); + if (start_async(&async)) + logerror("unable to fork"); + else + add_child(&async, addr, addrlen); close(incoming); - - exit(execute(0, addr)); } static void child_handler(int signo) -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 10/11] daemon: use full buffered mode for stderr 2009-11-26 0:39 ` [PATCH/RFC 09/11] daemon: use run-command api for async serving Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 11/11] mingw: compile git-daemon Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 1b0e290..130e951 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); } } @@ -1094,7 +1096,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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 11/11] mingw: compile git-daemon 2009-11-26 0:39 ` [PATCH/RFC 10/11] daemon: use full buffered mode for stderr Erik Faye-Lund @ 2009-11-26 0:39 ` Erik Faye-Lund 0 siblings, 0 replies; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:39 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 6 +++--- compat/mingw.h | 1 + daemon.c | 19 ++++++++++++++----- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 3b01694..406ca81 100644 --- a/Makefile +++ b/Makefile @@ -352,6 +352,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 @@ -981,6 +982,8 @@ ifneq (,$(findstring MINGW,$(uname_S))) OBJECT_CREATION_USES_RENAMES = UnfortunatelyNeedsTo NO_REGEX = YesPlease BLK_SHA1 = YesPlease + NO_INET_PTON = YesPlease + NO_INET_NTOP = YesPlease COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" # We have GCC, so let's make use of those nice options @@ -1079,9 +1082,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 576b1a1..1b0dd5b 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -6,6 +6,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 130e951..5872ec7 100644 --- a/daemon.c +++ b/daemon.c @@ -616,7 +616,7 @@ static struct child { struct sockaddr_storage address; } *firstborn; -static void add_child(struct async *async, struct sockaddr *addr, int addrlen) +static void add_child(struct async *async, struct sockaddr *addr, socklen_t addrlen) { struct child *newborn, **cradle; @@ -679,7 +679,7 @@ int async_execute(int fd, void *data) return ret; } -static void handle(int incoming, struct sockaddr *addr, int addrlen) +static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) { struct sockaddr_storage *ss; struct async async = { 0 }; @@ -884,7 +884,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) { @@ -916,6 +916,7 @@ static void sanitize_stdfds(void) static void daemonize(void) { +#ifndef WIN32 switch (fork()) { case 0: break; @@ -930,6 +931,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) @@ -950,10 +954,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); } @@ -966,7 +972,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; @@ -1110,6 +1115,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); @@ -1117,12 +1123,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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 00/11] daemon-win32 2009-11-26 0:39 [PATCH/RFC 00/11] daemon-win32 Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund @ 2009-11-26 0:43 ` Erik Faye-Lund 1 sibling, 0 replies; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:43 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund Awww, sorry people. I managed to send this one to the wrong msysgit-account. I'll repost, as I think it's important to get that list involved as well. On Thu, Nov 26, 2009 at 1:39 AM, Erik Faye-Lund <kusmabite@googlemail.com> wrote: > This is my stab at cleaning up Mike Pape's patches for git-daemon > on Windows for submission, plus some of my own. > > * Patch 1-4 originate from Mike Pape, but have been cleaned up quite > a lot by me. I hope Mike won't hate me. Credit have been retained, > as all important code here were written by Mike. The commit > messages were written mostly by me. > > * Patch 5 is a trivial old-style function declaration fix. > > * Patch 6 introduces two new functions to the run-command API, > kill_async() and is_async_alive(). > > * Patch 7-8 removes the stdin/stdout redirection for the service > functions, as redirecting won't work for the threaded version. > > * Patch 9 converts the daemon-code to use the run-command API. This > is the patch I expect to be the most controversial. > > * Patch 10 is about using line-buffered mode instead of full-buffered > mode for stderr. > > * Patch 11 finally enables compilation of git-daemon on MinGW. > > Let the flames begin! > > Erik Faye-Lund (7): > inet_ntop: fix a couple of old-style decls > run-command: add kill_async() and is_async_alive() > run-command: support input-fd > daemon: use explicit file descriptor > daemon: use run-command api for async serving > daemon: use full buffered mode for stderr > mingw: compile git-daemon > > Mike Pape (4): > mingw: add network-wrappers for daemon > strbuf: add non-variadic function strbuf_vaddf() > mingw: implement syslog > compat: add inet_pton and inet_ntop prototypes > > Makefile | 8 ++- > compat/inet_ntop.c | 22 ++------ > compat/inet_pton.c | 8 ++- > compat/mingw.c | 111 +++++++++++++++++++++++++++++++++++++++++-- > compat/mingw.h | 32 ++++++++++++ > daemon.c | 134 ++++++++++++++++++++++++++-------------------------- > git-compat-util.h | 9 ++++ > run-command.c | 32 ++++++++++++- > run-command.h | 2 + > strbuf.c | 15 ++++-- > strbuf.h | 1 + > 11 files changed, 274 insertions(+), 100 deletions(-) > > -- Erik "kusma" Faye-Lund ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH/RFC 00/11] daemon-win32 @ 2009-11-26 0:44 Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund 2009-11-27 20:59 ` [msysGit] " Johannes Sixt 0 siblings, 2 replies; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund This is my stab at cleaning up Mike Pape's patches for git-daemon on Windows for submission, plus some of my own. * Patch 1-4 originate from Mike Pape, but have been cleaned up quite a lot by me. I hope Mike won't hate me. Credit have been retained, as all important code here were written by Mike. The commit messages were written mostly by me. * Patch 5 is a trivial old-style function declaration fix. * Patch 6 introduces two new functions to the run-command API, kill_async() and is_async_alive(). * Patch 7-8 removes the stdin/stdout redirection for the service functions, as redirecting won't work for the threaded version. * Patch 9 converts the daemon-code to use the run-command API. This is the patch I expect to be the most controversial. * Patch 10 is about using line-buffered mode instead of full-buffered mode for stderr. * Patch 11 finally enables compilation of git-daemon on MinGW. Let the flames begin! Erik Faye-Lund (7): inet_ntop: fix a couple of old-style decls run-command: add kill_async() and is_async_alive() run-command: support input-fd daemon: use explicit file descriptor daemon: use run-command api for async serving daemon: use full buffered mode for stderr mingw: compile git-daemon Mike Pape (4): mingw: add network-wrappers for daemon strbuf: add non-variadic function strbuf_vaddf() mingw: implement syslog compat: add inet_pton and inet_ntop prototypes Makefile | 8 ++- compat/inet_ntop.c | 22 ++------ compat/inet_pton.c | 8 ++- compat/mingw.c | 111 +++++++++++++++++++++++++++++++++++++++++-- compat/mingw.h | 32 ++++++++++++ daemon.c | 134 ++++++++++++++++++++++++++-------------------------- git-compat-util.h | 9 ++++ run-command.c | 32 ++++++++++++- run-command.h | 2 + strbuf.c | 15 ++++-- strbuf.h | 1 + 11 files changed, 274 insertions(+), 100 deletions(-) ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH/RFC 01/11] mingw: add network-wrappers for daemon 2009-11-26 0:44 Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() Erik Faye-Lund 2009-11-27 20:59 ` [msysGit] " Johannes Sixt 1 sibling, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- compat/mingw.h | 16 ++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 10d6796..458021b 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -983,23 +983,37 @@ char **make_augmented_environ(const char *const *vars) return env; } -/* this is the first function to call into WS_32; initialize it */ -#undef gethostbyname -struct hostent *mingw_gethostbyname(const char *host) +static void wsa_init(void) { + static int initialized = 0; WSADATA wsa; + if (initialized) + return; + if (WSAStartup(MAKEWORD(2,2), &wsa)) die("unable to initialize winsock subsystem, error %d", WSAGetLastError()); atexit((void(*)(void)) WSACleanup); + initialized = 1; +} + +/* this can be the first function to call into WS_32; initialize it */ +#undef gethostbyname +struct hostent *mingw_gethostbyname(const char *host) +{ + wsa_init(); return gethostbyname(host); } +/* this can be the first function to call into WS_32; initialize it */ int mingw_socket(int domain, int type, int protocol) { + SOCKET s; int sockfd; - SOCKET s = WSASocket(domain, type, protocol, NULL, 0, 0); + + wsa_init(); + s = WSASocket(domain, type, protocol, NULL, 0, 0); if (s == INVALID_SOCKET) { /* * WSAGetLastError() values are regular BSD error codes @@ -1029,6 +1043,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 1978f8a..f362f61 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -5,6 +5,7 @@ */ typedef int pid_t; +typedef int socklen_t; #define hstrerror strerror #define S_IFLNK 0120000 /* Symbolic link */ @@ -33,6 +34,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; @@ -182,6 +186,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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() 2009-11-26 0:44 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 03/11] mingw: implement syslog Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund From: Mike Pape <dotzenlabs@gmail.com> This patch adds strbuf_vaddf, which takes a va_list as input instead of the variadic input that strbuf_addf takes. This is useful for fowarding varargs to strbuf_addf. Signed-off-by: Mike Pape <dotzenlabs@gmail.com> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> --- strbuf.c | 15 +++++++++------ strbuf.h | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/strbuf.c b/strbuf.c index a6153dc..e1833fb 100644 --- a/strbuf.c +++ b/strbuf.c @@ -190,23 +190,18 @@ void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len) strbuf_setlen(sb, sb->len + len); } -void strbuf_addf(struct strbuf *sb, const char *fmt, ...) +void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap) { int len; - va_list ap; if (!strbuf_avail(sb)) strbuf_grow(sb, 64); - va_start(ap, fmt); len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); - va_end(ap); if (len < 0) die("your vsnprintf is broken"); if (len > strbuf_avail(sb)) { strbuf_grow(sb, len); - va_start(ap, fmt); len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); - va_end(ap); if (len > strbuf_avail(sb)) { die("this should not happen, your snprintf is broken"); } @@ -214,6 +209,14 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) strbuf_setlen(sb, sb->len + len); } +void strbuf_addf(struct strbuf *sb, const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + strbuf_vaddf(sb, fmt, va); + va_end(va); +} + void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context) { diff --git a/strbuf.h b/strbuf.h index d05e056..8686bcb 100644 --- a/strbuf.h +++ b/strbuf.h @@ -119,6 +119,7 @@ extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, __attribute__((format(printf,2,3))) extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); +extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap); extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); /* XXX: if read fails, any partial read is undone */ -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 03/11] mingw: implement syslog 2009-11-26 0:44 ` [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ compat/mingw.h | 15 +++++++++++++++ daemon.c | 2 -- git-compat-util.h | 1 + 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 458021b..68116ac 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1255,6 +1255,57 @@ 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, ...) { + struct strbuf msg; + va_list va; + WORD logtype; + + strbuf_init(&msg, 0); + va_start(va, fmt); + strbuf_vaddf(&msg, fmt, va); + va_end(va); + + 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, + (WORD)NULL, + (DWORD)NULL, + NULL, + 1, + 0, + (const char **)&msg.buf, + NULL); + + strbuf_release(&msg); +} + #undef signal sig_handler_t mingw_signal(int sig, sig_handler_t handler) { diff --git a/compat/mingw.h b/compat/mingw.h index f362f61..576b1a1 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -37,6 +37,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; @@ -157,6 +170,8 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out); int link(const char *oldpath, const char *newpath); int symlink(const char *oldpath, const char *newpath); int readlink(const char *path, char *buf, size_t bufsiz); +void openlog(const char *ident, int logopt, int facility); +void syslog(int priority, const char *fmt, ...); /* * replacements of existing functions diff --git a/daemon.c b/daemon.c index 1b5ada6..07d7356 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 ef60803..33a8e33 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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes 2009-11-26 0:44 ` [PATCH/RFC 03/11] mingw: implement syslog Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 70cee6d..3b01694 100644 --- a/Makefile +++ b/Makefile @@ -1227,9 +1227,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 33a8e33..27fa601 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -340,6 +340,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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls 2009-11-26 0:44 ` [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() 2009-11-26 0:44 ` [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 07/11] run-command: support input-fd Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund These functions will aid the Windows port of git-daemon. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> --- run-command.c | 27 +++++++++++++++++++++++++++ run-command.h | 2 ++ 2 files changed, 29 insertions(+), 0 deletions(-) diff --git a/run-command.c b/run-command.c index cf2d8f7..e5a0e06 100644 --- a/run-command.c +++ b/run-command.c @@ -373,6 +373,33 @@ int finish_async(struct async *async) return ret; } +int kill_async(struct async *async) +{ +#ifndef WIN32 + return kill(async->pid, SIGTERM); +#else + DWORD ret = 0; + if (!TerminateThread(async->tid, 0)) + ret = error("killing thread failed: %lu", GetLastError()); + else if (!GetExitCodeThread(async->tid, &ret)) + ret = error("cannot get thread exit code: %lu", GetLastError()); + return ret; +#endif +} + +int is_async_alive(struct async *async) +{ +#ifndef WIN32 + int dummy; + return waitpid(async->pid, &dummy, WNOHANG); +#else + int ret = WaitForSingleObject(async->tid, 0); + if (ret == WAIT_FAILED) + return error("checking thread state failed: %lu", GetLastError()); + return ret != WAIT_OBJECT_0; +#endif +} + int run_hook(const char *index_file, const char *name, ...) { struct child_process hook; diff --git a/run-command.h b/run-command.h index fb34209..955b0bd 100644 --- a/run-command.h +++ b/run-command.h @@ -80,5 +80,7 @@ struct async { int start_async(struct async *async); int finish_async(struct async *async); +int kill_async(struct async *async); +int is_async_alive(struct async *async); #endif -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 07/11] run-command: support input-fd 2009-11-26 0:44 ` [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 08/11] daemon: use explicit file descriptor Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, Erik Faye-Lund This patch adds the possibility to supply a non-0 file descriptor for communucation, instead of the default-created pipe. The pipe gets duplicated, so the caller can free it's handles. This is usefull for async communication over sockets. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> --- run-command.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/run-command.c b/run-command.c index e5a0e06..98771ef 100644 --- a/run-command.c +++ b/run-command.c @@ -327,7 +327,10 @@ int start_async(struct async *async) { int pipe_out[2]; - if (pipe(pipe_out) < 0) + if (async->out) { + pipe_out[0] = dup(async->out); + pipe_out[1] = dup(async->out); + } else if (pipe(pipe_out) < 0) return error("cannot create pipe: %s", strerror(errno)); async->out = pipe_out[0]; -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 08/11] daemon: use explicit file descriptor 2009-11-26 0:44 ` [PATCH/RFC 07/11] run-command: support input-fd Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 09/11] daemon: use run-command api for async serving Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 34 ++++++++++++++++------------------ 1 files changed, 16 insertions(+), 18 deletions(-) diff --git a/daemon.c b/daemon.c index 07d7356..a0aead5 100644 --- a/daemon.c +++ b/daemon.c @@ -263,7 +263,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); struct daemon_service { const char *name; const char *config_name; @@ -287,7 +287,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, char *dir, struct daemon_service *service) { const char *path; int enabled = service->enabled; @@ -340,7 +340,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) @@ -364,7 +364,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, const char **argv) { struct child_process cld; @@ -372,37 +372,35 @@ static int run_service_command(const char **argv) cld.argv = argv; cld.git_cmd = 1; cld.err = -1; + cld.in = cld.out = fd; 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) { /* 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) { 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) { static const char *argv[] = { "receive-pack", ".", NULL }; - return run_service_command(argv); + return run_service_command(fd, argv); } static struct daemon_service daemon_service[] = { @@ -532,7 +530,7 @@ static void parse_host_arg(char *extra_args, int buflen) } -static int execute(struct sockaddr *addr) +static int execute(int fd, struct sockaddr *addr) { static char line[1000]; int pktlen, len, i; @@ -565,7 +563,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, line, sizeof(line)); alarm(0); len = strlen(line); @@ -597,7 +595,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); } } @@ -713,7 +711,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen) dup2(incoming, 1); close(incoming); - exit(execute(addr)); + exit(execute(0, addr)); } static void child_handler(int signo) @@ -1150,7 +1148,7 @@ int main(int argc, char **argv) if (getpeername(0, peer, &slen)) peer = NULL; - return execute(peer); + return execute(0, peer); } if (detach) { -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH/RFC 09/11] daemon: use run-command api for async serving 2009-11-26 0:44 ` [PATCH/RFC 08/11] daemon: use explicit file descriptor Erik Faye-Lund @ 2009-11-26 0:44 ` Erik Faye-Lund 0 siblings, 0 replies; 15+ messages in thread From: Erik Faye-Lund @ 2009-11-26 0:44 UTC (permalink / raw) To: msysgit; +Cc: git, dotzenlabs, 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 | 79 ++++++++++++++++++++++++++++--------------------------------- 1 files changed, 36 insertions(+), 43 deletions(-) diff --git a/daemon.c b/daemon.c index a0aead5..1b0e290 100644 --- a/daemon.c +++ b/daemon.c @@ -372,7 +372,8 @@ static int run_service_command(int fd, const char **argv) cld.argv = argv; cld.git_cmd = 1; cld.err = -1; - cld.in = cld.out = fd; + cld.in = dup(fd); + cld.out = fd; if (start_command(&cld)) return -1; @@ -609,11 +610,11 @@ static unsigned int live_children; static struct child { struct child *next; - pid_t pid; + struct async async; struct sockaddr_storage address; } *firstborn; -static void add_child(pid_t pid, struct sockaddr *addr, int addrlen) +static void add_child(struct async *async, struct sockaddr *addr, int addrlen) { struct child *newborn, **cradle; @@ -623,7 +624,7 @@ static void add_child(pid_t pid, struct sockaddr *addr, int addrlen) */ newborn = xcalloc(1, sizeof(*newborn)); live_children++; - newborn->pid = pid; + memcpy(&newborn->async, async, sizeof(struct async)); memcpy(&newborn->address, addr, addrlen); for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next) if (!memcmp(&(*cradle)->address, &newborn->address, @@ -633,19 +634,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". @@ -654,7 +642,7 @@ 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; @@ -662,28 +650,37 @@ static void kill_some_child(void) for (; (next = blanket->next); blanket = next) if (!memcmp(&blanket->address, &next->address, sizeof(next->address))) { - kill(blanket->pid, SIGTERM); + kill_async(&blanket->async); break; } } 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 (!is_async_alive(&blanket->async)) { + *cradle = blanket->next; + loginfo("Disconnected\n"); + live_children--; + close(blanket->async.out); + free(blanket); + } else + cradle = &blanket->next; +} + +int async_execute(int fd, void *data) +{ + int ret = execute(fd, data); + close(fd); + free(data); + return ret; } static void handle(int incoming, struct sockaddr *addr, int addrlen) { - pid_t pid; + struct sockaddr_storage *ss; + struct async async = { 0 }; if (max_connections && live_children >= max_connections) { kill_some_child(); @@ -696,22 +693,18 @@ 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; - } + ss = xmalloc(sizeof(*ss)); + memcpy(ss, addr, addrlen); - add_child(pid, addr, addrlen); - return; - } + async.proc = async_execute; + async.data = ss; + async.out = incoming; - dup2(incoming, 0); - dup2(incoming, 1); + if (start_async(&async)) + logerror("unable to fork"); + else + add_child(&async, addr, addrlen); close(incoming); - - exit(execute(0, addr)); } static void child_handler(int signo) -- 1.6.5.rc2.7.g4f8d3 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [msysGit] [PATCH/RFC 09/11] daemon: use run-command api for async serving 2009-11-26 0:44 ` [PATCH/RFC 09/11] daemon: use run-command api for async serving Erik Faye-Lund (?) @ 2009-11-27 20:59 ` Johannes Sixt 2009-12-02 15:45 ` Erik Faye-Lund -1 siblings, 1 reply; 15+ messages in thread From: Johannes Sixt @ 2009-11-27 20:59 UTC (permalink / raw) To: msysgit; +Cc: Erik Faye-Lund, git, dotzenlabs, Erik Faye-Lund On Donnerstag, 26. November 2009, Erik Faye-Lund wrote: > 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 (!is_async_alive(&blanket->async)) { This would be the right place to call finish_async(). But since we cannot wait, you invented is_async_alive(). But actually we are not only interested in whether the process is alive, but also whether it completed successfully so that we can add "(with error)". Would it make sense to have a function finish_async_nowait() instead of is_async_alive() that (1) stresses the start/finish symmetry and (2) can return more than just Boolean? > + *cradle = blanket->next; > + loginfo("Disconnected\n"); Here you are losing information about the pid, which is important to have in the syslog. The \n should be dropped. > + async.proc = async_execute; > + async.data = ss; > + async.out = incoming; > > - dup2(incoming, 0); > - dup2(incoming, 1); > + if (start_async(&async)) > + logerror("unable to fork"); > + else > + add_child(&async, addr, addrlen); > close(incoming); > - > - exit(execute(0, addr)); In start_command(), the convention is that fds that are provided by the caller are closed by start_command() (even if there are errors). The close(incoming) that you leave here indicates that you are not using the same convention with start_async(). It would be nice to switch to the same convention. -- Hannes ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [msysGit] [PATCH/RFC 09/11] daemon: use run-command api for async serving 2009-11-27 20:59 ` [msysGit] " Johannes Sixt @ 2009-12-02 15:45 ` Erik Faye-Lund 2009-12-02 19:12 ` Johannes Sixt 0 siblings, 1 reply; 15+ messages in thread From: Erik Faye-Lund @ 2009-12-02 15:45 UTC (permalink / raw) To: Johannes Sixt; +Cc: msysgit, git, dotzenlabs On Fri, Nov 27, 2009 at 9:59 PM, Johannes Sixt <j6t@kdbg.org> wrote: > On Donnerstag, 26. November 2009, Erik Faye-Lund wrote: >> 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 (!is_async_alive(&blanket->async)) { > > This would be the right place to call finish_async(). But since we cannot > wait, you invented is_async_alive(). But actually we are not only interested > in whether the process is alive, but also whether it completed successfully > so that we can add "(with error)". Would it make sense to have a function > finish_async_nowait() instead of is_async_alive() that (1) stresses the > start/finish symmetry and (2) can return more than just Boolean? > Yes, it does. >> + *cradle = blanket->next; >> + loginfo("Disconnected\n"); > > Here you are losing information about the pid, which is important to have in > the syslog. The \n should be dropped. > Yeah... I removed the pid mostly because after moving to async, there wasn't "just a pid" any more. But if we make finish_async_nowait() return whatever we need to report, I guess we can add the information back somehow. I'm not entirely sure how to make the interface, though. Any good suggestions? >> + async.proc = async_execute; >> + async.data = ss; >> + async.out = incoming; >> >> - dup2(incoming, 0); >> - dup2(incoming, 1); >> + if (start_async(&async)) >> + logerror("unable to fork"); >> + else >> + add_child(&async, addr, addrlen); >> close(incoming); >> - >> - exit(execute(0, addr)); > > In start_command(), the convention is that fds that are provided by the caller > are closed by start_command() (even if there are errors). The close(incoming) > that you leave here indicates that you are not using the same convention with > start_async(). It would be nice to switch to the same convention. > Yeah, I've fixed this for the next round. -- Erik "kusma" Faye-Lund ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [msysGit] [PATCH/RFC 09/11] daemon: use run-command api for async serving 2009-12-02 15:45 ` Erik Faye-Lund @ 2009-12-02 19:12 ` Johannes Sixt 2009-12-08 13:36 ` Erik Faye-Lund 0 siblings, 1 reply; 15+ messages in thread From: Johannes Sixt @ 2009-12-02 19:12 UTC (permalink / raw) To: kusmabite; +Cc: msysgit, git, dotzenlabs On Mittwoch, 2. Dezember 2009, Erik Faye-Lund wrote: > On Fri, Nov 27, 2009 at 9:59 PM, Johannes Sixt <j6t@kdbg.org> wrote: > > Would it make sense to > > have a function finish_async_nowait() instead of is_async_alive() that > > (1) stresses the start/finish symmetry and (2) can return more than just > > Boolean? >... > > I'm not entirely sure how to make the interface, though. Any good > suggestions? I suggest to model finish_async_nowait() after waitpid() so that while ((pid = waitpid(-1, &status, WNOHANG)) > 0) ... becomes while ((pid = finish_async_nowait(&some_async, &status)) > 0) ... but where the resulting status is already "decoded", i.e. zero is success and non-zero is failure (including death through signal); WIFEXITED and WEXITSTATUS should not be applicable to status anymore. -- Hannes ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH/RFC 09/11] daemon: use run-command api for async serving 2009-12-02 19:12 ` Johannes Sixt @ 2009-12-08 13:36 ` Erik Faye-Lund 0 siblings, 0 replies; 15+ messages in thread From: Erik Faye-Lund @ 2009-12-08 13:36 UTC (permalink / raw) To: Johannes Sixt; +Cc: msysgit, git, dotzenlabs On Wed, Dec 2, 2009 at 8:12 PM, Johannes Sixt <j6t@kdbg.org> wrote: > On Mittwoch, 2. Dezember 2009, Erik Faye-Lund wrote: >> I'm not entirely sure how to make the interface, though. Any good >> suggestions? > > I suggest to model finish_async_nowait() after waitpid() so that > > while ((pid = waitpid(-1, &status, WNOHANG)) > 0) ... > becomes > while ((pid = finish_async_nowait(&some_async, &status)) > 0) ... > > but where the resulting status is already "decoded", i.e. zero is success and > non-zero is failure (including death through signal); WIFEXITED and > WEXITSTATUS should not be applicable to status anymore. > > -- Hannes > Thanks. Implemented as suggested for the next round. -- Erik "kusma" Faye-Lund ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2009-12-08 13:37 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-26 0:39 [PATCH/RFC 00/11] daemon-win32 Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 03/11] mingw: implement syslog Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 07/11] run-command: support input-fd Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 08/11] daemon: use explicit file descriptor Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 09/11] daemon: use run-command api for async serving Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 10/11] daemon: use full buffered mode for stderr Erik Faye-Lund 2009-11-26 0:39 ` [PATCH/RFC 11/11] mingw: compile git-daemon Erik Faye-Lund 2009-11-26 0:43 ` [PATCH/RFC 00/11] daemon-win32 Erik Faye-Lund -- strict thread matches above, loose matches on Subject: below -- 2009-11-26 0:44 Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 01/11] mingw: add network-wrappers for daemon Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 02/11] strbuf: add non-variadic function strbuf_vaddf() Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 03/11] mingw: implement syslog Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 04/11] compat: add inet_pton and inet_ntop prototypes Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 05/11] inet_ntop: fix a couple of old-style decls Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 06/11] run-command: add kill_async() and is_async_alive() Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 07/11] run-command: support input-fd Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 08/11] daemon: use explicit file descriptor Erik Faye-Lund 2009-11-26 0:44 ` [PATCH/RFC 09/11] daemon: use run-command api for async serving Erik Faye-Lund 2009-11-27 20:59 ` [msysGit] " Johannes Sixt 2009-12-02 15:45 ` Erik Faye-Lund 2009-12-02 19:12 ` Johannes Sixt 2009-12-08 13:36 ` Erik Faye-Lund
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).