From 30d64a697c5b119bfe6a52ccaaeea46f049b72c1 Mon Sep 17 00:00:00 2001 From: Alexpux Date: Tue, 11 Feb 2014 15:17:44 +0400 Subject: [PATCH] Add gdbm package. --- mingw-w64-gdbm/PKGBUILD | 57 ++ mingw-w64-gdbm/gdbm-1.10-zeroheaders.patch | 33 + mingw-w64-gdbm/gdbm-win32-support.patch | 951 +++++++++++++++++++++ 3 files changed, 1041 insertions(+) create mode 100644 mingw-w64-gdbm/PKGBUILD create mode 100644 mingw-w64-gdbm/gdbm-1.10-zeroheaders.patch create mode 100644 mingw-w64-gdbm/gdbm-win32-support.patch diff --git a/mingw-w64-gdbm/PKGBUILD b/mingw-w64-gdbm/PKGBUILD new file mode 100644 index 0000000000..f128ca44fe --- /dev/null +++ b/mingw-w64-gdbm/PKGBUILD @@ -0,0 +1,57 @@ +# Maintainer: Alexey Pavlov + +_realname=gdbm +_mingw_suff=mingw-w64-${CARCH} +pkgname=("${_mingw_suff}-${_realname}") +pkgver=1.10 +pkgrel=1 +pkgdesc="GNU database library (mingw-w64)" +arch=('any') +url="http://www.gnu.org/software/gdbm/gdbm.html" +license=('GPL3') +depends=("${_mingw_suff}-gcc-libs" "${_mingw_suff}-gettext" "${_mingw_suff}-libiconv" ) +makedepends=("${_mingw_suff}-gcc") +options=('staticlibs') +source=(ftp://ftp.gnu.org/gnu/gdbm/${_realname}-${pkgver}.tar.gz{,.sig} + 'gdbm-1.10-zeroheaders.patch' + 'gdbm-win32-support.patch') +md5sums=('88770493c2559dc80b561293e39d3570' + 'SKIP' + 'ac255b10452005237836cd2d3a470733' + 'ce7d37d8d7cfc895ccd04a59adabbbbe') + +prepare() { + cd ${srcdir}/${_realname}-${pkgver} + + patch -p1 -i ${srcdir}/gdbm-1.10-zeroheaders.patch + patch -p1 -i ${srcdir}/gdbm-win32-support.patch + + autoreconf --install --force +} + +build() { + [[ -d ${srcdir}/build-${MINGW_CHOST} ]] && rm -rf ${srcdir}/build-${MINGW_CHOST} + mkdir ${srcdir}/build-${MINGW_CHOST} + cd ${srcdir}/build-${MINGW_CHOST} + + ${srcdir}/${_realname}-${pkgver}/configure \ + --build=${MINGW_CHOST} \ + --host=${MINGW_CHOST} \ + --target=${MINGW_CHOST} \ + --prefix=${MINGW_PREFIX} \ + --enable-static \ + --enable-shared \ + --enable-libgdbm-compat + + make +} + +check() { + cd ${srcdir}/build-${MINGW_CHOST} + make check +} + +package() { + cd ${srcdir}/build-${MINGW_CHOST} + make DESTDIR=${pkgdir} install +} diff --git a/mingw-w64-gdbm/gdbm-1.10-zeroheaders.patch b/mingw-w64-gdbm/gdbm-1.10-zeroheaders.patch new file mode 100644 index 0000000000..a268f6bdfa --- /dev/null +++ b/mingw-w64-gdbm/gdbm-1.10-zeroheaders.patch @@ -0,0 +1,33 @@ +diff -up gdbm-1.10/src/falloc.c.zeroheaders gdbm-1.10/src/falloc.c +--- gdbm-1.10/src/falloc.c.zeroheaders 2011-11-11 11:59:11.000000000 +0100 ++++ gdbm-1.10/src/falloc.c 2011-11-14 17:34:32.487604027 +0100 +@@ -255,7 +255,7 @@ push_avail_block (GDBM_FILE dbf) + + + /* Split the header block. */ +- temp = (avail_block *) malloc (av_size); ++ temp = (avail_block *) calloc (1, av_size); + if (temp == NULL) _gdbm_fatal (dbf, _("malloc error")); + /* Set the size to be correct AFTER the pop_avail_block. */ + temp->size = dbf->header->avail.size; +diff -up gdbm-1.10/src/gdbmopen.c.zeroheaders gdbm-1.10/src/gdbmopen.c +--- gdbm-1.10/src/gdbmopen.c.zeroheaders 2011-11-11 19:39:42.000000000 +0100 ++++ gdbm-1.10/src/gdbmopen.c 2011-11-14 17:33:24.867608650 +0100 +@@ -264,7 +264,7 @@ gdbm_open (const char *file, int block_s + (dbf->header->block_size - sizeof (hash_bucket)) + / sizeof (bucket_element) + 1; + dbf->header->bucket_size = dbf->header->block_size; +- dbf->bucket = (hash_bucket *) malloc (dbf->header->bucket_size); ++ dbf->bucket = (hash_bucket *) calloc (1, dbf->header->bucket_size); + if (dbf->bucket == NULL) + { + gdbm_close (dbf); +@@ -456,7 +456,7 @@ _gdbm_init_cache(GDBM_FILE dbf, size_t s + for(index = 0; index < size; index++) + { + (dbf->bucket_cache[index]).ca_bucket +- = (hash_bucket *) malloc (dbf->header->bucket_size); ++ = (hash_bucket *) calloc (1, dbf->header->bucket_size); + if ((dbf->bucket_cache[index]).ca_bucket == NULL) + { + gdbm_errno = GDBM_MALLOC_ERROR; diff --git a/mingw-w64-gdbm/gdbm-win32-support.patch b/mingw-w64-gdbm/gdbm-win32-support.patch new file mode 100644 index 0000000000..0237132c96 --- /dev/null +++ b/mingw-w64-gdbm/gdbm-win32-support.patch @@ -0,0 +1,951 @@ +From 49a6d868583051c80fa82ed87c79b9dae1a88eed Mon Sep 17 00:00:00 2001 +From: Hiroshi Shirosaki +Date: Wed, 4 Jul 2012 11:47:34 +0900 +Subject: [PATCH] Mingw port of gdbm 1.10 + +I fixed gdbm 1.10 based on existing gdbm 1.8.3 patch for Windows. +http://jarp.does.notwork.org/win32/gdbm-1.8.3-1-src.zip +http://gnuwin32.sourceforge.net/packages/gdbm.htm + +Additinal fixes: + +src/gdbmreorg.c: +Reorganize of gdbm doesn't work because file rename is not allowed +with opened files on Windows. Adding close/open file process fixes it. + +src/flatfile.c: +It doesn't exist in 1.8.3. I added fixes using winsock2.h. +compat/dbmopen.c has hard link related feature which doesn't work. +I fixed it using Windows API. + +`make check` executes tests for gdbm. It fails causes of CRLF newlines +and '.exe' of file names. I fixed it setting binary mode and adding +extention. + +I added some Makefile fixes. I did `autoreconf` on MinGW 1.0.17. It +needs `autopoint` command which is included in gettext package, but +devkit doesn't have. +--- + Makefile.in | 1 + + aclocal.m4 | 4 +-- + autoconf.h.in | 8 ++++- + compat/Makefile.am | 2 +- + compat/Makefile.in | 3 +- + compat/dbmopen.c | 46 ++++++++++++++++++++++++----- + doc/Makefile.in | 1 + + export/Makefile.in | 1 + + src/Makefile.am | 2 +- + src/Makefile.in | 3 +- + src/flatfile.c | 4 +++ + src/gdbmopen.c | 4 ++- + src/gdbmreorg.c | 32 ++++++++++++++++++-- + src/lock.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + src/systems.h | 17 ++++++++++- + src/testgdbm.c | 4 +++ + tests/Makefile.in | 1 + + tests/dtdel.c | 8 ++++- + tests/dtdump.c | 8 ++++- + tests/dtfetch.c | 8 ++++- + tests/dtload.c | 9 +++++- + tests/gtdel.c | 8 ++++- + tests/gtdump.c | 8 ++++- + tests/gtfetch.c | 8 ++++- + tests/gtload.c | 8 ++++- + tests/gtopt.c | 10 ++++++- + tests/gtver.c | 5 ++++ + tests/num2word.c | 5 ++++ + tests/testsuite | 8 ++--- + 29 files changed, 275 insertions(+), 34 deletions(-) + +diff --git a/Makefile.in b/Makefile.in +index 9f80d90..426f304 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -203,6 +203,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + PACKAGE_NAME = @PACKAGE_NAME@ + PACKAGE_STRING = @PACKAGE_STRING@ + PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ + PACKAGE_VERSION = @PACKAGE_VERSION@ + PATH_SEPARATOR = @PATH_SEPARATOR@ + POSUB = @POSUB@ +diff --git a/aclocal.m4 b/aclocal.m4 +index 9080a65..58f2365 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -13,8 +13,8 @@ + + m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],, +-[m4_warning([this file was generated for autoconf 2.63. ++m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, ++[m4_warning([this file was generated for autoconf 2.68. + You have another version of autoconf. It may work, but is not guaranteed to. + If you have problems, you may need to regenerate the build system entirely. + To do so, use the procedure documented by the package, typically `autoreconf'.])]) +diff --git a/autoconf.h.in b/autoconf.h.in +index aff7024..997ef10 100644 +--- a/autoconf.h.in ++++ b/autoconf.h.in +@@ -82,12 +82,15 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_STRING_H + +-/* Define to 1 if `st_blksize' is member of `struct stat'. */ ++/* Define to 1 if `st_blksize' is a member of `struct stat'. */ + #undef HAVE_STRUCT_STAT_ST_BLKSIZE + + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_FILE_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_PARAM_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_STAT_H + +@@ -119,6 +122,9 @@ + /* Define to the one symbol short name of this package. */ + #undef PACKAGE_TARNAME + ++/* Define to the home page for this package. */ ++#undef PACKAGE_URL ++ + /* Define to the version of this package. */ + #undef PACKAGE_VERSION + +diff --git a/compat/Makefile.am b/compat/Makefile.am +index 42554b6..7c4ab15 100644 +--- a/compat/Makefile.am ++++ b/compat/Makefile.am +@@ -50,5 +50,5 @@ NDBM_CF=\ + + libgdbm_compat_la_SOURCES = $(DBM_CF) $(NDBM_CF) + +-libgdbm_compat_la_LDFLAGS = -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) ++libgdbm_compat_la_LDFLAGS = -no-undefined -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) + +diff --git a/compat/Makefile.in b/compat/Makefile.in +index 4994e01..fe46887 100644 +--- a/compat/Makefile.in ++++ b/compat/Makefile.in +@@ -208,6 +208,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + PACKAGE_NAME = @PACKAGE_NAME@ + PACKAGE_STRING = @PACKAGE_STRING@ + PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ + PACKAGE_VERSION = @PACKAGE_VERSION@ + PATH_SEPARATOR = @PATH_SEPARATOR@ + POSUB = @POSUB@ +@@ -305,7 +306,7 @@ NDBM_CF = \ + dbmrdonly.c + + libgdbm_compat_la_SOURCES = $(DBM_CF) $(NDBM_CF) +-libgdbm_compat_la_LDFLAGS = -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) ++libgdbm_compat_la_LDFLAGS = -no-undefined -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) + all: all-am + + .SUFFIXES: +diff --git a/compat/dbmopen.c b/compat/dbmopen.c +index 7a5127e..6110afb 100644 +--- a/compat/dbmopen.c ++++ b/compat/dbmopen.c +@@ -58,13 +58,17 @@ putint (unsigned char *cp, unsigned n) + + /* FIXME: revise return codes */ + static int +-ndbm_open_dir_file0 (const char *file_name, int pagfd, int mode) ++ndbm_open_dir_file0 (const char *file_name, struct gdbm_file_info *pag, int mode) + { + int fd = -1; + struct stat st, pagst; + unsigned char dirbuf[DEF_DIR_SIZE]; + int flags = (mode & GDBM_OPENMASK) == GDBM_READER ? + O_RDONLY : O_RDWR; ++ int pagfd = pag->desc; ++#ifdef _WIN32 ++ HANDLE hFile; ++#endif + + if (mode & GDBM_CLOEXEC) + flags |= O_CLOEXEC; +@@ -76,13 +80,40 @@ ndbm_open_dir_file0 (const char *file_name, int pagfd, int mode) + } + + /* Previous versions of GDBM linked pag to dir. Try to detect this: */ ++#ifdef _WIN32 ++ hFile = CreateFile(file_name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, ++ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, ++ NULL); ++ ++ if (hFile != INVALID_HANDLE_VALUE) ++ { ++ BY_HANDLE_FILE_INFORMATION fileInfo; ++ GetFileInformationByHandle (hFile, &fileInfo); ++ CloseHandle (hFile); ++ st.st_size = (fileInfo.nFileSizeHigh * MAXDWORD) + fileInfo.nFileSizeLow; ++ ++ if (fileInfo.nNumberOfLinks >= 2) ++ { ++ BY_HANDLE_FILE_INFORMATION pagInfo; ++ GetFileInformationByHandle ((HANDLE)_get_osfhandle (pagfd), &pagInfo); ++ if ((fileInfo.nFileIndexLow == pagInfo.nFileIndexLow) && ++ (fileInfo.nFileIndexHigh == pagInfo.nFileIndexHigh)) ++ { ++ /* Close pag because unlink dir file fails on Windows */ ++ close (pagfd); ++#else + if (stat (file_name, &st) == 0) + { + if (st.st_nlink >= 2) + { + if (st.st_dev == pagst.st_dev && st.st_ino == pagst.st_ino) + { +- if (unlink (file_name)) ++#endif ++ int ret = unlink (file_name); ++#ifdef _WIN32 ++ pagfd = pag->desc = open(pag->name, flags | O_BINARY); ++#endif ++ if (ret) + { + if ((mode & GDBM_OPENMASK) == GDBM_READER) + /* Ok, try to cope with it. */ +@@ -109,7 +140,7 @@ ndbm_open_dir_file0 (const char *file_name, int pagfd, int mode) + } + else + { +- fd = open (file_name, flags); ++ fd = open (file_name, flags | O_BINARY); + if (fd == -1) + { + gdbm_errno = GDBM_FILE_OPEN_ERROR; +@@ -141,7 +172,7 @@ ndbm_open_dir_file0 (const char *file_name, int pagfd, int mode) + } + + /* File does not exist. Create it. */ +- fd = open (file_name, flags | O_CREAT, pagst.st_mode & 0777); ++ fd = open (file_name, flags | O_CREAT | O_BINARY, pagst.st_mode & 0777); + if (fd >= 0) + { + putint (dirbuf, GDBM_DIR_MAGIC); +@@ -161,10 +192,11 @@ ndbm_open_dir_file0 (const char *file_name, int pagfd, int mode) + } + + static int +-ndbm_open_dir_file (const char *base, int pagfd, int mode) ++ndbm_open_dir_file (const char *base, struct gdbm_file_info *pag, int mode) + { + char *file_name = malloc (strlen (base) + sizeof (DIRSUF)); + int fd; ++ int pagfd = pag->desc; + + if (!file_name) + { +@@ -172,7 +204,7 @@ ndbm_open_dir_file (const char *base, int pagfd, int mode) + return -1; + } + fd = ndbm_open_dir_file0 (strcat (strcpy (file_name, base), DIRSUF), +- pagfd, mode); ++ pag, mode); + free (file_name); + return fd; + } +@@ -265,7 +297,7 @@ dbm_open (char *file, int flags, int mode) + } + else + { +- dbm->dirfd = ndbm_open_dir_file (file, dbm->file->desc, open_flags); ++ dbm->dirfd = ndbm_open_dir_file (file, dbm->file, open_flags); + if (dbm->dirfd == -1) + { + gdbm_close (dbm->file); +diff --git a/doc/Makefile.in b/doc/Makefile.in +index 7379b75..d620ab6 100644 +--- a/doc/Makefile.in ++++ b/doc/Makefile.in +@@ -186,6 +186,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + PACKAGE_NAME = @PACKAGE_NAME@ + PACKAGE_STRING = @PACKAGE_STRING@ + PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ + PACKAGE_VERSION = @PACKAGE_VERSION@ + PATH_SEPARATOR = @PATH_SEPARATOR@ + POSUB = @POSUB@ +diff --git a/export/Makefile.in b/export/Makefile.in +index 37de02d..62db897 100644 +--- a/export/Makefile.in ++++ b/export/Makefile.in +@@ -178,6 +178,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + PACKAGE_NAME = @PACKAGE_NAME@ + PACKAGE_STRING = @PACKAGE_STRING@ + PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ + PACKAGE_VERSION = @PACKAGE_VERSION@ + PATH_SEPARATOR = @PATH_SEPARATOR@ + POSUB = @POSUB@ +diff --git a/src/Makefile.am b/src/Makefile.am +index 1c55a4e..860a56b 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -60,7 +60,7 @@ libgdbm_la_SOURCES = \ + update.c\ + version.c + +-libgdbm_la_LDFLAGS = -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) ++libgdbm_la_LDFLAGS = -no-undefined -lws2_32 -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) + + # Programs + bin_PROGRAMS = testgdbm +diff --git a/src/Makefile.in b/src/Makefile.in +index b03d5c1..7860daf 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -215,6 +215,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + PACKAGE_NAME = @PACKAGE_NAME@ + PACKAGE_STRING = @PACKAGE_STRING@ + PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ + PACKAGE_VERSION = @PACKAGE_VERSION@ + PATH_SEPARATOR = @PATH_SEPARATOR@ + POSUB = @POSUB@ +@@ -324,7 +325,7 @@ libgdbm_la_SOURCES = \ + update.c\ + version.c + +-libgdbm_la_LDFLAGS = -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) ++libgdbm_la_LDFLAGS = -no-undefined -lws2_32 -version-info $(VI_CURRENT):$(VI_REVISION):$(VI_AGE) + testgdbm_LDADD = ./libgdbm.la + all: all-am + +diff --git a/src/flatfile.c b/src/flatfile.c +index c0f9422..adb83f2 100644 +--- a/src/flatfile.c ++++ b/src/flatfile.c +@@ -20,7 +20,11 @@ + + /* Include system configuration before all else. */ + # include "autoconf.h" ++#ifdef _WIN32 ++# include ++#else + # include ++#endif + + # include "gdbmdefs.h" + # include "gdbm.h" +diff --git a/src/gdbmopen.c b/src/gdbmopen.c +index 67db9c2..ec1c9a7 100644 +--- a/src/gdbmopen.c ++++ b/src/gdbmopen.c +@@ -128,7 +128,9 @@ gdbm_open (const char *file, int block_size, int flags, int mode, + } + else + dbf->cloexec = FALSE; +- ++ ++ fbits |= O_BINARY; ++ + /* Open the file. */ + need_trunc = FALSE; + switch (flags & GDBM_OPENMASK) +diff --git a/src/gdbmreorg.c b/src/gdbmreorg.c +index cc2a929..8b716c9 100644 +--- a/src/gdbmreorg.c ++++ b/src/gdbmreorg.c +@@ -22,7 +22,17 @@ + + #include "gdbmdefs.h" + +-#if !HAVE_RENAME ++#if defined(_WIN32) ++static int ++_gdbm_rename (char *old_name, char *new_name) ++{ ++ if (!MoveFileEx (old_name, new_name, MOVEFILE_REPLACE_EXISTING)) ++ return -1; ++ ++ return 0; ++} ++#define rename _gdbm_rename ++#elif !HAVE_RENAME + + /* Rename takes OLD_NAME and renames it as NEW_NAME. If it can not rename + the file a non-zero value is returned. OLD_NAME is guaranteed to +@@ -94,7 +104,7 @@ gdbm_reorganize (GDBM_FILE dbf) + strcpy (&new_name[0], dbf->name); + new_name[len+2] = 0; + new_name[len+1] = '#'; +- while ( (len > 0) && new_name[len-1] != '/') ++ while ( (len > 0) && new_name[len-1] != '/' && new_name[len-1] != '\\') + { + new_name[len] = new_name[len-1]; + len -= 1; +@@ -157,20 +167,38 @@ gdbm_reorganize (GDBM_FILE dbf) + + /* Move the new file to old name. */ + ++ ++#ifdef _WIN32 ++ close (new_dbf->desc); ++ ++ if (dbf->file_locking) ++ { ++ _gdbm_unlock_file (dbf); ++ } ++ close (dbf->desc); ++#endif + if (rename (new_name, dbf->name) != 0) + { + gdbm_errno = GDBM_REORGANIZE_FAILED; ++#ifdef _WIN32 ++ dbf->desc = open (dbf->name, O_RDWR|O_BINARY, 0); ++ new_dbf->desc = open (new_name, O_RDWR|O_BINARY, 0); ++#endif + gdbm_close (new_dbf); + free (new_name); + return -1; + } + + /* Fix up DBF to have the correct information for the new file. */ ++#ifdef _WIN32 ++ new_dbf->desc = open (dbf->name, O_RDWR|O_BINARY, 0); ++#else + if (dbf->file_locking) + { + _gdbm_unlock_file (dbf); + } + close (dbf->desc); ++#endif + free (dbf->header); + free (dbf->dir); + +diff --git a/src/lock.c b/src/lock.c +index 214e1cb..8ccb98b 100644 +--- a/src/lock.c ++++ b/src/lock.c +@@ -23,7 +23,7 @@ + + #include + +-#if HAVE_FLOCK ++#if HAVE_FLOCK || defined(_WIN32) + # ifndef LOCK_SH + # define LOCK_SH 1 + # endif +@@ -41,6 +41,83 @@ + # endif + #endif + ++#ifdef _WIN32 ++#include ++#include ++ ++/* ++ * flock support code for windows ++ * ++ * This code is derived from ruby (http://www.ruby-lang.org/). ++ * Original copyright notice is below. ++ */ ++/* ++ * Copyright (c) 1993, Intergraph Corporation ++ * ++ * You may distribute under the terms of either the GNU General Public ++ * License or the Artistic License, as specified in the perl README file. ++ * ++ * Various Unix compatibility functions and NT specific functions. ++ * ++ * Some of this code was derived from the MSDOS port(s) and the OS/2 port. ++ * ++ */ ++ ++#ifndef EWOULDBLOCK ++#define EWOULDBLOCK 10035 /* EBASEERR + 35 (winsock.h) */ ++#endif ++ ++#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError() == ERROR_LOCK_VIOLATION ? EWOULDBLOCK : EACCES)) ++#define LK_LEN ULONG_MAX ++ ++static int ++flock_winnt(HANDLE fh, int oper) ++{ ++ OVERLAPPED o; ++ int i = -1; ++ ++ memset(&o, 0, sizeof(o)); ++ ++ switch(oper) { ++ case LOCK_SH: /* shared lock */ ++ LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, LK_LEN, &o), i); ++ break; ++ case LOCK_EX: /* exclusive lock */ ++ LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, LK_LEN, &o), i); ++ break; ++ case LOCK_SH|LOCK_NB: /* non-blocking shared lock */ ++ LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, LK_LEN, &o), i); ++ break; ++ case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */ ++ LK_ERR(LockFileEx(fh, ++ LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, ++ 0, LK_LEN, LK_LEN, &o), i); ++ break; ++ case LOCK_UN: /* unlock lock */ ++ LK_ERR(UnlockFileEx(fh, 0, LK_LEN, LK_LEN, &o), i); ++ break; ++ default: /* unknown */ ++ errno = EINVAL; ++ break; ++ } ++ return i; ++} ++ ++#undef LK_ERR ++ ++int ++flock(int fd, int oper) ++{ ++ static int (*locker)(HANDLE, int) = NULL; ++ ++ if (!locker) { ++ locker = flock_winnt; ++ } ++ ++ return locker((HANDLE)_get_osfhandle(fd), oper); ++} ++#endif /* _WIN32 */ ++ + #if defined(F_SETLK) && defined(F_RDLCK) && defined(F_WRLCK) + # define HAVE_FCNTL_LOCK 1 + #else +@@ -65,7 +142,7 @@ _gdbm_unlock_file (GDBM_FILE dbf) + switch (dbf->lock_type) + { + case LOCKING_FLOCK: +-#if HAVE_FLOCK ++#if HAVE_FLOCK || defined(_WIN32) + flock (dbf->desc, LOCK_UN); + #endif + break; +@@ -101,7 +178,7 @@ _gdbm_lock_file (GDBM_FILE dbf) + #endif + int lock_val = -1; + +-#if HAVE_FLOCK ++#if HAVE_FLOCK || defined(_WIN32) + if (dbf->read_write == GDBM_READER) + lock_val = flock (dbf->desc, LOCK_SH + LOCK_NB); + else +diff --git a/src/systems.h b/src/systems.h +index c83cd9c..7b3eee4 100644 +--- a/src/systems.h ++++ b/src/systems.h +@@ -18,6 +18,11 @@ + along with GDBM. If not, see . */ + + /* Include all system headers first. */ ++#ifdef _WIN32 ++# undef _WIN32_WINNT ++# define _WIN32_WINNT 0x0501 ++# include ++#endif + #if HAVE_SYS_TYPES_H + # include + #endif +@@ -50,6 +55,10 @@ + # define O_CLOEXEC 0 + #endif + ++#ifndef O_BINARY ++# define O_BINARY 0 ++#endif ++ + /* Default block size. Some systems do not have blocksize in their + stat record. This code uses the BSD blocksize from stat. */ + +@@ -63,7 +72,7 @@ + #if HAVE_FTRUNCATE + # define TRUNCATE(dbf) ftruncate (dbf->desc, 0) + #else +-# define TRUNCATE(dbf) close( open (dbf->name, O_RDWR|O_TRUNC, mode)); ++# define TRUNCATE(dbf) close( open (dbf->name, O_RDWR|O_TRUNC|O_BINARY, mode)); + #endif + + #ifndef STDERR_FILENO +@@ -82,8 +91,14 @@ + # define __lseek(_dbf, _off, _whn) lseek(_dbf->desc, _off, _whn) + # if HAVE_FSYNC + # define __fsync(_dbf) fsync(_dbf->desc) ++# elif defined(_WIN32) ++# define __fsync(_dbf) _commit(_dbf->desc) + # else + # define __fsync(_dbf) { sync(); sync(); } + # endif + #endif + ++/* Windows port of flock */ ++#ifdef _WIN32 ++extern int flock(int fd, int oper); ++#endif +diff --git a/src/testgdbm.c b/src/testgdbm.c +index b2b9c6c..3a0926c 100644 +--- a/src/testgdbm.c ++++ b/src/testgdbm.c +@@ -27,7 +27,9 @@ + #include + #include + #include ++#ifndef _WIN32 + #include ++#endif + #ifdef HAVE_SYS_TERMIOS_H + # include + #endif +@@ -1126,7 +1128,9 @@ main (int argc, char *argv[]) + -1) + error (2, _("gdbm_setopt failed: %s"), gdbm_strerror (gdbm_errno)); + ++#ifndef _WIN32 + signal (SIGPIPE, SIG_IGN); ++#endif + + /* Welcome message. */ + if (interactive) +diff --git a/tests/Makefile.in b/tests/Makefile.in +index a7a7e39..8a5a368 100644 +--- a/tests/Makefile.in ++++ b/tests/Makefile.in +@@ -230,6 +230,7 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + PACKAGE_NAME = @PACKAGE_NAME@ + PACKAGE_STRING = @PACKAGE_STRING@ + PACKAGE_TARNAME = @PACKAGE_TARNAME@ ++PACKAGE_URL = @PACKAGE_URL@ + PACKAGE_VERSION = @PACKAGE_VERSION@ + PATH_SEPARATOR = @PATH_SEPARATOR@ + POSUB = @POSUB@ +diff --git a/tests/dtdel.c b/tests/dtdel.c +index b7d0112..1134027 100644 +--- a/tests/dtdel.c ++++ b/tests/dtdel.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include "dbm.h" +@@ -30,7 +31,12 @@ main (int argc, char **argv) + int flags = 0; + int data_z = 0; + int rc = 0; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++ _setmode(_fileno(stderr), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/dtdump.c b/tests/dtdump.c +index 4e0aa3e..302655a 100644 +--- a/tests/dtdump.c ++++ b/tests/dtdump.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include "dbm.h" +@@ -29,7 +30,12 @@ main (int argc, char **argv) + datum key; + datum data; + int delim = '\t'; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++ _setmode(_fileno(stderr), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/dtfetch.c b/tests/dtfetch.c +index 8a2686f..b17a344 100644 +--- a/tests/dtfetch.c ++++ b/tests/dtfetch.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include "dbm.h" +@@ -44,7 +45,12 @@ main (int argc, char **argv) + int data_z = 0; + int delim = 0; + int rc = 0; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++ _setmode(_fileno(stderr), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/dtload.c b/tests/dtload.c +index 6ebd638..c449c74 100644 +--- a/tests/dtload.c ++++ b/tests/dtload.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include +@@ -39,7 +40,13 @@ main (int argc, char **argv) + datum data; + int delim = '\t'; + int data_z = 0; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdin), O_BINARY); ++ _setmode(_fileno(stdout), O_BINARY); ++ _setmode(_fileno(stderr), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/gtdel.c b/tests/gtdel.c +index ff9cdb9..e6a8c5f 100644 +--- a/tests/gtdel.c ++++ b/tests/gtdel.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include "gdbm.h" +@@ -31,7 +32,12 @@ main (int argc, char **argv) + GDBM_FILE dbf; + int data_z = 0; + int rc = 0; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++ _setmode(_fileno(stderr), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/gtdump.c b/tests/gtdump.c +index 927a47c..acb0f56 100644 +--- a/tests/gtdump.c ++++ b/tests/gtdump.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include "gdbm.h" +@@ -31,7 +32,12 @@ main (int argc, char **argv) + int flags = 0; + GDBM_FILE dbf; + int delim = '\t'; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdin), O_BINARY); ++ _setmode(_fileno(stdout), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/gtfetch.c b/tests/gtfetch.c +index 0c254b7..4f7135c 100644 +--- a/tests/gtfetch.c ++++ b/tests/gtfetch.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include "gdbm.h" +@@ -46,7 +47,12 @@ main (int argc, char **argv) + int data_z = 0; + int delim = 0; + int rc = 0; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++ _setmode(_fileno(stderr), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/gtload.c b/tests/gtload.c +index b89ae1f..f0c09cf 100644 +--- a/tests/gtload.c ++++ b/tests/gtload.c +@@ -16,6 +16,7 @@ + */ + #include "autoconf.h" + #include ++#include + #include + #include + #include +@@ -39,7 +40,12 @@ main (int argc, char **argv) + int delim = '\t'; + int data_z = 0; + size_t mapped_size_max = 0; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdin), O_BINARY); ++ _setmode(_fileno(stdout), O_BINARY); ++#endif ++ + while (--argc) + { + char *arg = *++argv; +diff --git a/tests/gtopt.c b/tests/gtopt.c +index 13ad8cc..535edbb 100644 +--- a/tests/gtopt.c ++++ b/tests/gtopt.c +@@ -178,7 +178,11 @@ init_maxmapsize (void *valptr, int valsize) + int + test_maxmapsize (void *valptr) + { ++#ifdef _SC_PAGESIZE + size_t page_size = sysconf (_SC_PAGESIZE); ++#else ++ size_t page_size = 4096; ++#endif + size_t expected_size = ((mapped_size_max + page_size - 1) / page_size) * + page_size; + return (*(size_t*) valptr == expected_size) ? RES_PASS : RES_FAIL; +@@ -308,7 +312,11 @@ main (int argc, char **argv) + { + GDBM_FILE dbf; + struct optest *op; +- ++ ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++#endif ++ + progname = canonical_progname (argv[0]); + while (--argc) + { +diff --git a/tests/gtver.c b/tests/gtver.c +index 27fc0b9..cbfe794 100644 +--- a/tests/gtver.c ++++ b/tests/gtver.c +@@ -17,6 +17,7 @@ + #include "autoconf.h" + #include + #include ++#include + #include + #include "gdbm.h" + #include "progname.h" +@@ -31,6 +32,10 @@ main (int argc, char **argv) + const char *progname = canonical_progname (argv[0]); + int library = 0; + ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++#endif ++ + if (argc == 1) + { + printf ("%s\n", gdbm_version); +diff --git a/tests/num2word.c b/tests/num2word.c +index 4b55a35..551afd0 100644 +--- a/tests/num2word.c ++++ b/tests/num2word.c +@@ -17,6 +17,7 @@ + #include "autoconf.h" + #include + #include ++#include + #include + #include + #include +@@ -203,6 +204,10 @@ xstrtoul (char *arg, char **endp) + int + main (int argc, char **argv) + { ++#ifdef _WIN32 ++ _setmode(_fileno(stdout), O_BINARY); ++#endif ++ + progname = argv[0]; + + if (argc == 1 || strcmp (argv[1], "-h") == 0) +diff --git a/tests/testsuite b/tests/testsuite +index 96ee5f9..8826999 100644 +--- a/tests/testsuite ++++ b/tests/testsuite +@@ -2069,7 +2069,7 @@ gtfetch test.db 0 + fi + at_status=$? + at_failed=false +-echo >>"$at_stderr"; $as_echo "gtfetch: 0: not found ++echo >>"$at_stderr"; $as_echo "gtfetch.exe: 0: not found + " | \ + $at_diff - "$at_stderr" || at_failed=: + at_func_diff_devnull "$at_stdout" || at_failed=: +@@ -2200,7 +2200,7 @@ gtdel test.db 11 + fi + at_status=$? + at_failed=false +-echo >>"$at_stderr"; $as_echo "gtdel: cannot delete 11: Item not found ++echo >>"$at_stderr"; $as_echo "gtdel.exe: cannot delete 11: Item not found + " | \ + $at_diff - "$at_stderr" || at_failed=: + at_func_diff_devnull "$at_stdout" || at_failed=: +@@ -2519,7 +2519,7 @@ dtfetch test 0 + fi + at_status=$? + at_failed=false +-echo >>"$at_stderr"; $as_echo "dtfetch: 0: not found ++echo >>"$at_stderr"; $as_echo "dtfetch.exe: 0: not found + " | \ + $at_diff - "$at_stderr" || at_failed=: + at_func_diff_devnull "$at_stdout" || at_failed=: +@@ -2808,7 +2808,7 @@ dtdel test 11 + fi + at_status=$? + at_failed=false +-echo >>"$at_stderr"; $as_echo "dtdel: cannot delete 11: Item not found ++echo >>"$at_stderr"; $as_echo "dtdel.exe: cannot delete 11: Item not found + " | \ + $at_diff - "$at_stderr" || at_failed=: + at_func_diff_devnull "$at_stdout" || at_failed=: +-- +1.7.10.msysgit.1