Created
February 23, 2018 22:45
-
-
Save przemoc/fbf2bfb11af0d9cd58726c200e4d133e to your computer and use it in GitHub Desktop.
Make plzip compilable on MSYS2+MinGW-w64
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Make plzip compilable on MSYS2+MinGW-w64. | |
It's Hannes Domani's plzip.patch taken from: | |
http://download.savannah.gnu.org/releases/lzip/plzip/plzip-1.1-w.zip | |
that was applied against plzip 1.7: | |
http://download.savannah.gnu.org/releases/lzip/plzip/plzip-1.7.tar.gz | |
changed to not artificially limit number of threads (the limit was 32), | |
and finally diff has been regenerated using output with unified context. | |
--- a/decompress.cc 2018-02-07 20:17:00.000000000 +0100 | |
+++ b/decompress.cc 2018-02-23 23:14:21.644369300 +0100 | |
@@ -37,6 +37,61 @@ | |
#include "file_index.h" | |
+#ifdef _WIN32 | |
+#include <windows.h> | |
+ | |
+ssize_t pread(int fd, void *buf, size_t count, long long offset) | |
+{ | |
+ OVERLAPPED o = {0,0,0,0,0}; | |
+ HANDLE fh = (HANDLE)_get_osfhandle(fd); | |
+ uint64_t off = offset; | |
+ DWORD bytes; | |
+ BOOL ret; | |
+ | |
+ if (fh == INVALID_HANDLE_VALUE) { | |
+ errno = EBADF; | |
+ return -1; | |
+ } | |
+ | |
+ o.Offset = off & 0xffffffff; | |
+ o.OffsetHigh = (off >> 32) & 0xffffffff; | |
+ | |
+ ret = ReadFile(fh, buf, (DWORD)count, &bytes, &o); | |
+ if (!ret) { | |
+ errno = EIO; | |
+ return -1; | |
+ } | |
+ | |
+ return (ssize_t)bytes; | |
+} | |
+ | |
+ssize_t pwrite(int fd, const void *buf, size_t count, long long offset) | |
+{ | |
+ OVERLAPPED o = {0,0,0,0,0}; | |
+ HANDLE fh = (HANDLE)_get_osfhandle(fd); | |
+ uint64_t off = offset; | |
+ DWORD bytes; | |
+ BOOL ret; | |
+ | |
+ if (fh == INVALID_HANDLE_VALUE) { | |
+ errno = EBADF; | |
+ return -1; | |
+ } | |
+ | |
+ o.Offset = off & 0xffffffff; | |
+ o.OffsetHigh = (off >> 32) & 0xffffffff; | |
+ | |
+ ret = WriteFile(fh, buf, (DWORD)count, &bytes, &o); | |
+ if (!ret) { | |
+ errno = EIO; | |
+ return -1; | |
+ } | |
+ | |
+ return (ssize_t)bytes; | |
+} | |
+#endif | |
+ | |
+ | |
// Returns the number of bytes really read. | |
// If (returned value < size) and (errno == 0), means EOF was reached. | |
// | |
--- a/main.cc 2018-02-07 20:17:00.000000000 +0100 | |
+++ b/main.cc 2018-02-23 23:14:27.592984400 +0100 | |
@@ -69,6 +69,31 @@ | |
int verbosity = 0; | |
+#ifdef _WIN32 | |
+#include <windows.h> | |
+ | |
+#define _SC_NPROCESSORS_ONLN 1 | |
+#define _SC_THREAD_THREADS_MAX 2 | |
+long sysconf( int flag ) | |
+{ | |
+ switch( flag ) | |
+ { | |
+ case _SC_NPROCESSORS_ONLN: | |
+ { | |
+ SYSTEM_INFO si; | |
+ GetSystemInfo( &si ); | |
+ return si.dwNumberOfProcessors; | |
+ } | |
+ | |
+ case _SC_THREAD_THREADS_MAX: | |
+ return -1; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+#endif | |
+ | |
+ | |
namespace { | |
const char * const Program_name = "Plzip"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
pread()
andpwrite()
implementation available here, i.e. revision 1 of plzip-msys2-mingw-w64.patch, is not POSIX conformant, so program may misbehave.Check System Interfaces volume of POSIX, specifically read and write, where you can read:
The issue is that ReadFile and WriteFile used to implement them update file pointer (equivalent of file offset in POSIX world), regardless of
OVERLAPPED
structure being used to specify byte offset or not. As can be read in Synchronous and Asynchronous I/O:Using
SetFilePointer()
to save current file pointer beforepread()
/pwrite()
and restore it afterwards would be only acceptable in single-threaded applications. In multi-threaded applications, wherepread()
/pwrite()
calls may be concurrent toread()
/write()
calls (relying on current file offset), we would have a window, when file offset is different than expected.You can additionally check following 2 threads from mailing lists that touched this subject:
So how
pread()
/pwrite()
could be implemented in Windows?Basically additional file object is needed that would be exclusively used by
pread()
/pwrite()
, thus file pointer changes would not affectread()
/write()
calls, as they would be using "original" file object. I do mean file object (equivalent of file description in POSIX world) and not just mere file handle (equivalent of file descriptor in POSIX worlds). Using DuplicateHandle won't suffice:It may be tempting to use NtQueryInformationFile with
FileInternalInformation
asFileInformationClass
followed by NtCreateFile withFILE_OPEN_BY_FILE_ID
inCreateOptions
, but 64-bit file ID is not available, stable and unique on all file systems, as can be seen in below table. Therefore this approach cannot be used without any fallback solution if application is meant to work on non-NTFS file systems like FAT32 or exFAT.Table source:
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/d4bc551b-7aaf-4b4f-ba0e-3a75e7c528f0