- /* win32_mmapcat1.c - memory-map file and write file's contents to stdout */
- /*
- * Compile under Cygwin 3.6 with:
- * $ clang -target x86_64-pc-windows-gnu \
- * -Wall -Wextra -DUNICODE=1 -D_UNICODE=1 -D__USE_MINGW_ANSI_STDIO=1 \
- * win32_mmapcat1.c -o win32_mmapcat1.exe
- */
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #define EXIT_USAGE (2)
- static
- LONGLONG getfilesize(HANDLE hFile)
- {
- LARGE_INTEGER fs = { .QuadPart = -1LL };
- if (!GetFileSizeEx(hFile, &fs))
- return -1LL;
- return fs.QuadPart;
- }
- int main(int argc, char *argv[])
- {
- HANDLE hFile = INVALID_HANDLE_VALUE;
- HANDLE hMap = NULL;
- LPVOID pMapView = NULL;
- LONGLONG fileSize = 0LL;
- LONGLONG bytesWritten = 0LL;
- HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
- int retval = EXIT_FAILURE;
- if (hStdout == INVALID_HANDLE_VALUE) {
- "Error getting stdout handle: %d\n",
- (int)GetLastError());
- return EXIT_FAILURE;
- }
- if (argc != 2) {
- "Usage: %s <filename>\n",
- argv[0]);
- return EXIT_USAGE;
- }
- const char *filename = argv[1];
- hFile = CreateFileA(filename,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- "Error creating/opening file '%s': %d\n",
- filename, (int)GetLastError());
- retval = EXIT_FAILURE;
- goto done;
- }
- fileSize = getfilesize(hFile);
- if (fileSize == -1LL) {
- "Error getting file size: %d\n",
- (int)GetLastError());
- retval = EXIT_FAILURE;
- goto done;
- }
- hMap = CreateFileMappingA(hFile,
- NULL,
- PAGE_READONLY,
- ((fileSize >> 32) & 0xFFFFFFFF),
- (fileSize & 0xFFFFFFFF),
- NULL);
- if (hMap == NULL) {
- "Error creating file mapping: %d\n",
- (int)GetLastError());
- retval = EXIT_FAILURE;
- goto done;
- }
- pMapView = MapViewOfFile(hMap,
- FILE_MAP_READ,
- 0,
- 0,
- 0);
- if (pMapView == NULL) {
- "Error mapping view of file: %d\n",
- (int)GetLastError());
- retval = EXIT_FAILURE;
- goto done;
- }
- LONGLONG bytesLeft;
- DWORD chunkSize = 512*1024*1024;
- DWORD chunkBytesWritten;
- char *buf;
- for (buf = pMapView, bytesLeft=fileSize ; bytesLeft > 0 ; ) {
- if (bytesLeft < chunkSize)
- chunkSize = bytesLeft;
- if (!WriteFile(hStdout,
- buf,
- chunkSize,
- &chunkBytesWritten,
- NULL))
- {
- "Error writing to stdout: %d, chunkSize=%lld, bytesLeft=%lld, bytesWritten=%lld\n",
- (int)GetLastError(),
- (long long)chunkSize,
- (long long)bytesLeft,
- (long long)bytesWritten);
- retval = EXIT_FAILURE;
- goto done;
- }
- bytesWritten += chunkBytesWritten;
- buf += chunkBytesWritten;
- bytesLeft -= chunkBytesWritten;
- }
- if (bytesWritten != fileSize) {
- "Warning: Only %lld bytes written to stdout instead of %lld.\n",
- (long long)bytesWritten,
- (long long)fileSize);
- retval = EXIT_FAILURE;
- } else {
- "Successfully wrote %lld bytes to stdout.\n",
- (long long)bytesWritten);
- retval = EXIT_SUCCESS;
- }
- done:
- if (pMapView) {
- (void)UnmapViewOfFile(pMapView);
- }
- if (hMap) {
- (void)CloseHandle(hMap);
- }
- if (hFile != INVALID_HANDLE_VALUE) {
- (void)CloseHandle(hFile);
- }
- return retval;
- }
win32_mmapcat1.c - memory-map file and write file's contents to stdout
Posted by Anonymous on Sat 24th May 2025 14:06
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.