[PATCH]: glob win32 compatibility fixes, fnmatch license, glthread cond win32 compilation problem
Hi, Attached are a few patch that fixes glob and glthread/cond modules compilation problem under MinGW. Additionally, a third patch fixes a licensing problem with the fnmatch module: fnmatch license was changed to LGPLv2+, but the fnmatch-posix and fnmatch-gnu associated modules are still GPL. Regards, -- Yoann Vandoorselaere [EMAIL PROTECTED] diff --git a/lib/glob.c b/lib/glob.c index 24aec87..5139a90 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -43,7 +43,9 @@ # define POSIX #endif -#include pwd.h +#ifndef WIN32 +# include pwd.h +#endif #include errno.h #ifndef __set_errno @@ -81,7 +83,7 @@ /* If the system has the `struct dirent64' type we use it internally. */ #if defined _LIBC !defined COMPILE_GLOB64 -# if (defined POSIX || defined WINDOWS32) !defined __GNU_LIBRARY__ +# if (defined POSIX || defined WIN32) !defined __GNU_LIBRARY__ # define CONVERT_D_INO(d64, d32) # else # define CONVERT_D_INO(d64, d32) \ @@ -102,7 +104,7 @@ #endif -#if (defined POSIX || defined WINDOWS32) !defined __GNU_LIBRARY__ +#if (defined POSIX || defined WIN32) !defined __GNU_LIBRARY__ /* Posix does not require that the d_ino field be present, and some systems do not provide it. */ # define REAL_DIR_ENTRY(dp) 1 @@ -423,14 +425,14 @@ glob (pattern, flags, errfunc, pglob) /* Find the filename. */ filename = strrchr (pattern, '/'); -#if defined __MSDOS__ || defined WINDOWS32 +#if defined __MSDOS__ || defined WIN32 /* The case of d:pattern. Since `:' is not allowed in file names, we can safely assume that wherever it happens in pattern, it signals the filename part. This is so we could some day support patterns like [a-z]:foo. */ if (filename == NULL) filename = strchr (pattern, ':'); -#endif /* __MSDOS__ || WINDOWS32 */ +#endif /* __MSDOS__ || WIN32 */ dirname_modified = 0; if (filename == NULL) { @@ -470,7 +472,7 @@ glob (pattern, flags, errfunc, pglob) { char *newp; dirlen = filename - pattern; -#if defined __MSDOS__ || defined WINDOWS32 +#if defined __MSDOS__ || defined WIN32 if (*filename == ':' || (filename pattern + 1 filename[-1] == ':')) { @@ -494,7 +496,7 @@ glob (pattern, flags, errfunc, pglob) ++filename; if (filename[0] == '\0' -#if defined __MSDOS__ || defined WINDOWS32 +#if defined __MSDOS__ || defined WIN32 dirname[dirlen - 1] != ':' (dirlen 3 || dirname[dirlen - 2] != ':' || dirname[dirlen - 1] != '/') @@ -564,7 +566,7 @@ glob (pattern, flags, errfunc, pglob) if (home_dir == NULL || home_dir[0] == '\0') home_dir = SYS:; # else -# ifdef WINDOWS32 +# ifdef WIN32 if (home_dir == NULL || home_dir[0] == '\0') home_dir = c:/users/default; /* poor default */ # else @@ -629,7 +631,7 @@ glob (pattern, flags, errfunc, pglob) else home_dir = ~; /* No luck. */ } -# endif /* WINDOWS32 */ +# endif /* WIN32 */ # endif /* Now construct the full directory. */ if (dirname[1] == '\0') @@ -649,7 +651,7 @@ glob (pattern, flags, errfunc, pglob) } dirname_modified = 1; } -# if !defined _AMIGA !defined WINDOWS32 +# if !defined _AMIGA !defined WIN32 else { char *end_name = strchr (dirname, '/'); @@ -765,7 +767,7 @@ glob (pattern, flags, errfunc, pglob) home directory. */ return GLOB_NOMATCH; } -# endif /* Not Amiga not WINDOWS32. */ +# endif /* Not Amiga not WIN32. */ } /* Now test whether we looked for ~ or ~NAME. In this case we @@ -1113,7 +1115,7 @@ prefix_array (const char *dirname, char **array, size_t n) { register size_t i; size_t dirlen = strlen (dirname); -#if defined __MSDOS__ || defined WINDOWS32 +#if defined __MSDOS__ || defined WIN32 int sep_char = '/'; # define DIRSEP_CHAR sep_char #else @@ -1124,7 +1126,7 @@ prefix_array (const char *dirname, char **array, size_t n) /* DIRNAME is just /, so normal prepending would get us //foo. We want /foo instead, so don't prepend any chars from DIRNAME. */ dirlen = 0; -#if defined __MSDOS__ || defined WINDOWS32 +#if defined __MSDOS__ || defined WIN32 else if (dirlen 1) { if (dirname[dirlen - 1] == '/' dirname[dirlen - 2] == ':') diff --git a/lib/glthread/cond.h b/lib/glthread/cond.h index f71e627..a9fc699 100644 --- a/lib/glthread/cond.h +++ b/lib/glthread/cond.h @@ -269,7 +269,7 @@ typedef pthread_cond_t gl_cond_t; /* = */ -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS) +#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS) /* Provide dummy implementation if threads are not supported. */ @@ -285,6 +285,10 @@ typedef int gl_cond_t; #endif +#if USE_WIN32_THREADS +# define ETIMEDOUT WSAETIMEDOUT +#endif + /* = */ /* Macros with built-in error
[PATCH]: poll module issue on Win32
Hi Paolo, Attached is a patch that fixes the poll() module to work on WIN32 systems with unconnected socket (example: server socket). Regards, -- Yoann Vandoorselaere | Responsable RD / CTO | PreludeIDS Technologies Tel: +33 (0)8 70 70 21 58 Fax: +33(0)4 78 42 21 58 http://www.prelude-ids.com diff --git a/lib/poll.c b/lib/poll.c index 4a62dc1..e0714f0 100644 --- a/lib/poll.c +++ b/lib/poll.c @@ -180,6 +180,12 @@ poll (pfd, nfd, timeout) #else char data[64]; r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK); + +# ifdef WIN32 + if (r 0 GetLastError() == 10057) /* server socket */ + socket_errno = ENOTCONN; + else +# endif socket_errno = (r 0) ? errno : 0; #endif if (r == 0)
Re: [PATCH]: poll module issue on Win32
Yoann Vandoorselaere wrote: Hi Paolo, Attached is a patch that fixes the poll() module to work on WIN32 systems with unconnected socket (example: server socket). Committed. In the meanwhile I have forward-ported it to my reimplementation of poll() for WIN32, which I attach (not even compiled, unfortunately) and would very much like to have feedback on. Thanks! Paolo diff --git a/ChangeLog b/ChangeLog index 3375a19..4ffbb6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,3 @@ -2008-09-11 Yoann Vandoorselaere [EMAIL PROTECTED] - - * lib/poll.c (poll): Fix polling unconnected server sockets on WIN32. - 2008-09-11 Jim Meyering [EMAIL PROTECTED] * users.txt: Add gtk-vnc. diff --git a/lib/poll.c b/lib/poll.c index e0714f0..84ac058 100644 --- a/lib/poll.c +++ b/lib/poll.c @@ -25,9 +25,19 @@ #include poll.h #include errno.h #include limits.h +#include assert.h + +#ifdef __MSVCRT__ +#include windows.h +#include winsock2.h +#include io.h +#include stdio.h +#include conio.h +#else #include sys/socket.h #include sys/select.h #include unistd.h +#endif #ifdef HAVE_SYS_IOCTL_H #include sys/ioctl.h @@ -48,12 +58,219 @@ #define MSG_PEEK 0 #endif +#ifdef __MSVCRT__ + +/* Declare data structures for ntdll functions. */ +typedef struct _FILE_PIPE_LOCAL_INFORMATION { + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; + +typedef struct _IO_STATUS_BLOCK +{ + union { +DWORD Status; +PVOID Pointer; + } u; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +#define FilePipeLocalInformation 24 + +typedef DWORD (WINAPI *PNtQueryInformationFile) +(HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS); + +#ifndef PIPE_BUF +#define PIPE_BUF 512 +#endif + +/* Compute revents values for file handle H. */ + +static int +win32_compute_revents (HANDLE h, int sought) +{ + int i, ret, happened; + INPUT_RECORD *irbuffer; + DWORD avail, nbuffer; + BOOL bRet; + IO_STATUS_BLOCK iosb; + FILE_PIPE_LOCAL_INFORMATION fpli; + static PNtQueryInformationFile NtQueryInformationFile; + + ret = WaitForSingleObject (h, 0); + if (ret != WAIT_OBJECT_0) +return sought (POLLOUT | POLLWRNORM | POLLWRBAND); + + switch (GetFileType (h)) +{ +case FILE_TYPE_PIPE: + if (!NtQueryInformationFile) + NtQueryInformationFile = (PNtQueryInformationFile) + GetProcAddress (GetModuleHandle (ntdll.dll), + NtQueryInformationFile); + + happened = 0; + if (!PeekNamedPipe (h, NULL, 0, NULL, avail, NULL)) + return POLLERR; + + if (avail) + happened |= sought (POLLIN | POLLRDNORM); + + memset (iosb, 0, sizeof (iosb)); + memset (fpli, 0, sizeof (fpli)); + + /* If NtQueryInformationFile fails, optimistically assume the pipe is +writable. This could happen on Win9x, because NtQueryInformationFile +is not available, or if we inherit a pipe that doesn't permit +FILE_READ_ATTRIBUTES access on the write end (I think this should +not happen since WinXP SP2; WINE seems fine too). Otherwise, +ensure that enough space is available for atomic writes. */ + if (NtQueryInformationFile (h, iosb, fpli, sizeof (fpli), + FilePipeLocalInformation) + || fpli.WriteQuotaAvailable = PIPE_BUF + || (fpli.OutboundQuota PIPE_BUF + fpli.WriteQuotaAvailable == fpli.OutboundQuota)) + happened |= sought (POLLOUT | POLLWRNORM | POLLWRBAND); + + return happened; + +case FILE_TYPE_CHAR: + nbuffer = avail = 0; + bRet = GetNumberOfConsoleInputEvents (h, nbuffer); + if (!bRet || nbuffer == 0) +return POLLHUP; + + irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD)); + bRet = PeekConsoleInput (h, irbuffer, nbuffer, avail); + if (!bRet || avail == 0) +return POLLHUP; + + for (i = 0; i avail; i++) +if (irbuffer[i].EventType == KEY_EVENT) + return sought ~(POLLPRI | POLLRDBAND); + + return sought (POLLOUT | POLLWRNORM | POLLWRBAND); + +default: + return sought ~(POLLPRI | POLLRDBAND); +} +} + +/* Convert fd_sets returned by select into revents values. */ + +static int +win32_compute_revents_socket (SOCKET h, int sought, + fd_set *rfds, fd_set *wfds, fd_set *efds) +{ + int happened = 0; + + if (FD_ISSET (h, rfds)) +{ + int r, error; + + char data[64]; + WSASetLastError (0); + r = recv (h, data, sizeof (data), MSG_PEEK); + + /* If the event happened on an unconnected server socket, that's fine. */ + if (r 0 GetLastError() == 10057) + r = 1; + +
[PATCH] Use `AC_C_RESTRICT' in `time'
Hi, The following patch makes sure `time' uses `AC_C_RESTRICT'. This fixes compilation at least on MinGW as reported here: http://thread.gmane.org/gmane.lisp.guile.bugs/3984 Thanks, Ludovic. From 06dc37c4ee56e9d32bfcb79ace9221c903ade7b2 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Ludovic=20Court=C3=A8s?= [EMAIL PROTECTED] Date: Thu, 11 Sep 2008 21:27:23 +0200 Subject: [PATCH] time: Use `AC_C_RESTRICT'. * modules/time (configure.ac): Add `AC_C_RESTRICT'. Fixes compilation on MinGW. Reported by Han-Wen Nienhuys [EMAIL PROTECTED]. --- modules/time |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/modules/time b/modules/time index 50b07af..8b28dda 100644 --- a/modules/time +++ b/modules/time @@ -10,6 +10,7 @@ extensions include_next configure.ac: +AC_C_RESTRICT gl_HEADER_TIME_H Makefile.am: -- 1.6.0
Re: [PATCH]: poll module issue on Win32
Yoann Vandoorselaere wrote: r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK); + +# ifdef WIN32 + if (r 0 GetLastError() == 10057) /* server socket */ + socket_errno = ENOTCONN; + else +# endif I thought that after using a winsock function, you need to check WSAGetLastError() and not GetLastError()? [1] Also, is there no symbolic, self-explanatory name instead of 10057? Bruno [1] http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx
Re: [PATCH] Use `AC_C_RESTRICT' in `time'
Ludovic Courtès wrote: The following patch makes sure `time' uses `AC_C_RESTRICT'. This is redundant, because gl_HEADER_TIME_H requires gl_HEADER_TIME_H_BODY which requires AC_C_RESTRICT. This fixes compilation at least on MinGW as reported here: http://thread.gmane.org/gmane.lisp.guile.bugs/3984 The user's problem can be tracked down as follows: - Check that configure contains an expansion of AC_C_RESTRICT. - Check that config.h.in contains a section for 'restrict'. - Check that config.h contains a definition for 'restrict'. If not, check the config.log for explanations. Maybe the user simply attempted to build the package with a different compiler than with the one with which the configure script was run? This is not supported. Or maybe some subdirectories are built with gcc and others with gcc -std=gnu99 or similar? Bruno
Re: [PATCH]: fnmatch license
Yoann Vandoorselaere wrote: Additionally, a third patch fixes a licensing problem with the fnmatch module: fnmatch license was changed to LGPLv2+, but the fnmatch-posix and fnmatch-gnu associated modules are still GPL. I applied your patch: No relicensing of files is needed, because these modules have no files of their own in lib/. Bruno 2008-09-11 Yoann Vandoorselaere [EMAIL PROTECTED] * modules/fnmatch-posix (License): Change to LGPLv2+. * modules/fnmatch-gnu (License): Likewise.
Re: [PATCH]: glob win32 compatibility fixes
Hi Yoann, Attached are a few patch that fixes glob ... compilation problem under MinGW. A couple of details in this patch can be improved: - The predefine 'WIN32' is sometimes also defined for Cygwin, and is not defined on some native Win32 platforms. The right test for platforms that use the MSVCRT is (defined _WIN32 || defined __WIN32__) ! defined __CYGWIN__ - You comment out the use of pwd.h and provide no replacement. Nowadays, Windows systems have a home directory per user, but getenv(HOME) is usually not set. The standard way to get the home directory is getenv(HOMEDRIVE) and getenv(HOMEPATH) and glue the two strings together (by simple string concatenation). Bruno
Re: [PATCH]: glthread cond win32 compilation problem
Yoann Vandoorselaere wrote: Attached are a few patch that fixes ... glthread/cond modules compilation problem under MinGW. I'm applying the first hunk: 2008-09-11 Yoann Vandoorselaere [EMAIL PROTECTED] * lib/glthread/cond.h: Use dummy implementation also if USE_WIN32_THREADS. --- a/lib/glthread/cond.h +++ b/lib/glthread/cond.h @@ -269,7 +269,7 @@ typedef pthread_cond_t gl_cond_t; /* = */ -#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS) +#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS) /* Provide dummy implementation if threads are not supported. */ - About the second hunk, the problem is more general: not only on mingw, but on all platforms which lack ETIMEDOUT, one needs a substitute. It can be a random positive number. I propose this patch instead. 2008-09-11 Yoann Vandoorselaere [EMAIL PROTECTED] Bruno Haible [EMAIL PROTECTED] * lib/glthread/cond.h (ETIMEDOUT): Define to a fallback value if not defined by errno.h. *** lib/glthread/cond.h.orig2008-09-12 02:38:56.0 +0200 --- lib/glthread/cond.h 2008-09-12 02:38:31.0 +0200 *** *** 283,288 --- 283,294 # define glthread_cond_broadcast(COND) 0 # define glthread_cond_destroy(COND) 0 + /* Possible return value of glthread_cond_timedwait. +Use a random value as fallback replacement. */ + # ifndef ETIMEDOUT + # define ETIMEDOUT 1789 + # endif + #endif /* = */ - Additionally, the use of #define ETIMEDOUT ETIME in the Solaris case is incorrect: Solaris has ETIMEDOUT, and it's a no-no to redefine errno values in header files that user code may include. I propose this instead: 2008-09-11 Bruno Haible [EMAIL PROTECTED] * lib/glthread/cond.h [USE_SOLARIS_THREADS] (ETIMEDOUT): Remove macro. (glthread_cond_timedwait_multithreaded): New declaration. (glthread_cond_timedwait): Use it. * lib/glthread/cond.c [USE_SOLARIS_THREADS] (glthread_cond_timedwait_multithreaded): New function. *** lib/glthread/cond.h.orig2008-09-12 02:49:46.0 +0200 --- lib/glthread/cond.h 2008-09-12 02:49:41.0 +0200 *** *** 239,246 /* -- gl_cond_t datatype -- */ - #define ETIMEDOUT ETIME - typedef pthread_cond_t gl_cond_t; # define gl_cond_define(STORAGECLASS, NAME) \ STORAGECLASS cond_t NAME; --- 239,244 *** *** 253,265 # define glthread_cond_wait(COND, LOCK) \ (pthread_in_use () ? cond_wait (COND, LOCK) : 0) # define glthread_cond_timedwait(COND, LOCK, ABSTIME) \ ! (pthread_in_use () ? cond_timedwait (COND, LOCK, ABSTIME) : 0) # define glthread_cond_signal(COND) \ (pthread_in_use () ? cond_signal (COND) : 0) # define glthread_cond_broadcast(COND) \ (pthread_in_use () ? cond_broadcast (COND) : 0) # define glthread_cond_destroy(COND) \ (pthread_in_use () ? cond_destroy (COND) : 0) # ifdef __cplusplus } --- 251,264 # define glthread_cond_wait(COND, LOCK) \ (pthread_in_use () ? cond_wait (COND, LOCK) : 0) # define glthread_cond_timedwait(COND, LOCK, ABSTIME) \ ! (pthread_in_use () ? glthread_cond_timedwait_multithreaded (COND, LOCK, ABSTIME) : 0) # define glthread_cond_signal(COND) \ (pthread_in_use () ? cond_signal (COND) : 0) # define glthread_cond_broadcast(COND) \ (pthread_in_use () ? cond_broadcast (COND) : 0) # define glthread_cond_destroy(COND) \ (pthread_in_use () ? cond_destroy (COND) : 0) + extern int glthread_cond_timedwait_multithreaded (gl_cond_t *cond, gl_lock_t *lock, struct timespec *abstime); # ifdef __cplusplus } *** lib/glthread/cond.c.orig2008-09-12 02:49:46.0 +0200 --- lib/glthread/cond.c 2008-09-12 02:43:34.0 +0200 *** *** 50,52 --- 50,73 #endif /* = */ + + #if USE_SOLARIS_THREADS + + /* -- gl_cond_t datatype -- */ + + int + glthread_cond_timedwait_multithreaded (gl_cond_t *cond, + gl_lock_t *lock, + struct timespec *abstime) + { + int ret; + + ret = cond_timedwait (cond, lock, abstime); + if (ret == ETIME) + return ETIMEDOUT; + return ret; + } + + #endif + + /* = */
Re: [PATCH] Use `AC_C_RESTRICT' in `time'
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Bruno Haible on 9/11/2008 5:45 PM: Ludovic Courtès wrote: The following patch makes sure `time' uses `AC_C_RESTRICT'. This is redundant, because gl_HEADER_TIME_H requires gl_HEADER_TIME_H_BODY which requires AC_C_RESTRICT. Maybe the user simply attempted to build the package with a different compiler than with the one with which the configure script was run? This is not supported. Could it also be a case of not including config.h before system headers? - -- Don't work too hard, make some time for fun as well! Eric Blake [EMAIL PROTECTED] -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkjJwhIACgkQ84KuGfSFAYAc9gCgw0yoCzxQGLjUzr8lIy1fekFu shcAoK2ctI+/T5jzf/mon3hHAfTJvcEL =2oSt -END PGP SIGNATURE-
Re: [PATCH]: poll module issue on Win32
Bruno Haible wrote: Yoann Vandoorselaere wrote: r = recv (pfd[i].fd, data, sizeof (data), MSG_PEEK); + +# ifdef WIN32 + if (r 0 GetLastError() == 10057) /* server socket */ + socket_errno = ENOTCONN; + else +# endif I thought that after using a winsock function, you need to check WSAGetLastError() and not GetLastError()? [1] Also, is there no symbolic, self-explanatory name instead of 10057? It is temporary anyway; Yoann seems to be the main user of poll on Win32 and if he helps testing the native implementation, it will get in sooner. Paolo