{"thread":{"id":"25510","subject":"[PATCH 03/15] inet_ntop: fix a couple of old-style decls","startedAt":"2010-10-22T00:05:30Z","lastAt":"2010-10-22T00:20:09Z","messageCount":18,"participants":["Erik Faye-Lund","Jonathan Nieder"],"isPatch":true,"patchVersion":1,"patchTotal":15},"messages":[{"id":"154051","messageId":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":null,"subject":"[PATCH 01/15] mingw: implement syslog","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:30Z","receivedAt":"2010-10-22T00:05:30Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"From: Mike Pape <dotzenlabs@gmail.com>\n\nSyslog does not usually exist on Windows, so implement our own using\nWindow's ReportEvent mechanism.\n\nStrings containing \"%1\" gets expanded into them selves by ReportEvent,\nresulting in an unreadable string. \"%2\" and above is not a problem.\nUnfortunately, on Windows an IPv6 address can contain \"%1\", so expand\n\"%1\" to \"% 1\" before reporting. \"%%1\" is also a problem for ReportEvent,\nbut that string cannot occur in an IPv6 address.\n\nSigned-off-by: Mike Pape <dotzenlabs@gmail.com>\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n Makefile              |    5 ++-\n compat/win32/syslog.c |   72 +++++++++++++++++++++++++++++++++++++++++++++++++\n compat/win32/syslog.h |   20 +++++++++++++\n daemon.c              |    2 -\n git-compat-util.h     |    1 +\n 5 files changed, 96 insertions(+), 4 deletions(-)\n create mode 100644 compat/win32/syslog.c\n create mode 100644 compat/win32/syslog.h\n\ndiff --git a/Makefile b/Makefile\nindex 1f1ce04..d9d9419 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -496,6 +496,7 @@ LIB_H += compat/bswap.h\n LIB_H += compat/cygwin.h\n LIB_H += compat/mingw.h\n LIB_H += compat/win32/pthread.h\n+LIB_H += compat/win32/syslog.h\n LIB_H += csum-file.h\n LIB_H += decorate.h\n LIB_H += delta.h\n@@ -1081,7 +1082,7 @@ ifeq ($(uname_S),Windows)\n \tAR = compat/vcbuild/scripts/lib.pl\n \tCFLAGS =\n \tBASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE\n-\tCOMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o\n+\tCOMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o\n \tCOMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\\\".exe\\\"\n \tBASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib\n \tEXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib\n@@ -1131,7 +1132,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))\n \tCOMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32\n \tCOMPAT_CFLAGS += -DSTRIP_EXTENSION=\\\".exe\\\"\n \tCOMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \\\n-\t\tcompat/win32/pthread.o\n+\t\tcompat/win32/pthread.o compat/win32/syslog.o\n \tEXTLIBS += -lws2_32\n \tPTHREAD_LIBS =\n \tX = .exe\ndiff --git a/compat/win32/syslog.c b/compat/win32/syslog.c\nnew file mode 100644\nindex 0000000..42b95a9\n--- /dev/null\n+++ b/compat/win32/syslog.c\n@@ -0,0 +1,72 @@\n+#include \"../../git-compat-util.h\"\n+#include \"../../strbuf.h\"\n+\n+static HANDLE ms_eventlog;\n+\n+void openlog(const char *ident, int logopt, int facility)\n+{\n+\tif (ms_eventlog)\n+\t\treturn;\n+\n+\tms_eventlog = RegisterEventSourceA(NULL, ident);\n+\n+\tif (!ms_eventlog)\n+\t\twarning(\"RegisterEventSource() failed: %lu\", GetLastError());\n+}\n+\n+void syslog(int priority, const char *fmt, ...)\n+{\n+\tstruct strbuf sb = STRBUF_INIT;\n+\tstruct strbuf_expand_dict_entry dict[] = {\n+\t\t{\"1\", \"% 1\"},\n+\t\t{NULL, NULL}\n+\t};\n+\tWORD logtype;\n+\tchar *str;\n+\tint str_len;\n+\tva_list ap;\n+\n+\tif (!ms_eventlog)\n+\t\treturn;\n+\n+\tva_start(ap, fmt);\n+\tstr_len = vsnprintf(NULL, 0, fmt, ap);\n+\tva_end(ap);\n+\n+\tif (str_len < 0) {\n+\t\twarning(\"vsnprintf failed: '%s'\", strerror(errno));\n+\t\treturn;\n+\t}\n+\n+\tstr = malloc(str_len + 1);\n+\tva_start(ap, fmt);\n+\tvsnprintf(str, str_len + 1, fmt, ap);\n+\tva_end(ap);\n+\tstrbuf_expand(&sb, str, strbuf_expand_dict_cb, &dict);\n+\tfree(str);\n+\n+\tswitch (priority) {\n+\tcase LOG_EMERG:\n+\tcase LOG_ALERT:\n+\tcase LOG_CRIT:\n+\tcase LOG_ERR:\n+\t\tlogtype = EVENTLOG_ERROR_TYPE;\n+\t\tbreak;\n+\n+\tcase LOG_WARNING:\n+\t\tlogtype = EVENTLOG_WARNING_TYPE;\n+\t\tbreak;\n+\n+\tcase LOG_NOTICE:\n+\tcase LOG_INFO:\n+\tcase LOG_DEBUG:\n+\tdefault:\n+\t\tlogtype = EVENTLOG_INFORMATION_TYPE;\n+\t\tbreak;\n+\t}\n+\n+\tReportEventA(ms_eventlog, logtype, 0, 0, NULL, 1, 0,\n+\t    (const char **)&sb.buf, NULL);\n+\n+\tstrbuf_release(&sb);\n+}\ndiff --git a/compat/win32/syslog.h b/compat/win32/syslog.h\nnew file mode 100644\nindex 0000000..70daa7c\n--- /dev/null\n+++ b/compat/win32/syslog.h\n@@ -0,0 +1,20 @@\n+#ifndef SYSLOG_H\n+#define SYSLOG_H\n+\n+#define LOG_PID     0x01\n+\n+#define LOG_EMERG   0\n+#define LOG_ALERT   1\n+#define LOG_CRIT    2\n+#define LOG_ERR     3\n+#define LOG_WARNING 4\n+#define LOG_NOTICE  5\n+#define LOG_INFO    6\n+#define LOG_DEBUG   7\n+\n+#define LOG_DAEMON  (3<<3)\n+\n+void openlog(const char *ident, int logopt, int facility);\n+void syslog(int priority, const char *fmt, ...);\n+\n+#endif /* SYSLOG_H */\ndiff --git a/daemon.c b/daemon.c\nindex d6e20c6..d594375 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -5,8 +5,6 @@\n #include \"strbuf.h\"\n #include \"string-list.h\"\n \n-#include <syslog.h>\n-\n #ifndef HOST_NAME_MAX\n #define HOST_NAME_MAX 256\n #endif\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 2af8d3e..e192831 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -104,6 +104,7 @@\n #include <assert.h>\n #include <regex.h>\n #include <utime.h>\n+#include <syslog.h>\n #ifndef __MINGW32__\n #include <sys/wait.h>\n #include <sys/poll.h>\n-- \n1.7.3.1.199.g72340\n"},{"id":"154050","messageId":"1287705944-5668-2-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 02/15] compat: add inet_pton and inet_ntop prototypes","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:31Z","receivedAt":"2010-10-22T00:05:31Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"From: Mike Pape <dotzenlabs@gmail.com>\n\nWindows doesn't have inet_pton and inet_ntop, so\nadd prototypes in git-compat-util.h for them.\n\nAt the same time include git-compat-util.h in\nthe sources for these functions, so they use the\nnetwork-wrappers from there on Windows.\n\nSigned-off-by: Mike Pape <dotzenlabs@gmail.com>\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n Makefile           |    2 ++\n compat/inet_ntop.c |    6 +++---\n compat/inet_pton.c |    8 +++++---\n git-compat-util.h  |    8 ++++++++\n 4 files changed, 18 insertions(+), 6 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex d9d9419..2aa067a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1398,9 +1398,11 @@ endif\n endif\n ifdef NO_INET_NTOP\n \tLIB_OBJS += compat/inet_ntop.o\n+\tBASIC_CFLAGS += -DNO_INET_NTOP\n endif\n ifdef NO_INET_PTON\n \tLIB_OBJS += compat/inet_pton.o\n+\tBASIC_CFLAGS += -DNO_INET_PTON\n endif\n \n ifdef NO_ICONV\ndiff --git a/compat/inet_ntop.c b/compat/inet_ntop.c\nindex f444982..e5b46a0 100644\n--- a/compat/inet_ntop.c\n+++ b/compat/inet_ntop.c\n@@ -17,9 +17,9 @@\n \n #include <errno.h>\n #include <sys/types.h>\n-#include <sys/socket.h>\n-#include <netinet/in.h>\n-#include <arpa/inet.h>\n+\n+#include \"../git-compat-util.h\"\n+\n #include <stdio.h>\n #include <string.h>\n \ndiff --git a/compat/inet_pton.c b/compat/inet_pton.c\nindex 4078fc0..2ec995e 100644\n--- a/compat/inet_pton.c\n+++ b/compat/inet_pton.c\n@@ -17,9 +17,9 @@\n \n #include <errno.h>\n #include <sys/types.h>\n-#include <sys/socket.h>\n-#include <netinet/in.h>\n-#include <arpa/inet.h>\n+\n+#include \"../git-compat-util.h\"\n+\n #include <stdio.h>\n #include <string.h>\n \n@@ -41,7 +41,9 @@\n  */\n \n static int inet_pton4(const char *src, unsigned char *dst);\n+#ifndef NO_IPV6\n static int inet_pton6(const char *src, unsigned char *dst);\n+#endif\n \n /* int\n  * inet_pton4(src, dst)\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex e192831..56dce85 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -387,6 +387,14 @@ static inline void *gitmempcpy(void *dest, const void *src, size_t n)\n }\n #endif\n \n+#ifdef NO_INET_PTON\n+int inet_pton(int af, const char *src, void *dst);\n+#endif\n+\n+#ifdef NO_INET_NTOP\n+const char *inet_ntop(int af, const void *src, char *dst, size_t size);\n+#endif\n+\n extern void release_pack_memory(size_t, int);\n \n typedef void (*try_to_free_t)(size_t);\n-- \n1.7.3.1.199.g72340\n"},{"id":"154049","messageId":"1287705944-5668-3-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 03/15] inet_ntop: fix a couple of old-style decls","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:32Z","receivedAt":"2010-10-22T00:05:32Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n compat/inet_ntop.c |   16 +++-------------\n 1 files changed, 3 insertions(+), 13 deletions(-)\n\ndiff --git a/compat/inet_ntop.c b/compat/inet_ntop.c\nindex e5b46a0..ea249c6 100644\n--- a/compat/inet_ntop.c\n+++ b/compat/inet_ntop.c\n@@ -50,10 +50,7 @@\n  *\tPaul Vixie, 1996.\n  */\n static const char *\n-inet_ntop4(src, dst, size)\n-\tconst u_char *src;\n-\tchar *dst;\n-\tsize_t size;\n+inet_ntop4(const u_char *src, char *dst, size_t size)\n {\n \tstatic const char fmt[] = \"%u.%u.%u.%u\";\n \tchar tmp[sizeof \"255.255.255.255\"];\n@@ -78,10 +75,7 @@ inet_ntop4(src, dst, size)\n  *\tPaul Vixie, 1996.\n  */\n static const char *\n-inet_ntop6(src, dst, size)\n-\tconst u_char *src;\n-\tchar *dst;\n-\tsize_t size;\n+inet_ntop6(const u_char *src, char *dst, size_t size)\n {\n \t/*\n \t * Note that int32_t and int16_t need only be \"at least\" large enough\n@@ -178,11 +172,7 @@ inet_ntop6(src, dst, size)\n  *\tPaul Vixie, 1996.\n  */\n const char *\n-inet_ntop(af, src, dst, size)\n-\tint af;\n-\tconst void *src;\n-\tchar *dst;\n-\tsize_t size;\n+inet_ntop(int af, const void *src, char *dst, size_t size)\n {\n \tswitch (af) {\n \tcase AF_INET:\n-- \n1.7.3.1.199.g72340\n"},{"id":"154052","messageId":"1287705944-5668-4-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 04/15] mingw: use real pid","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:33Z","receivedAt":"2010-10-22T00:05:33Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"The Windows port have so far been using process handles in place\nof PID. However, this is not work consistent with what getpid\nreturns.\n\nPIDs are system-global identifiers, but process handles are local\nto a process. Using PIDs instead of process handles allows, for\ninstance, a user to kill a hung process with the Task Manager,\nsomething that would have been impossible with process handles.\n\nChange the code to use the real PID, and use OpenProcess to get a\nprocess-handle. Store the PID and the process handle in a table\nprotected by a critical section, so we can safely close the\nprocess handle later.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n compat/mingw.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n compat/mingw.h |   10 ++-----\n 2 files changed, 72 insertions(+), 8 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 701a555..e2e3c54 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -702,6 +702,13 @@ static int env_compare(const void *a, const void *b)\n \treturn strcasecmp(*ea, *eb);\n }\n \n+struct {\n+\tpid_t pid;\n+\tHANDLE proc;\n+} *pinfo;\n+static int num_pinfo;\n+CRITICAL_SECTION pinfo_cs;\n+\n static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,\n \t\t\t      const char *dir,\n \t\t\t      int prepend_cmd, int fhin, int fhout, int fherr)\n@@ -794,7 +801,23 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,\n \t\treturn -1;\n \t}\n \tCloseHandle(pi.hThread);\n-\treturn (pid_t)pi.hProcess;\n+\n+\t/*\n+\t * The process ID is the human-readable identifier of the process\n+\t * that we want to present in log and error messages. The handle\n+\t * is not useful for this purpose. But we cannot close it, either,\n+\t * because it is not possible to turn a process ID into a process\n+\t * handle after the process terminated.\n+\t * Keep the handle in a list for waitpid.\n+\t */\n+\tEnterCriticalSection(&pinfo_cs);\n+\tnum_pinfo++;\n+\tpinfo = xrealloc(pinfo, sizeof(*pinfo) * num_pinfo);\n+\tpinfo[num_pinfo - 1].pid = pi.dwProcessId;\n+\tpinfo[num_pinfo - 1].proc = pi.hProcess;\n+\tLeaveCriticalSection(&pinfo_cs);\n+\n+\treturn (pid_t)pi.dwProcessId;\n }\n \n static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,\n@@ -1518,6 +1541,51 @@ char *getpass(const char *prompt)\n \treturn strbuf_detach(&buf, NULL);\n }\n \n+pid_t waitpid(pid_t pid, int *status, unsigned options)\n+{\n+\tHANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,\n+\t    FALSE, pid);\n+\tif (!h) {\n+\t\terrno = ECHILD;\n+\t\treturn -1;\n+\t}\n+\n+\tif (options == 0) {\n+\t\tint i;\n+\t\tif (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {\n+\t\t\tCloseHandle(h);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tif (status)\n+\t\t\tGetExitCodeProcess(h, (LPDWORD)status);\n+\n+\t\tEnterCriticalSection(&pinfo_cs);\n+\n+\t\tfor (i = 0; i < num_pinfo; ++i)\n+\t\t\tif (pinfo[i].pid == pid)\n+\t\t\t\tbreak;\n+\n+\t\tif (i < num_pinfo) {\n+\t\t\tCloseHandle(pinfo[i].proc);\n+\t\t\tmemmove(pinfo + i, pinfo + i + 1,\n+\t\t\t    sizeof(*pinfo) * (num_pinfo - i - 1));\n+\t\t\tnum_pinfo--;\n+\t\t\tpinfo = xrealloc(pinfo,\n+\t\t\t    sizeof(*pinfo) * num_pinfo);\n+\t\t}\n+\n+\t\tLeaveCriticalSection(&pinfo_cs);\n+\n+\t\tCloseHandle(h);\n+\t\treturn pid;\n+\t}\n+\tCloseHandle(h);\n+\n+\terrno = EINVAL;\n+\treturn -1;\n+}\n+\n #ifndef NO_MINGW_REPLACE_READDIR\n /* MinGW readdir implementation to avoid extra lstats for Git */\n struct mingw_DIR\ndiff --git a/compat/mingw.h b/compat/mingw.h\nindex a5bde82..7c4eeea 100644\n--- a/compat/mingw.h\n+++ b/compat/mingw.h\n@@ -140,13 +140,7 @@ static inline int mingw_unlink(const char *pathname)\n }\n #define unlink mingw_unlink\n \n-static inline pid_t waitpid(pid_t pid, int *status, unsigned options)\n-{\n-\tif (options == 0)\n-\t\treturn _cwait(status, pid, 0);\n-\terrno = EINVAL;\n-\treturn -1;\n-}\n+pid_t waitpid(pid_t pid, int *status, unsigned options);\n \n #ifndef NO_OPENSSL\n #include <openssl/ssl.h>\n@@ -321,11 +315,13 @@ void free_environ(char **env);\n static int mingw_main(); \\\n int main(int argc, const char **argv) \\\n { \\\n+\textern CRITICAL_SECTION pinfo_cs; \\\n \t_fmode = _O_BINARY; \\\n \t_setmode(_fileno(stdin), _O_BINARY); \\\n \t_setmode(_fileno(stdout), _O_BINARY); \\\n \t_setmode(_fileno(stderr), _O_BINARY); \\\n \targv[0] = xstrdup(_pgmptr); \\\n+\tInitializeCriticalSection(&pinfo_cs); \\\n \treturn mingw_main(argc, argv); \\\n } \\\n static int mingw_main(c,v)\n-- \n1.7.3.1.199.g72340\n"},{"id":"154053","messageId":"1287705944-5668-5-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 05/15] mingw: support waitpid with pid > 0 and WNOHANG","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:34Z","receivedAt":"2010-10-22T00:05:34Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n compat/mingw.c |    6 ++++++\n compat/mingw.h |    1 +\n 2 files changed, 7 insertions(+), 0 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex e2e3c54..2e7c644 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -1550,6 +1550,12 @@ pid_t waitpid(pid_t pid, int *status, unsigned options)\n \t\treturn -1;\n \t}\n \n+\tif (pid > 0 && options & WNOHANG) {\n+\t\tif (WAIT_OBJECT_0 != WaitForSingleObject((HANDLE)pid, 0))\n+\t\t\treturn 0;\n+\t\toptions &= ~WNOHANG;\n+\t}\n+\n \tif (options == 0) {\n \t\tint i;\n \t\tif (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {\ndiff --git a/compat/mingw.h b/compat/mingw.h\nindex 7c4eeea..379d7bf 100644\n--- a/compat/mingw.h\n+++ b/compat/mingw.h\n@@ -140,6 +140,7 @@ static inline int mingw_unlink(const char *pathname)\n }\n #define unlink mingw_unlink\n \n+#define WNOHANG 1\n pid_t waitpid(pid_t pid, int *status, unsigned options);\n \n #ifndef NO_OPENSSL\n-- \n1.7.3.1.199.g72340\n"},{"id":"154055","messageId":"1287705944-5668-6-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 06/15] mingw: add kill emulation","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:35Z","receivedAt":"2010-10-22T00:05:35Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"This is a quite limited kill-emulation; it can only handle\nSIGTERM on positive pids. However, it's enough for git-daemon.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n compat/mingw.c |   19 +++++++++++++++++++\n compat/mingw.h |    3 +++\n 2 files changed, 22 insertions(+), 0 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 2e7c644..21d1c2c 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -932,6 +932,25 @@ void mingw_execv(const char *cmd, char *const *argv)\n \tmingw_execve(cmd, argv, environ);\n }\n \n+int mingw_kill(pid_t pid, int sig)\n+{\n+\tif (pid > 0 && sig == SIGTERM) {\n+\t\tHANDLE h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);\n+\n+\t\tif (TerminateProcess(h, -1)) {\n+\t\t\tCloseHandle(h);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\terrno = err_win_to_posix(GetLastError());\n+\t\tCloseHandle(h);\n+\t\treturn -1;\n+\t}\n+\n+\terrno = EINVAL;\n+\treturn -1;\n+}\n+\n static char **copy_environ(void)\n {\n \tchar **env;\ndiff --git a/compat/mingw.h b/compat/mingw.h\nindex 379d7bf..51fca2f 100644\n--- a/compat/mingw.h\n+++ b/compat/mingw.h\n@@ -143,6 +143,9 @@ static inline int mingw_unlink(const char *pathname)\n #define WNOHANG 1\n pid_t waitpid(pid_t pid, int *status, unsigned options);\n \n+#define kill mingw_kill\n+int mingw_kill(pid_t pid, int sig);\n+\n #ifndef NO_OPENSSL\n #include <openssl/ssl.h>\n static inline int mingw_SSL_set_fd(SSL *ssl, int fd)\n-- \n1.7.3.1.199.g72340\n"},{"id":"154056","messageId":"1287705944-5668-7-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 07/15] daemon: use run-command api for async serving","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:36Z","receivedAt":"2010-10-22T00:05:36Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"fork() is only available on POSIX, so to support git-daemon\non Windows we have to use something else.\n\nInstead we invent the flag --serve, which is a stripped down\nversion of --inetd-mode. We use start_command() to call\ngit-daemon with this flag appended to serve clients.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n daemon.c |   87 +++++++++++++++++++++++++++++++------------------------------\n 1 files changed, 44 insertions(+), 43 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex d594375..11a5e06 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -614,17 +614,17 @@ static unsigned int live_children;\n \n static struct child {\n \tstruct child *next;\n-\tpid_t pid;\n+\tstruct child_process cld;\n \tstruct sockaddr_storage address;\n } *firstborn;\n \n-static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)\n+static void add_child(struct child_process *cld, struct sockaddr *addr, int addrlen)\n {\n \tstruct child *newborn, **cradle;\n \n \tnewborn = xcalloc(1, sizeof(*newborn));\n \tlive_children++;\n-\tnewborn->pid = pid;\n+\tmemcpy(&newborn->cld, cld, sizeof(*cld));\n \tmemcpy(&newborn->address, addr, addrlen);\n \tfor (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)\n \t\tif (!addrcmp(&(*cradle)->address, &newborn->address))\n@@ -633,19 +633,6 @@ static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)\n \t*cradle = newborn;\n }\n \n-static void remove_child(pid_t pid)\n-{\n-\tstruct child **cradle, *blanket;\n-\n-\tfor (cradle = &firstborn; (blanket = *cradle); cradle = &blanket->next)\n-\t\tif (blanket->pid == pid) {\n-\t\t\t*cradle = blanket->next;\n-\t\t\tlive_children--;\n-\t\t\tfree(blanket);\n-\t\t\tbreak;\n-\t\t}\n-}\n-\n /*\n  * This gets called if the number of connections grows\n  * past \"max_connections\".\n@@ -661,7 +648,7 @@ static void kill_some_child(void)\n \n \tfor (; (next = blanket->next); blanket = next)\n \t\tif (!addrcmp(&blanket->address, &next->address)) {\n-\t\t\tkill(blanket->pid, SIGTERM);\n+\t\t\tkill(blanket->cld.pid, SIGTERM);\n \t\t\tbreak;\n \t\t}\n }\n@@ -671,18 +658,26 @@ static void check_dead_children(void)\n \tint status;\n \tpid_t pid;\n \n-\twhile ((pid = waitpid(-1, &status, WNOHANG)) > 0) {\n-\t\tconst char *dead = \"\";\n-\t\tremove_child(pid);\n-\t\tif (!WIFEXITED(status) || (WEXITSTATUS(status) > 0))\n-\t\t\tdead = \" (with error)\";\n-\t\tloginfo(\"[%\"PRIuMAX\"] Disconnected%s\", (uintmax_t)pid, dead);\n-\t}\n+\tstruct child **cradle, *blanket;\n+\tfor (cradle = &firstborn; (blanket = *cradle);)\n+\t\tif ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) {\n+\t\t\tconst char *dead = \"\";\n+\t\t\tif (status)\n+\t\t\t\tdead = \" (with error)\";\n+\t\t\tloginfo(\"[%\"PRIuMAX\"] Disconnected%s\", (uintmax_t)pid, dead);\n+\n+\t\t\t/* remove the child */\n+\t\t\t*cradle = blanket->next;\n+\t\t\tlive_children--;\n+\t\t\tfree(blanket);\n+\t\t} else\n+\t\t\tcradle = &blanket->next;\n }\n \n+static char **cld_argv;\n static void handle(int incoming, struct sockaddr *addr, int addrlen)\n {\n-\tpid_t pid;\n+\tstruct child_process cld = { 0 };\n \n \tif (max_connections && live_children >= max_connections) {\n \t\tkill_some_child();\n@@ -695,22 +690,15 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)\n \t\t}\n \t}\n \n-\tif ((pid = fork())) {\n-\t\tclose(incoming);\n-\t\tif (pid < 0) {\n-\t\t\tlogerror(\"Couldn't fork %s\", strerror(errno));\n-\t\t\treturn;\n-\t\t}\n-\n-\t\tadd_child(pid, addr, addrlen);\n-\t\treturn;\n-\t}\n+\tcld.argv = (const char **)cld_argv;\n+\tcld.in = incoming;\n+\tcld.out = dup(incoming);\n \n-\tdup2(incoming, 0);\n-\tdup2(incoming, 1);\n+\tif (start_command(&cld))\n+\t\tlogerror(\"unable to fork\");\n+\telse\n+\t\tadd_child(&cld, addr, addrlen);\n \tclose(incoming);\n-\n-\texit(execute(addr));\n }\n \n static void child_handler(int signo)\n@@ -991,7 +979,7 @@ int main(int argc, char **argv)\n {\n \tint listen_port = 0;\n \tstruct string_list listen_addr = STRING_LIST_INIT_NODUP;\n-\tint inetd_mode = 0;\n+\tint serve_mode = 0, inetd_mode = 0;\n \tconst char *pid_file = NULL, *user_name = NULL, *group_name = NULL;\n \tint detach = 0;\n \tstruct passwd *pass = NULL;\n@@ -1017,6 +1005,10 @@ int main(int argc, char **argv)\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t}\n+\t\tif (!strcmp(arg, \"--serve\")) {\n+\t\t\tserve_mode = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(arg, \"--inetd\")) {\n \t\t\tinetd_mode = 1;\n \t\t\tlog_syslog = 1;\n@@ -1162,13 +1154,15 @@ int main(int argc, char **argv)\n \t\t    base_path);\n \n \tif (inetd_mode) {\n+\t\tif (!freopen(\"/dev/null\", \"w\", stderr))\n+\t\t\tdie_errno(\"failed to redirect stderr to /dev/null\");\n+\t}\n+\n+\tif (inetd_mode || serve_mode) {\n \t\tstruct sockaddr_storage ss;\n \t\tstruct sockaddr *peer = (struct sockaddr *)&ss;\n \t\tsocklen_t slen = sizeof(ss);\n \n-\t\tif (!freopen(\"/dev/null\", \"w\", stderr))\n-\t\t\tdie_errno(\"failed to redirect stderr to /dev/null\");\n-\n \t\tif (getpeername(0, peer, &slen))\n \t\t\tpeer = NULL;\n \n@@ -1185,5 +1179,12 @@ int main(int argc, char **argv)\n \tif (pid_file)\n \t\tstore_pid(pid_file);\n \n+\t/* prepare argv for serving-processes */\n+\tcld_argv = xmalloc(sizeof (char *) * (argc + 2));\n+\tfor (i = 0; i < argc; ++i)\n+\t\tcld_argv[i] = argv[i];\n+\tcld_argv[argc] = \"--serve\";\n+\tcld_argv[argc+1] = NULL;\n+\n \treturn serve(&listen_addr, listen_port, pass, gid);\n }\n-- \n1.7.3.1.199.g72340\n"},{"id":"154054","messageId":"1287705944-5668-8-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 08/15] daemon: use full buffered mode for stderr","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:37Z","receivedAt":"2010-10-22T00:05:37Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Windows doesn't support line buffered mode for file\nstreams, so let's just use full buffered mode with\na big buffer (\"4096 should be enough for everyone\")\nand add explicit flushing.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n daemon.c |    6 ++++--\n 1 files changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex 11a5e06..b72c89f 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -67,12 +67,14 @@ static void logreport(int priority, const char *err, va_list params)\n \t\tsyslog(priority, \"%s\", buf);\n \t} else {\n \t\t/*\n-\t\t * Since stderr is set to linebuffered mode, the\n+\t\t * Since stderr is set to buffered mode, the\n \t\t * logging of different processes will not overlap\n+\t\t * unless they overflow the (rather big) buffers.\n \t\t */\n \t\tfprintf(stderr, \"[%\"PRIuMAX\"] \", (uintmax_t)getpid());\n \t\tvfprintf(stderr, err, params);\n \t\tfputc('\\n', stderr);\n+\t\tfflush(stderr);\n \t}\n }\n \n@@ -1117,7 +1119,7 @@ int main(int argc, char **argv)\n \t\tset_die_routine(daemon_die);\n \t} else\n \t\t/* avoid splitting a message in the middle */\n-\t\tsetvbuf(stderr, NULL, _IOLBF, 0);\n+\t\tsetvbuf(stderr, NULL, _IOFBF, 4096);\n \n \tif (inetd_mode && (group_name || user_name))\n \t\tdie(\"--user and --group are incompatible with --inetd\");\n-- \n1.7.3.1.199.g72340\n"},{"id":"154057","messageId":"1287705944-5668-9-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 09/15] Improve the mingw getaddrinfo stub to handle more use cases","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:38Z","receivedAt":"2010-10-22T00:05:38Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"From: Martin Storsjö <martin@martin.st>\n\nAllow the node parameter to be null, which is used for getting\nthe default bind address.\n\nAlso allow the hints parameter to be null, to improve standard\nconformance of the stub implementation a little.\n\nSigned-off-by: Martin Storsjo <martin@martin.st>\n---\n compat/mingw.c |   28 +++++++++++++++++++++-------\n 1 files changed, 21 insertions(+), 7 deletions(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 21d1c2c..d88c0d0 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -1035,19 +1035,22 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service,\n \t\t\t\t   const struct addrinfo *hints,\n \t\t\t\t   struct addrinfo **res)\n {\n-\tstruct hostent *h = gethostbyname(node);\n+\tstruct hostent *h = NULL;\n \tstruct addrinfo *ai;\n \tstruct sockaddr_in *sin;\n \n-\tif (!h)\n-\t\treturn WSAGetLastError();\n+\tif (node) {\n+\t\th = gethostbyname(node);\n+\t\tif (!h)\n+\t\t\treturn WSAGetLastError();\n+\t}\n \n \tai = xmalloc(sizeof(struct addrinfo));\n \t*res = ai;\n \tai->ai_flags = 0;\n \tai->ai_family = AF_INET;\n-\tai->ai_socktype = hints->ai_socktype;\n-\tswitch (hints->ai_socktype) {\n+\tai->ai_socktype = hints ? hints->ai_socktype : 0;\n+\tswitch (ai->ai_socktype) {\n \tcase SOCK_STREAM:\n \t\tai->ai_protocol = IPPROTO_TCP;\n \t\tbreak;\n@@ -1059,14 +1062,25 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service,\n \t\tbreak;\n \t}\n \tai->ai_addrlen = sizeof(struct sockaddr_in);\n-\tai->ai_canonname = strdup(h->h_name);\n+\tif (hints && (hints->ai_flags & AI_CANONNAME))\n+\t\tai->ai_canonname = h ? strdup(h->h_name) : NULL;\n+\telse\n+\t\tai->ai_canonname = NULL;\n \n \tsin = xmalloc(ai->ai_addrlen);\n \tmemset(sin, 0, ai->ai_addrlen);\n \tsin->sin_family = AF_INET;\n+\t/* Note: getaddrinfo is supposed to allow service to be a string,\n+\t * which should be looked up using getservbyname. This is\n+\t * currently not implemented */\n \tif (service)\n \t\tsin->sin_port = htons(atoi(service));\n-\tsin->sin_addr = *(struct in_addr *)h->h_addr;\n+\tif (h)\n+\t\tsin->sin_addr = *(struct in_addr *)h->h_addr;\n+\telse if (hints && (hints->ai_flags & AI_PASSIVE))\n+\t\tsin->sin_addr.s_addr = INADDR_ANY;\n+\telse\n+\t\tsin->sin_addr.s_addr = INADDR_LOOPBACK;\n \tai->ai_addr = (struct sockaddr *)sin;\n \tai->ai_next = 0;\n \treturn 0;\n-- \n1.7.3.1.199.g72340\n"},{"id":"154058","messageId":"1287705944-5668-10-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 10/15] daemon: get remote host address from root-process","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:39Z","receivedAt":"2010-10-22T00:05:39Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Get remote host in the process that accept() and pass it through\nthe REMOTE_ADDR environment variable to the handler-process.\nIntroduce the REMOTE_PORT environmen variable for the port.\n\nUse these variables for reporting instead of doing\ngetpeername(0, ...), which doesn't work on Windows.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n daemon.c |   67 +++++++++++++++++++++++++++----------------------------------\n 1 files changed, 30 insertions(+), 37 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex b72c89f..19b4eb3 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -516,37 +516,14 @@ static void parse_host_arg(char *extra_args, int buflen)\n }\n \n \n-static int execute(struct sockaddr *addr)\n+static int execute(void)\n {\n \tstatic char line[1000];\n \tint pktlen, len, i;\n+\tchar *addr = getenv(\"REMOTE_ADDR\"), *port = getenv(\"REMOTE_PORT\");\n \n-\tif (addr) {\n-\t\tchar addrbuf[256] = \"\";\n-\t\tint port = -1;\n-\n-\t\tif (addr->sa_family == AF_INET) {\n-\t\t\tstruct sockaddr_in *sin_addr = (void *) addr;\n-\t\t\tinet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));\n-\t\t\tport = ntohs(sin_addr->sin_port);\n-#ifndef NO_IPV6\n-\t\t} else if (addr && addr->sa_family == AF_INET6) {\n-\t\t\tstruct sockaddr_in6 *sin6_addr = (void *) addr;\n-\n-\t\t\tchar *buf = addrbuf;\n-\t\t\t*buf++ = '['; *buf = '\\0'; /* stpcpy() is cool */\n-\t\t\tinet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);\n-\t\t\tstrcat(buf, \"]\");\n-\n-\t\t\tport = ntohs(sin6_addr->sin6_port);\n-#endif\n-\t\t}\n-\t\tloginfo(\"Connection from %s:%d\", addrbuf, port);\n-\t\tsetenv(\"REMOTE_ADDR\", addrbuf, 1);\n-\t}\n-\telse {\n-\t\tunsetenv(\"REMOTE_ADDR\");\n-\t}\n+\tif (addr)\n+\t\tloginfo(\"Connection from %s:%s\", addr, port);\n \n \talarm(init_timeout ? init_timeout : timeout);\n \tpktlen = packet_read_line(0, line, sizeof(line));\n@@ -680,6 +657,8 @@ static char **cld_argv;\n static void handle(int incoming, struct sockaddr *addr, int addrlen)\n {\n \tstruct child_process cld = { 0 };\n+\tchar addrbuf[300] = \"REMOTE_ADDR=\", portbuf[300];\n+\tchar *env[] = { addrbuf, portbuf, NULL };\n \n \tif (max_connections && live_children >= max_connections) {\n \t\tkill_some_child();\n@@ -692,6 +671,28 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)\n \t\t}\n \t}\n \n+\tif (addr->sa_family == AF_INET) {\n+\t\tstruct sockaddr_in *sin_addr = (void *) addr;\n+\t\tinet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,\n+\t\t    sizeof(addrbuf) - 12);\n+\t\tsnprintf(portbuf, sizeof(portbuf), \"REMOTE_PORT=%d\",\n+\t\t    ntohs(sin_addr->sin_port));\n+#ifndef NO_IPV6\n+\t} else if (addr && addr->sa_family == AF_INET6) {\n+\t\tstruct sockaddr_in6 *sin6_addr = (void *) addr;\n+\n+\t\tchar *buf = addrbuf + 12;\n+\t\t*buf++ = '['; *buf = '\\0'; /* stpcpy() is cool */\n+\t\tinet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,\n+\t\t    sizeof(addrbuf) - 13);\n+\t\tstrcat(buf, \"]\");\n+\n+\t\tsnprintf(portbuf, sizeof(portbuf), \"REMOTE_PORT=%d\",\n+\t\t    ntohs(sin6_addr->sin6_port));\n+#endif\n+\t}\n+\n+\tcld.env = (const char **)env;\n \tcld.argv = (const char **)cld_argv;\n \tcld.in = incoming;\n \tcld.out = dup(incoming);\n@@ -1160,16 +1161,8 @@ int main(int argc, char **argv)\n \t\t\tdie_errno(\"failed to redirect stderr to /dev/null\");\n \t}\n \n-\tif (inetd_mode || serve_mode) {\n-\t\tstruct sockaddr_storage ss;\n-\t\tstruct sockaddr *peer = (struct sockaddr *)&ss;\n-\t\tsocklen_t slen = sizeof(ss);\n-\n-\t\tif (getpeername(0, peer, &slen))\n-\t\t\tpeer = NULL;\n-\n-\t\treturn execute(peer);\n-\t}\n+\tif (inetd_mode || serve_mode)\n+\t\treturn execute();\n \n \tif (detach) {\n \t\tdaemonize();\n-- \n1.7.3.1.199.g72340\n"},{"id":"154059","messageId":"1287705944-5668-11-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 11/15] mingw: import poll-emulation from gnulib","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:40Z","receivedAt":"2010-10-22T00:05:40Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"copy lib/poll.c and lib/poll.in.h verbatim from commit 0a05120 in\ngit://git.savannah.gnu.org/gnulib.git to compat/win32/sys/poll.[ch]\n\nTo upgrade this code in the future, branch out from this commit, copy\nnew versions of the files above on top, and merge back the result.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n compat/win32/sys/poll.c |  597 +++++++++++++++++++++++++++++++++++++++++++++++\n compat/win32/sys/poll.h |   53 +++++\n 2 files changed, 650 insertions(+), 0 deletions(-)\n create mode 100644 compat/win32/sys/poll.c\n create mode 100644 compat/win32/sys/poll.h\n\ndiff --git a/compat/win32/sys/poll.c b/compat/win32/sys/poll.c\nnew file mode 100644\nindex 0000000..7c52cb6\n--- /dev/null\n+++ b/compat/win32/sys/poll.c\n@@ -0,0 +1,597 @@\n+/* Emulation for poll(2)\n+   Contributed by Paolo Bonzini.\n+\n+   Copyright 2001-2003, 2006-2010 Free Software Foundation, Inc.\n+\n+   This file is part of gnulib.\n+\n+   This program is free software; you can redistribute it and/or modify\n+   it under the terms of the GNU General Public License as published by\n+   the Free Software Foundation; either version 2, or (at your option)\n+   any later version.\n+\n+   This program is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+   GNU General Public License for more details.\n+\n+   You should have received a copy of the GNU General Public License along\n+   with this program; if not, write to the Free Software Foundation,\n+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */\n+\n+/* Tell gcc not to warn about the (nfd < 0) tests, below.  */\n+#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__\n+# pragma GCC diagnostic ignored \"-Wtype-limits\"\n+#endif\n+\n+#include <config.h>\n+#include <alloca.h>\n+\n+#include <sys/types.h>\n+#include \"poll.h\"\n+#include <errno.h>\n+#include <limits.h>\n+#include <assert.h>\n+\n+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__\n+# define WIN32_NATIVE\n+# include <winsock2.h>\n+# include <windows.h>\n+# include <io.h>\n+# include <stdio.h>\n+# include <conio.h>\n+#else\n+# include <sys/time.h>\n+# include <sys/socket.h>\n+# include <sys/select.h>\n+# include <unistd.h>\n+#endif\n+\n+#ifdef HAVE_SYS_IOCTL_H\n+# include <sys/ioctl.h>\n+#endif\n+#ifdef HAVE_SYS_FILIO_H\n+# include <sys/filio.h>\n+#endif\n+\n+#include <time.h>\n+\n+#ifndef INFTIM\n+# define INFTIM (-1)\n+#endif\n+\n+/* BeOS does not have MSG_PEEK.  */\n+#ifndef MSG_PEEK\n+# define MSG_PEEK 0\n+#endif\n+\n+#ifdef WIN32_NATIVE\n+\n+#define IsConsoleHandle(h) (((long) (h) & 3) == 3)\n+\n+static BOOL\n+IsSocketHandle (HANDLE h)\n+{\n+  WSANETWORKEVENTS ev;\n+\n+  if (IsConsoleHandle (h))\n+    return FALSE;\n+\n+  /* Under Wine, it seems that getsockopt returns 0 for pipes too.\n+     WSAEnumNetworkEvents instead distinguishes the two correctly.  */\n+  ev.lNetworkEvents = 0xDEADBEEF;\n+  WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);\n+  return ev.lNetworkEvents != 0xDEADBEEF;\n+}\n+\n+/* Declare data structures for ntdll functions.  */\n+typedef struct _FILE_PIPE_LOCAL_INFORMATION {\n+  ULONG NamedPipeType;\n+  ULONG NamedPipeConfiguration;\n+  ULONG MaximumInstances;\n+  ULONG CurrentInstances;\n+  ULONG InboundQuota;\n+  ULONG ReadDataAvailable;\n+  ULONG OutboundQuota;\n+  ULONG WriteQuotaAvailable;\n+  ULONG NamedPipeState;\n+  ULONG NamedPipeEnd;\n+} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;\n+\n+typedef struct _IO_STATUS_BLOCK\n+{\n+  union {\n+    DWORD Status;\n+    PVOID Pointer;\n+  } u;\n+  ULONG_PTR Information;\n+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;\n+\n+typedef enum _FILE_INFORMATION_CLASS {\n+  FilePipeLocalInformation = 24\n+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;\n+\n+typedef DWORD (WINAPI *PNtQueryInformationFile)\n+         (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);\n+\n+# ifndef PIPE_BUF\n+#  define PIPE_BUF      512\n+# endif\n+\n+/* Compute revents values for file handle H.  If some events cannot happen\n+   for the handle, eliminate them from *P_SOUGHT.  */\n+\n+static int\n+win32_compute_revents (HANDLE h, int *p_sought)\n+{\n+  int i, ret, happened;\n+  INPUT_RECORD *irbuffer;\n+  DWORD avail, nbuffer;\n+  BOOL bRet;\n+  IO_STATUS_BLOCK iosb;\n+  FILE_PIPE_LOCAL_INFORMATION fpli;\n+  static PNtQueryInformationFile NtQueryInformationFile;\n+  static BOOL once_only;\n+\n+  switch (GetFileType (h))\n+    {\n+    case FILE_TYPE_PIPE:\n+      if (!once_only)\n+        {\n+          NtQueryInformationFile = (PNtQueryInformationFile)\n+            GetProcAddress (GetModuleHandle (\"ntdll.dll\"),\n+                            \"NtQueryInformationFile\");\n+          once_only = TRUE;\n+        }\n+\n+      happened = 0;\n+      if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)\n+        {\n+          if (avail)\n+            happened |= *p_sought & (POLLIN | POLLRDNORM);\n+        }\n+      else if (GetLastError () == ERROR_BROKEN_PIPE)\n+        happened |= POLLHUP;\n+\n+      else\n+        {\n+          /* It was the write-end of the pipe.  Check if it is writable.\n+             If NtQueryInformationFile fails, optimistically assume the pipe is\n+             writable.  This could happen on Win9x, where NtQueryInformationFile\n+             is not available, or if we inherit a pipe that doesn't permit\n+             FILE_READ_ATTRIBUTES access on the write end (I think this should\n+             not happen since WinXP SP2; WINE seems fine too).  Otherwise,\n+             ensure that enough space is available for atomic writes.  */\n+          memset (&iosb, 0, sizeof (iosb));\n+          memset (&fpli, 0, sizeof (fpli));\n+\n+          if (!NtQueryInformationFile\n+              || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),\n+                                         FilePipeLocalInformation)\n+              || fpli.WriteQuotaAvailable >= PIPE_BUF\n+              || (fpli.OutboundQuota < PIPE_BUF &&\n+                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))\n+            happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);\n+        }\n+      return happened;\n+\n+    case FILE_TYPE_CHAR:\n+      ret = WaitForSingleObject (h, 0);\n+      if (!IsConsoleHandle (h))\n+        return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;\n+\n+      nbuffer = avail = 0;\n+      bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);\n+      if (bRet)\n+        {\n+          /* Input buffer.  */\n+          *p_sought &= POLLIN | POLLRDNORM;\n+          if (nbuffer == 0)\n+            return POLLHUP;\n+          if (!*p_sought)\n+            return 0;\n+\n+          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));\n+          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);\n+          if (!bRet || avail == 0)\n+            return POLLHUP;\n+\n+          for (i = 0; i < avail; i++)\n+            if (irbuffer[i].EventType == KEY_EVENT)\n+              return *p_sought;\n+          return 0;\n+        }\n+      else\n+        {\n+          /* Screen buffer.  */\n+          *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;\n+          return *p_sought;\n+        }\n+\n+    default:\n+      ret = WaitForSingleObject (h, 0);\n+      if (ret == WAIT_OBJECT_0)\n+        return *p_sought & ~(POLLPRI | POLLRDBAND);\n+\n+      return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);\n+    }\n+}\n+\n+/* Convert fd_sets returned by select into revents values.  */\n+\n+static int\n+win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)\n+{\n+  int happened = 0;\n+\n+  if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)\n+    happened |= (POLLIN | POLLRDNORM) & sought;\n+\n+  else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))\n+    {\n+      int r, error;\n+\n+      char data[64];\n+      WSASetLastError (0);\n+      r = recv (h, data, sizeof (data), MSG_PEEK);\n+      error = WSAGetLastError ();\n+      WSASetLastError (0);\n+\n+      if (r > 0 || error == WSAENOTCONN)\n+        happened |= (POLLIN | POLLRDNORM) & sought;\n+\n+      /* Distinguish hung-up sockets from other errors.  */\n+      else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET\n+               || error == WSAECONNABORTED || error == WSAENETRESET)\n+        happened |= POLLHUP;\n+\n+      else\n+        happened |= POLLERR;\n+    }\n+\n+  if (lNetworkEvents & (FD_WRITE | FD_CONNECT))\n+    happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;\n+\n+  if (lNetworkEvents & FD_OOB)\n+    happened |= (POLLPRI | POLLRDBAND) & sought;\n+\n+  return happened;\n+}\n+\n+#else /* !MinGW */\n+\n+/* Convert select(2) returned fd_sets into poll(2) revents values.  */\n+static int\n+compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)\n+{\n+  int happened = 0;\n+  if (FD_ISSET (fd, rfds))\n+    {\n+      int r;\n+      int socket_errno;\n+\n+# if defined __MACH__ && defined __APPLE__\n+      /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK\n+         for some kinds of descriptors.  Detect if this descriptor is a\n+         connected socket, a server socket, or something else using a\n+         0-byte recv, and use ioctl(2) to detect POLLHUP.  */\n+      r = recv (fd, NULL, 0, MSG_PEEK);\n+      socket_errno = (r < 0) ? errno : 0;\n+      if (r == 0 || socket_errno == ENOTSOCK)\n+        ioctl (fd, FIONREAD, &r);\n+# else\n+      char data[64];\n+      r = recv (fd, data, sizeof (data), MSG_PEEK);\n+      socket_errno = (r < 0) ? errno : 0;\n+# endif\n+      if (r == 0)\n+        happened |= POLLHUP;\n+\n+      /* If the event happened on an unconnected server socket,\n+         that's fine. */\n+      else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))\n+        happened |= (POLLIN | POLLRDNORM) & sought;\n+\n+      /* Distinguish hung-up sockets from other errors.  */\n+      else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET\n+               || socket_errno == ECONNABORTED || socket_errno == ENETRESET)\n+        happened |= POLLHUP;\n+\n+      else\n+        happened |= POLLERR;\n+    }\n+\n+  if (FD_ISSET (fd, wfds))\n+    happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;\n+\n+  if (FD_ISSET (fd, efds))\n+    happened |= (POLLPRI | POLLRDBAND) & sought;\n+\n+  return happened;\n+}\n+#endif /* !MinGW */\n+\n+int\n+poll (pfd, nfd, timeout)\n+     struct pollfd *pfd;\n+     nfds_t nfd;\n+     int timeout;\n+{\n+#ifndef WIN32_NATIVE\n+  fd_set rfds, wfds, efds;\n+  struct timeval tv;\n+  struct timeval *ptv;\n+  int maxfd, rc;\n+  nfds_t i;\n+\n+# ifdef _SC_OPEN_MAX\n+  static int sc_open_max = -1;\n+\n+  if (nfd < 0\n+      || (nfd > sc_open_max\n+          && (sc_open_max != -1\n+              || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))\n+    {\n+      errno = EINVAL;\n+      return -1;\n+    }\n+# else /* !_SC_OPEN_MAX */\n+#  ifdef OPEN_MAX\n+  if (nfd < 0 || nfd > OPEN_MAX)\n+    {\n+      errno = EINVAL;\n+      return -1;\n+    }\n+#  endif /* OPEN_MAX -- else, no check is needed */\n+# endif /* !_SC_OPEN_MAX */\n+\n+  /* EFAULT is not necessary to implement, but let's do it in the\n+     simplest case. */\n+  if (!pfd)\n+    {\n+      errno = EFAULT;\n+      return -1;\n+    }\n+\n+  /* convert timeout number into a timeval structure */\n+  if (timeout == 0)\n+    {\n+      ptv = &tv;\n+      ptv->tv_sec = 0;\n+      ptv->tv_usec = 0;\n+    }\n+  else if (timeout > 0)\n+    {\n+      ptv = &tv;\n+      ptv->tv_sec = timeout / 1000;\n+      ptv->tv_usec = (timeout % 1000) * 1000;\n+    }\n+  else if (timeout == INFTIM)\n+    /* wait forever */\n+    ptv = NULL;\n+  else\n+    {\n+      errno = EINVAL;\n+      return -1;\n+    }\n+\n+  /* create fd sets and determine max fd */\n+  maxfd = -1;\n+  FD_ZERO (&rfds);\n+  FD_ZERO (&wfds);\n+  FD_ZERO (&efds);\n+  for (i = 0; i < nfd; i++)\n+    {\n+      if (pfd[i].fd < 0)\n+        continue;\n+\n+      if (pfd[i].events & (POLLIN | POLLRDNORM))\n+        FD_SET (pfd[i].fd, &rfds);\n+\n+      /* see select(2): \"the only exceptional condition detectable\n+         is out-of-band data received on a socket\", hence we push\n+         POLLWRBAND events onto wfds instead of efds. */\n+      if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))\n+        FD_SET (pfd[i].fd, &wfds);\n+      if (pfd[i].events & (POLLPRI | POLLRDBAND))\n+        FD_SET (pfd[i].fd, &efds);\n+      if (pfd[i].fd >= maxfd\n+          && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI\n+                               | POLLRDNORM | POLLRDBAND\n+                               | POLLWRNORM | POLLWRBAND)))\n+        {\n+          maxfd = pfd[i].fd;\n+          if (maxfd > FD_SETSIZE)\n+            {\n+              errno = EOVERFLOW;\n+              return -1;\n+            }\n+        }\n+    }\n+\n+  /* examine fd sets */\n+  rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);\n+  if (rc < 0)\n+    return rc;\n+\n+  /* establish results */\n+  rc = 0;\n+  for (i = 0; i < nfd; i++)\n+    if (pfd[i].fd < 0)\n+      pfd[i].revents = 0;\n+    else\n+      {\n+        int happened = compute_revents (pfd[i].fd, pfd[i].events,\n+                                        &rfds, &wfds, &efds);\n+        if (happened)\n+          {\n+            pfd[i].revents = happened;\n+            rc++;\n+          }\n+      }\n+\n+  return rc;\n+#else\n+  static struct timeval tv0;\n+  static HANDLE hEvent;\n+  WSANETWORKEVENTS ev;\n+  HANDLE h, handle_array[FD_SETSIZE + 2];\n+  DWORD ret, wait_timeout, nhandles;\n+  fd_set rfds, wfds, xfds;\n+  BOOL poll_again;\n+  MSG msg;\n+  int rc = 0;\n+  nfds_t i;\n+\n+  if (nfd < 0 || timeout < -1)\n+    {\n+      errno = EINVAL;\n+      return -1;\n+    }\n+\n+  if (!hEvent)\n+    hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);\n+\n+  handle_array[0] = hEvent;\n+  nhandles = 1;\n+  FD_ZERO (&rfds);\n+  FD_ZERO (&wfds);\n+  FD_ZERO (&xfds);\n+\n+  /* Classify socket handles and create fd sets. */\n+  for (i = 0; i < nfd; i++)\n+    {\n+      int sought = pfd[i].events;\n+      pfd[i].revents = 0;\n+      if (pfd[i].fd < 0)\n+        continue;\n+      if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND\n+                      | POLLPRI | POLLRDBAND)))\n+        continue;\n+\n+      h = (HANDLE) _get_osfhandle (pfd[i].fd);\n+      assert (h != NULL);\n+      if (IsSocketHandle (h))\n+        {\n+          int requested = FD_CLOSE;\n+\n+          /* see above; socket handles are mapped onto select.  */\n+          if (sought & (POLLIN | POLLRDNORM))\n+            {\n+              requested |= FD_READ | FD_ACCEPT;\n+              FD_SET ((SOCKET) h, &rfds);\n+            }\n+          if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))\n+            {\n+              requested |= FD_WRITE | FD_CONNECT;\n+              FD_SET ((SOCKET) h, &wfds);\n+            }\n+          if (sought & (POLLPRI | POLLRDBAND))\n+            {\n+              requested |= FD_OOB;\n+              FD_SET ((SOCKET) h, &xfds);\n+            }\n+\n+          if (requested)\n+            WSAEventSelect ((SOCKET) h, hEvent, requested);\n+        }\n+      else\n+        {\n+          /* Poll now.  If we get an event, do not poll again.  Also,\n+             screen buffer handles are waitable, and they'll block until\n+             a character is available.  win32_compute_revents eliminates\n+             bits for the \"wrong\" direction. */\n+          pfd[i].revents = win32_compute_revents (h, &sought);\n+          if (sought)\n+            handle_array[nhandles++] = h;\n+          if (pfd[i].revents)\n+            timeout = 0;\n+        }\n+    }\n+\n+  if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)\n+    {\n+      /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but\n+         no need to call select again.  */\n+      poll_again = FALSE;\n+      wait_timeout = 0;\n+    }\n+  else\n+    {\n+      poll_again = TRUE;\n+      if (timeout == INFTIM)\n+        wait_timeout = INFINITE;\n+      else\n+        wait_timeout = timeout;\n+    }\n+\n+  for (;;)\n+    {\n+      ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,\n+                                       wait_timeout, QS_ALLINPUT);\n+\n+      if (ret == WAIT_OBJECT_0 + nhandles)\n+        {\n+          /* new input of some other kind */\n+          BOOL bRet;\n+          while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)\n+            {\n+              TranslateMessage (&msg);\n+              DispatchMessage (&msg);\n+            }\n+        }\n+      else\n+        break;\n+    }\n+\n+  if (poll_again)\n+    select (0, &rfds, &wfds, &xfds, &tv0);\n+\n+  /* Place a sentinel at the end of the array.  */\n+  handle_array[nhandles] = NULL;\n+  nhandles = 1;\n+  for (i = 0; i < nfd; i++)\n+    {\n+      int happened;\n+\n+      if (pfd[i].fd < 0)\n+        continue;\n+      if (!(pfd[i].events & (POLLIN | POLLRDNORM |\n+                             POLLOUT | POLLWRNORM | POLLWRBAND)))\n+        continue;\n+\n+      h = (HANDLE) _get_osfhandle (pfd[i].fd);\n+      if (h != handle_array[nhandles])\n+        {\n+          /* It's a socket.  */\n+          WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);\n+          WSAEventSelect ((SOCKET) h, 0, 0);\n+\n+          /* If we're lucky, WSAEnumNetworkEvents already provided a way\n+             to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */\n+          if (FD_ISSET ((SOCKET) h, &rfds)\n+              && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))\n+            ev.lNetworkEvents |= FD_READ | FD_ACCEPT;\n+          if (FD_ISSET ((SOCKET) h, &wfds))\n+            ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;\n+          if (FD_ISSET ((SOCKET) h, &xfds))\n+            ev.lNetworkEvents |= FD_OOB;\n+\n+          happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,\n+                                                   ev.lNetworkEvents);\n+        }\n+      else\n+        {\n+          /* Not a socket.  */\n+          int sought = pfd[i].events;\n+          happened = win32_compute_revents (h, &sought);\n+          nhandles++;\n+        }\n+\n+       if ((pfd[i].revents |= happened) != 0)\n+        rc++;\n+    }\n+\n+  return rc;\n+#endif\n+}\ndiff --git a/compat/win32/sys/poll.h b/compat/win32/sys/poll.h\nnew file mode 100644\nindex 0000000..b7aa59d\n--- /dev/null\n+++ b/compat/win32/sys/poll.h\n@@ -0,0 +1,53 @@\n+/* Header for poll(2) emulation\n+   Contributed by Paolo Bonzini.\n+\n+   Copyright 2001, 2002, 2003, 2007, 2009, 2010 Free Software Foundation, Inc.\n+\n+   This file is part of gnulib.\n+\n+   This program is free software; you can redistribute it and/or modify\n+   it under the terms of the GNU General Public License as published by\n+   the Free Software Foundation; either version 2, or (at your option)\n+   any later version.\n+\n+   This program is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+   GNU General Public License for more details.\n+\n+   You should have received a copy of the GNU General Public License along\n+   with this program; if not, write to the Free Software Foundation,\n+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */\n+\n+#ifndef _GL_POLL_H\n+#define _GL_POLL_H\n+\n+/* fake a poll(2) environment */\n+#define POLLIN      0x0001      /* any readable data available   */\n+#define POLLPRI     0x0002      /* OOB/Urgent readable data      */\n+#define POLLOUT     0x0004      /* file descriptor is writeable  */\n+#define POLLERR     0x0008      /* some poll error occurred      */\n+#define POLLHUP     0x0010      /* file descriptor was \"hung up\" */\n+#define POLLNVAL    0x0020      /* requested events \"invalid\"    */\n+#define POLLRDNORM  0x0040\n+#define POLLRDBAND  0x0080\n+#define POLLWRNORM  0x0100\n+#define POLLWRBAND  0x0200\n+\n+struct pollfd\n+{\n+  int fd;                       /* which file descriptor to poll */\n+  short events;                 /* events we are interested in   */\n+  short revents;                /* events found on return        */\n+};\n+\n+typedef unsigned long nfds_t;\n+\n+extern int poll (struct pollfd *pfd, nfds_t nfd, int timeout);\n+\n+/* Define INFTIM only if doing so conforms to POSIX.  */\n+#if !defined (_POSIX_C_SOURCE) && !defined (_XOPEN_SOURCE)\n+#define INFTIM (-1)\n+#endif\n+\n+#endif /* _GL_POLL_H */\n-- \n1.7.3.1.199.g72340\n"},{"id":"154060","messageId":"1287705944-5668-12-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 12/15] mingw: use poll-emulation from gnulib","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:41Z","receivedAt":"2010-10-22T00:05:41Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n Makefile                |    6 +++-\n compat/mingw.c          |   65 -----------------------------------------------\n compat/mingw.h          |   11 --------\n compat/win32/sys/poll.c |    3 +-\n git-compat-util.h       |    2 +-\n 5 files changed, 6 insertions(+), 81 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 2aa067a..46034bf 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -497,6 +497,7 @@ LIB_H += compat/cygwin.h\n LIB_H += compat/mingw.h\n LIB_H += compat/win32/pthread.h\n LIB_H += compat/win32/syslog.h\n+LIB_H += compat/win32/sys/poll.h\n LIB_H += csum-file.h\n LIB_H += decorate.h\n LIB_H += delta.h\n@@ -1082,7 +1083,7 @@ ifeq ($(uname_S),Windows)\n \tAR = compat/vcbuild/scripts/lib.pl\n \tCFLAGS =\n \tBASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE\n-\tCOMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o\n+\tCOMPAT_OBJS = compat/msvc.o compat/fnmatch/fnmatch.o compat/winansi.o compat/win32/pthread.o compat/win32/syslog.o compat/win32/sys/poll.o\n \tCOMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -DHAVE_ALLOCA_H -Icompat -Icompat/fnmatch -Icompat/regex -Icompat/fnmatch -Icompat/win32 -DSTRIP_EXTENSION=\\\".exe\\\"\n \tBASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE -NODEFAULTLIB:MSVCRT.lib\n \tEXTLIBS = advapi32.lib shell32.lib wininet.lib ws2_32.lib\n@@ -1132,7 +1133,8 @@ ifneq (,$(findstring MINGW,$(uname_S)))\n \tCOMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32\n \tCOMPAT_CFLAGS += -DSTRIP_EXTENSION=\\\".exe\\\"\n \tCOMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \\\n-\t\tcompat/win32/pthread.o compat/win32/syslog.o\n+\t\tcompat/win32/pthread.o compat/win32/syslog.o \\\n+\t\tcompat/win32/sys/poll.o\n \tEXTLIBS += -lws2_32\n \tPTHREAD_LIBS =\n \tX = .exe\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex d88c0d0..b780200 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -408,71 +408,6 @@ int pipe(int filedes[2])\n \treturn 0;\n }\n \n-int poll(struct pollfd *ufds, unsigned int nfds, int timeout)\n-{\n-\tint i, pending;\n-\n-\tif (timeout >= 0) {\n-\t\tif (nfds == 0) {\n-\t\t\tSleep(timeout);\n-\t\t\treturn 0;\n-\t\t}\n-\t\treturn errno = EINVAL, error(\"poll timeout not supported\");\n-\t}\n-\n-\t/* When there is only one fd to wait for, then we pretend that\n-\t * input is available and let the actual wait happen when the\n-\t * caller invokes read().\n-\t */\n-\tif (nfds == 1) {\n-\t\tif (!(ufds[0].events & POLLIN))\n-\t\t\treturn errno = EINVAL, error(\"POLLIN not set\");\n-\t\tufds[0].revents = POLLIN;\n-\t\treturn 0;\n-\t}\n-\n-repeat:\n-\tpending = 0;\n-\tfor (i = 0; i < nfds; i++) {\n-\t\tDWORD avail = 0;\n-\t\tHANDLE h = (HANDLE) _get_osfhandle(ufds[i].fd);\n-\t\tif (h == INVALID_HANDLE_VALUE)\n-\t\t\treturn -1;\t/* errno was set */\n-\n-\t\tif (!(ufds[i].events & POLLIN))\n-\t\t\treturn errno = EINVAL, error(\"POLLIN not set\");\n-\n-\t\t/* this emulation works only for pipes */\n-\t\tif (!PeekNamedPipe(h, NULL, 0, NULL, &avail, NULL)) {\n-\t\t\tint err = GetLastError();\n-\t\t\tif (err == ERROR_BROKEN_PIPE) {\n-\t\t\t\tufds[i].revents = POLLHUP;\n-\t\t\t\tpending++;\n-\t\t\t} else {\n-\t\t\t\terrno = EINVAL;\n-\t\t\t\treturn error(\"PeekNamedPipe failed,\"\n-\t\t\t\t\t\" GetLastError: %u\", err);\n-\t\t\t}\n-\t\t} else if (avail) {\n-\t\t\tufds[i].revents = POLLIN;\n-\t\t\tpending++;\n-\t\t} else\n-\t\t\tufds[i].revents = 0;\n-\t}\n-\tif (!pending) {\n-\t\t/* The only times that we spin here is when the process\n-\t\t * that is connected through the pipes is waiting for\n-\t\t * its own input data to become available. But since\n-\t\t * the process (pack-objects) is itself CPU intensive,\n-\t\t * it will happily pick up the time slice that we are\n-\t\t * relinquishing here.\n-\t\t */\n-\t\tSleep(0);\n-\t\tgoto repeat;\n-\t}\n-\treturn 0;\n-}\n-\n struct tm *gmtime_r(const time_t *timep, struct tm *result)\n {\n \t/* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */\ndiff --git a/compat/mingw.h b/compat/mingw.h\nindex 51fca2f..99a7467 100644\n--- a/compat/mingw.h\n+++ b/compat/mingw.h\n@@ -59,16 +59,6 @@ struct passwd {\n \n extern char *getpass(const char *prompt);\n \n-#ifndef POLLIN\n-struct pollfd {\n-\tint fd;           /* file descriptor */\n-\tshort events;     /* requested events */\n-\tshort revents;    /* returned events */\n-};\n-#define POLLIN 1\n-#define POLLHUP 2\n-#endif\n-\n typedef void (__cdecl *sig_handler_t)(int);\n struct sigaction {\n \tsig_handler_t sa_handler;\n@@ -175,7 +165,6 @@ int pipe(int filedes[2]);\n unsigned int sleep (unsigned int seconds);\n int mkstemp(char *template);\n int gettimeofday(struct timeval *tv, void *tz);\n-int poll(struct pollfd *ufds, unsigned int nfds, int timeout);\n struct tm *gmtime_r(const time_t *timep, struct tm *result);\n struct tm *localtime_r(const time_t *timep, struct tm *result);\n int getpagesize(void);\t/* defined in MinGW's libgcc.a */\ndiff --git a/compat/win32/sys/poll.c b/compat/win32/sys/poll.c\nindex 7c52cb6..c1ca0d2 100644\n--- a/compat/win32/sys/poll.c\n+++ b/compat/win32/sys/poll.c\n@@ -24,8 +24,7 @@\n # pragma GCC diagnostic ignored \"-Wtype-limits\"\n #endif\n \n-#include <config.h>\n-#include <alloca.h>\n+#include <malloc.h>\n \n #include <sys/types.h>\n #include \"poll.h\"\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 56dce85..d0a1e48 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -105,9 +105,9 @@\n #include <regex.h>\n #include <utime.h>\n #include <syslog.h>\n+#include <sys/poll.h>\n #ifndef __MINGW32__\n #include <sys/wait.h>\n-#include <sys/poll.h>\n #include <sys/socket.h>\n #include <sys/ioctl.h>\n #include <termios.h>\n-- \n1.7.3.1.199.g72340\n"},{"id":"154061","messageId":"1287705944-5668-13-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 13/15] daemon: use socklen_t","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:42Z","receivedAt":"2010-10-22T00:05:42Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Windows's accept()-function takes the last argument as an int, but glibc\ntakes an unsigned int. Use socklen_t to get rid of a warning. This is\nbasically a revert of 7fa0908, but we have already been depending on\nsocklen_t existing since June 2006 (commit 5b276ee4). I guess this means\nthat socklen_t IS defined on OSX after all - at least in recent headers.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n daemon.c |    6 +++---\n 1 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex 19b4eb3..af13f4a 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -597,7 +597,7 @@ static struct child {\n \tstruct sockaddr_storage address;\n } *firstborn;\n \n-static void add_child(struct child_process *cld, struct sockaddr *addr, int addrlen)\n+static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen)\n {\n \tstruct child *newborn, **cradle;\n \n@@ -654,7 +654,7 @@ static void check_dead_children(void)\n }\n \n static char **cld_argv;\n-static void handle(int incoming, struct sockaddr *addr, int addrlen)\n+static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)\n {\n \tstruct child_process cld = { 0 };\n \tchar addrbuf[300] = \"REMOTE_ADDR=\", portbuf[300];\n@@ -904,7 +904,7 @@ static int service_loop(struct socketlist *socklist)\n \t\tfor (i = 0; i < socklist->nr; i++) {\n \t\t\tif (pfd[i].revents & POLLIN) {\n \t\t\t\tstruct sockaddr_storage ss;\n-\t\t\t\tunsigned int sslen = sizeof(ss);\n+\t\t\t\tsocklen_t sslen = sizeof(ss);\n \t\t\t\tint incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);\n \t\t\t\tif (incoming < 0) {\n \t\t\t\t\tswitch (errno) {\n-- \n1.7.3.1.199.g72340\n"},{"id":"154062","messageId":"1287705944-5668-14-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 14/15] daemon: make --inetd and --detcach incompatible","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:43Z","receivedAt":"2010-10-22T00:05:43Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Since --inetd makes main return with the result of execute() before\ndaemonize is gets called, these two options are already incompatible.\n\nDocument it, and add an error if attempted.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n Documentation/git-daemon.txt |    3 ++-\n daemon.c                     |    8 ++++----\n 2 files changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt\nindex 685aa58..053ded5 100644\n--- a/Documentation/git-daemon.txt\n+++ b/Documentation/git-daemon.txt\n@@ -78,7 +78,8 @@ OPTIONS\n \n --inetd::\n \tHave the server run as an inetd service. Implies --syslog.\n-\tIncompatible with --port, --listen, --user and --group options.\n+\tIncompatible with --detach, --port, --listen, --user and --group\n+\toptions.\n \n --listen=host_or_ipaddr::\n \tListen on a specific IP address or hostname.  IP addresses can\ndiff --git a/daemon.c b/daemon.c\nindex af13f4a..fc55367 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -23,10 +23,10 @@ static const char daemon_usage[] =\n \"           [--strict-paths] [--base-path=path] [--base-path-relaxed]\\n\"\n \"           [--user-path | --user-path=path]\\n\"\n \"           [--interpolated-path=path]\\n\"\n-\"           [--reuseaddr] [--detach] [--pid-file=file]\\n\"\n+\"           [--reuseaddr] [--pid-file=file]\\n\"\n \"           [--[enable|disable|allow-override|forbid-override]=service]\\n\"\n \"           [--inetd | [--listen=host_or_ipaddr] [--port=n]\\n\"\n-\"                      [--user=user [--group=group]]\\n\"\n+\"                      [--detach] [--user=user [--group=group]]\\n\"\n \"           [directory...]\";\n \n /* List of acceptable pathname prefixes */\n@@ -1122,8 +1122,8 @@ int main(int argc, char **argv)\n \t\t/* avoid splitting a message in the middle */\n \t\tsetvbuf(stderr, NULL, _IOFBF, 4096);\n \n-\tif (inetd_mode && (group_name || user_name))\n-\t\tdie(\"--user and --group are incompatible with --inetd\");\n+\tif (inetd_mode && (detach || group_name || user_name))\n+\t\tdie(\"--detach, --user and --group are incompatible with --inetd\");\n \n \tif (inetd_mode && (listen_port || (listen_addr.nr > 0)))\n \t\tdie(\"--listen= and --port= are incompatible with --inetd\");\n-- \n1.7.3.1.199.g72340\n"},{"id":"154063","messageId":"1287705944-5668-15-git-send-email-kusmabite@gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"[PATCH 15/15] daemon: opt-out on features that require posix","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:05:44Z","receivedAt":"2010-10-22T00:05:44Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"Windows does not supply the POSIX-functions fork(), setuuid(), setgid(),\nsetsid() and initgroups(). Error out if --user or --detach is specified\nwhen if so.\n\nMinGW doesn't have prototypes and headers for inet_ntop and inet_pton,\nso include our implementation instead. MSVC does, so avoid doing so\nthere.\n\nSigned-off-by: Erik Faye-Lund <kusmabite@gmail.com>\n---\n Makefile |   14 ++++++---\n daemon.c |   90 +++++++++++++++++++++++++++++++++++++++++++++----------------\n 2 files changed, 75 insertions(+), 29 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 46034bf..53986b1 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -401,6 +401,7 @@ EXTRA_PROGRAMS =\n # ... and all the rest that could be moved out of bindir to gitexecdir\n PROGRAMS += $(EXTRA_PROGRAMS)\n \n+PROGRAM_OBJS += daemon.o\n PROGRAM_OBJS += fast-import.o\n PROGRAM_OBJS += imap-send.o\n PROGRAM_OBJS += shell.o\n@@ -1066,7 +1067,6 @@ ifeq ($(uname_S),Windows)\n \tNO_SVN_TESTS = YesPlease\n \tNO_PERL_MAKEMAKER = YesPlease\n \tRUNTIME_PREFIX = YesPlease\n-\tNO_POSIX_ONLY_PROGRAMS = YesPlease\n \tNO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease\n \tNO_NSEC = YesPlease\n \tUSE_WIN32_MMAP = YesPlease\n@@ -1077,6 +1077,7 @@ ifeq ($(uname_S),Windows)\n \tNO_CURL = YesPlease\n \tNO_PYTHON = YesPlease\n \tBLK_SHA1 = YesPlease\n+\tNO_POSIX_GOODIES = UnfortunatelyYes\n \tNATIVE_CRLF = YesPlease\n \n \tCC = compat/vcbuild/scripts/clink.pl\n@@ -1119,7 +1120,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))\n \tNO_SVN_TESTS = YesPlease\n \tNO_PERL_MAKEMAKER = YesPlease\n \tRUNTIME_PREFIX = YesPlease\n-\tNO_POSIX_ONLY_PROGRAMS = YesPlease\n \tNO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease\n \tNO_NSEC = YesPlease\n \tUSE_WIN32_MMAP = YesPlease\n@@ -1130,6 +1130,9 @@ ifneq (,$(findstring MINGW,$(uname_S)))\n \tNO_PYTHON = YesPlease\n \tBLK_SHA1 = YesPlease\n \tETAGS_TARGET = ETAGS\n+\tNO_INET_PTON = YesPlease\n+\tNO_INET_NTOP = YesPlease\n+\tNO_POSIX_GOODIES = UnfortunatelyYes\n \tCOMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32\n \tCOMPAT_CFLAGS += -DSTRIP_EXTENSION=\\\".exe\\\"\n \tCOMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \\\n@@ -1249,9 +1252,6 @@ ifdef ZLIB_PATH\n endif\n EXTLIBS += -lz\n \n-ifndef NO_POSIX_ONLY_PROGRAMS\n-\tPROGRAM_OBJS += daemon.o\n-endif\n ifndef NO_OPENSSL\n \tOPENSSL_LIBSSL = -lssl\n \tifdef OPENSSLDIR\n@@ -1419,6 +1419,10 @@ ifdef NO_DEFLATE_BOUND\n \tBASIC_CFLAGS += -DNO_DEFLATE_BOUND\n endif\n \n+ifdef NO_POSIX_GOODIES\n+\tBASIC_CFLAGS += -DNO_POSIX_GOODIES\n+endif\n+\n ifdef BLK_SHA1\n \tSHA1_HEADER = \"block-sha1/sha1.h\"\n \tLIB_OBJS += block-sha1/sha1.o\ndiff --git a/daemon.c b/daemon.c\nindex fc55367..64646cd 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -26,7 +26,9 @@ static const char daemon_usage[] =\n \"           [--reuseaddr] [--pid-file=file]\\n\"\n \"           [--[enable|disable|allow-override|forbid-override]=service]\\n\"\n \"           [--inetd | [--listen=host_or_ipaddr] [--port=n]\\n\"\n+#ifndef NO_POSIX_GOODIES\n \"                      [--detach] [--user=user [--group=group]]\\n\"\n+#endif\n \"           [directory...]\";\n \n /* List of acceptable pathname prefixes */\n@@ -934,6 +936,62 @@ static void sanitize_stdfds(void)\n \t\tclose(fd);\n }\n \n+#ifdef NO_POSIX_GOODIES\n+\n+struct credentials;\n+\n+static void drop_privileges(struct credentials *cred)\n+{\n+\t/* nothing */\n+}\n+\n+static void daemonize(void)\n+{\n+\tdie(\"--detach not supported on this platform\");\n+}\n+\n+static struct credentials *prepare_credentials(const char *user_name,\n+    const char *group_name)\n+{\n+\tdie(\"--user not supported on this platform\");\n+}\n+\n+#else\n+\n+struct credentials {\n+\tstruct passwd *pass;\n+\tgid_t gid;\n+};\n+\n+static void drop_privileges(struct credentials *cred)\n+{\n+\tif (cred && (initgroups(cred->pass->pw_name, cred->gid) ||\n+\t    setgid (cred->gid) || setuid(cred->pass->pw_uid)))\n+\t\tdie(\"cannot drop privileges\");\n+}\n+\n+static struct credentials *prepare_credentials(const char *user_name,\n+    const char *group_name)\n+{\n+\tstatic struct credentials c;\n+\n+\tc.pass = getpwnam(user_name);\n+\tif (!c.pass)\n+\t\tdie(\"user not found - %s\", user_name);\n+\n+\tif (!group_name)\n+\t\tc.gid = c.pass->pw_gid;\n+\telse {\n+\t\tstruct group *group = getgrnam(group_name);\n+\t\tif (!group)\n+\t\t\tdie(\"group not found - %s\", group_name);\n+\n+\t\tc.gid = group->gr_gid;\n+\t}\n+\n+\treturn &c;\n+}\n+\n static void daemonize(void)\n {\n \tswitch (fork()) {\n@@ -951,6 +1009,7 @@ static void daemonize(void)\n \tclose(2);\n \tsanitize_stdfds();\n }\n+#endif\n \n static void store_pid(const char *path)\n {\n@@ -961,7 +1020,8 @@ static void store_pid(const char *path)\n \t\tdie_errno(\"failed to write pid file '%s'\", path);\n }\n \n-static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid)\n+static int serve(struct string_list *listen_addr, int listen_port,\n+    struct credentials *cred)\n {\n \tstruct socketlist socklist = { NULL, 0, 0 };\n \n@@ -970,10 +1030,7 @@ static int serve(struct string_list *listen_addr, int listen_port, struct passwd\n \t\tdie(\"unable to allocate any listen sockets on port %u\",\n \t\t    listen_port);\n \n-\tif (pass && gid &&\n-\t    (initgroups(pass->pw_name, gid) || setgid (gid) ||\n-\t     setuid(pass->pw_uid)))\n-\t\tdie(\"cannot drop privileges\");\n+\tdrop_privileges(cred);\n \n \treturn service_loop(&socklist);\n }\n@@ -985,9 +1042,7 @@ int main(int argc, char **argv)\n \tint serve_mode = 0, inetd_mode = 0;\n \tconst char *pid_file = NULL, *user_name = NULL, *group_name = NULL;\n \tint detach = 0;\n-\tstruct passwd *pass = NULL;\n-\tstruct group *group;\n-\tgid_t gid = 0;\n+\tstruct credentials *cred = NULL;\n \tint i;\n \n \tgit_extract_argv0_path(argv[0]);\n@@ -1133,21 +1188,8 @@ int main(int argc, char **argv)\n \tif (group_name && !user_name)\n \t\tdie(\"--group supplied without --user\");\n \n-\tif (user_name) {\n-\t\tpass = getpwnam(user_name);\n-\t\tif (!pass)\n-\t\t\tdie(\"user not found - %s\", user_name);\n-\n-\t\tif (!group_name)\n-\t\t\tgid = pass->pw_gid;\n-\t\telse {\n-\t\t\tgroup = getgrnam(group_name);\n-\t\t\tif (!group)\n-\t\t\t\tdie(\"group not found - %s\", group_name);\n-\n-\t\t\tgid = group->gr_gid;\n-\t\t}\n-\t}\n+\tif (user_name)\n+\t\tcred = prepare_credentials(user_name, group_name);\n \n \tif (strict_paths && (!ok_paths || !*ok_paths))\n \t\tdie(\"option --strict-paths requires a whitelist\");\n@@ -1181,5 +1223,5 @@ int main(int argc, char **argv)\n \tcld_argv[argc] = \"--serve\";\n \tcld_argv[argc+1] = NULL;\n \n-\treturn serve(&listen_addr, listen_port, pass, gid);\n+\treturn serve(&listen_addr, listen_port, cred);\n }\n-- \n1.7.3.1.199.g72340\n"},{"id":"154065","messageId":"20101022001010.GB13779@burratino","threadId":"25510","inReplyTo":"1287705944-5668-7-git-send-email-kusmabite@gmail.com","subject":"Re: [PATCH 07/15] daemon: use run-command api for async serving","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-10-22T00:10:10Z","receivedAt":"2010-10-22T00:10:10Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Erik Faye-Lund wrote:\n\n> --- a/daemon.c\n> +++ b/daemon.c\n[...]\n> @@ -671,18 +658,26 @@ static void check_dead_children(void)\n>  \tint status;\n>  \tpid_t pid;\n>  \n> -\twhile ((pid = waitpid(-1, &status, WNOHANG)) > 0) {\n> +\tstruct child **cradle, *blanket;\n> +\tfor (cradle = &firstborn; (blanket = *cradle);)\n> +\t\tif ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) {\n\nWhat is this change (> 0 → > 1) about?\n"},{"id":"154064","messageId":"AANLkTinGABTRegSCCboRafGknU_B_faFrMC-vxtCHE++@mail.gmail.com","threadId":"25510","inReplyTo":"1287705944-5668-1-git-send-email-kusmabite@gmail.com","subject":"Re: [PATCH 01/15] mingw: implement syslog","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:13:26Z","receivedAt":"2010-10-22T00:13:26Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"I'm sorry for the noise, but this was incorrectly sent out. It's\nmissing the first patch, so I'll resend in a little while with a\nproper cover letter etc...\n"},{"id":"154066","messageId":"AANLkTikL-uWKUtcB=NS+42ajAGrLH1B9CEE6B-0Ykeiq@mail.gmail.com","threadId":"25510","inReplyTo":"20101022001010.GB13779@burratino","subject":"Re: [PATCH 07/15] daemon: use run-command api for async serving","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@gmail.com","sentAt":"2010-10-22T00:20:09Z","receivedAt":"2010-10-22T00:20:09Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"On Fri, Oct 22, 2010 at 2:10 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Erik Faye-Lund wrote:\n>\n>> --- a/daemon.c\n>> +++ b/daemon.c\n> [...]\n>> @@ -671,18 +658,26 @@ static void check_dead_children(void)\n>>       int status;\n>>       pid_t pid;\n>>\n>> -     while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {\n>> +     struct child **cradle, *blanket;\n>> +     for (cradle = &firstborn; (blanket = *cradle);)\n>> +             if ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) {\n>\n> What is this change (> 0 → > 1) about?\n>\n\nOooh, that's a typo, nice catch! I'll throw in a hot-fix when reposting!\n"}]}