pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


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

  1.  
  2. /* win32_mmapcat1.c - memory-map file and write file's contents to stdout */
  3.  
  4. /*
  5.  * Compile under Cygwin 3.6 with:
  6.  * $ clang -target x86_64-pc-windows-gnu \
  7.  *   -Wall -Wextra -DUNICODE=1 -D_UNICODE=1 -D__USE_MINGW_ANSI_STDIO=1 \
  8.  *   win32_mmapcat1.c -o win32_mmapcat1.exe
  9.  */
  10. #include <windows.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13.  
  14. #define EXIT_USAGE (2)
  15.  
  16. static
  17. LONGLONG getfilesize(HANDLE hFile)
  18. {
  19.     LARGE_INTEGER fs = { .QuadPart = -1LL };
  20.  
  21.     if (!GetFileSizeEx(hFile, &fs))
  22.         return -1LL;
  23.  
  24.     return fs.QuadPart;
  25. }
  26.  
  27. int main(int argc, char *argv[])
  28. {
  29.     HANDLE hFile = INVALID_HANDLE_VALUE;
  30.     HANDLE hMap = NULL;
  31.     LPVOID pMapView = NULL;
  32.     LONGLONG fileSize = 0LL;
  33.     LONGLONG bytesWritten = 0LL;
  34.     HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
  35.     int retval = EXIT_FAILURE;
  36.  
  37.     if (hStdout == INVALID_HANDLE_VALUE) {
  38.         (void)fprintf(stderr,
  39.             "Error getting stdout handle: %d\n",
  40.             (int)GetLastError());
  41.         return EXIT_FAILURE;
  42.     }
  43.  
  44.     if (argc != 2) {
  45.         (void)fprintf(stderr,
  46.             "Usage: %s <filename>\n",
  47.             argv[0]);
  48.         return EXIT_USAGE;
  49.     }
  50.  
  51.     const char *filename = argv[1];
  52.  
  53.     hFile = CreateFileA(filename,
  54.         GENERIC_READ,
  55.         FILE_SHARE_READ,
  56.         NULL,
  57.         OPEN_ALWAYS,
  58.         FILE_ATTRIBUTE_NORMAL,
  59.         NULL);
  60.  
  61.     if (hFile == INVALID_HANDLE_VALUE) {
  62.         (void)fprintf(stderr,
  63.             "Error creating/opening file '%s': %d\n",
  64.             filename, (int)GetLastError());
  65.         retval = EXIT_FAILURE;
  66.         goto done;
  67.     }
  68.  
  69.     fileSize = getfilesize(hFile);
  70.     if (fileSize == -1LL) {
  71.         (void)fprintf(stderr,
  72.             "Error getting file size: %d\n",
  73.             (int)GetLastError());
  74.         retval = EXIT_FAILURE;
  75.         goto done;
  76.     }
  77.  
  78.     hMap = CreateFileMappingA(hFile,
  79.         NULL,
  80.         PAGE_READONLY,
  81.         ((fileSize >> 32) & 0xFFFFFFFF),
  82.         (fileSize & 0xFFFFFFFF),
  83.         NULL);
  84.  
  85.     if (hMap == NULL) {
  86.         (void)fprintf(stderr,
  87.             "Error creating file mapping: %d\n",
  88.             (int)GetLastError());
  89.         retval = EXIT_FAILURE;
  90.         goto done;
  91.     }
  92.  
  93.     pMapView = MapViewOfFile(hMap,
  94.         FILE_MAP_READ,
  95.         0,
  96.         0,
  97.         0);
  98.  
  99.     if (pMapView == NULL) {
  100.         (void)fprintf(stderr,
  101.             "Error mapping view of file: %d\n",
  102.             (int)GetLastError());
  103.         retval = EXIT_FAILURE;
  104.         goto done;
  105.     }
  106.  
  107.     LONGLONG bytesLeft;
  108.     DWORD chunkSize = 512*1024*1024;
  109.     DWORD chunkBytesWritten;
  110.     char *buf;
  111.  
  112.     for (buf = pMapView, bytesLeft=fileSize ; bytesLeft > 0 ; ) {
  113.         if (bytesLeft < chunkSize)
  114.             chunkSize = bytesLeft;
  115.  
  116.         if (!WriteFile(hStdout,
  117.             buf,
  118.             chunkSize,
  119.             &chunkBytesWritten,
  120.             NULL))
  121.         {
  122.             (void)fprintf(stderr,
  123.                 "Error writing to stdout: %d, chunkSize=%lld, bytesLeft=%lld, bytesWritten=%lld\n",
  124.                 (int)GetLastError(),
  125.                 (long long)chunkSize,
  126.                 (long long)bytesLeft,
  127.                 (long long)bytesWritten);
  128.             retval = EXIT_FAILURE;
  129.             goto done;
  130.         }
  131.  
  132.         bytesWritten += chunkBytesWritten;
  133.         buf += chunkBytesWritten;
  134.         bytesLeft -= chunkBytesWritten;
  135.     }
  136.  
  137.     if (bytesWritten != fileSize) {
  138.         (void)fprintf(stderr,
  139.             "Warning: Only %lld bytes written to stdout instead of %lld.\n",
  140.             (long long)bytesWritten,
  141.             (long long)fileSize);
  142.         retval = EXIT_FAILURE;
  143.     } else {
  144.         (void)fprintf(stderr,
  145.             "Successfully wrote %lld bytes to stdout.\n",
  146.             (long long)bytesWritten);
  147.         retval = EXIT_SUCCESS;
  148.     }
  149.  
  150. done:
  151.     if (pMapView) {
  152.         (void)UnmapViewOfFile(pMapView);
  153.     }
  154.     if (hMap) {
  155.         (void)CloseHandle(hMap);
  156.     }
  157.     if (hFile != INVALID_HANDLE_VALUE) {
  158.         (void)CloseHandle(hFile);
  159.     }
  160.  
  161.     return retval;
  162. }

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at