OSDN Git Service

9154fa341d5406b9f933164b90269f3120f14f47
[mingw/mingw-org-wsl.git] / mingwrt / mingwex / mingw-fseek.c
1 /*
2  * Workaround for limitations on win9x where a file contents are
3  * not zero'd out if you seek past the end and then write.
4  * Copied from ming local-patch to binutils/bfd/libbfd.c written by
5  * Mumit Khan  <khan@xraylith.wisc.edu>
6  */
7
8 #include <windows.h>
9 #include <stdio.h>
10 #include <io.h>
11 #include <stdlib.h>
12
13 #define ZEROBLOCKSIZE 512
14 static int __mingw_fseek_called;
15
16 /* The fseek in Win9x runtime does not zero out the file if seeking past
17    the end; if you don't want random stuff from your disk included in your
18    output DLL/executable, use this version instead. On WinNT/Win2k, it
19    just calls runtime fseek().
20
21    CHECK/FIXME: Does this work for both text and binary modes?? */
22
23
24 int
25 __mingw_fseek (FILE *fp, long offset, int whence)
26 {
27 # undef fseek
28   __mingw_fseek_called = 1;
29   return fseek (fp, offset, whence);
30 }
31
32 int
33 __mingw_fseeko64 (FILE *fp, off64_t offset, int whence)
34 {
35 # undef fseeko64
36   __mingw_fseek_called = 1;
37   return fseeko64 (fp, offset, whence);
38 }
39
40 size_t
41 __mingw_fwrite (const void *buffer, size_t size, size_t count, FILE *fp)
42 {
43 # undef fwrite
44   if ((_osver & 0x8000) &&  __mingw_fseek_called)
45     {
46       ULARGE_INTEGER actual_length;
47       LARGE_INTEGER current_position = {{0LL}};
48       __mingw_fseek_called = 0;
49       fflush (fp);
50       actual_length.u.LowPart = GetFileSize ((HANDLE) _get_osfhandle (fileno (fp)),
51                                              &actual_length.u.HighPart);
52       if (actual_length.u.LowPart == 0xFFFFFFFF
53           && GetLastError() != NO_ERROR )
54         return -1;
55       current_position.u.LowPart = SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
56                                                    current_position.u.LowPart,
57                                                    &current_position.u.HighPart,
58                                                  FILE_CURRENT);
59       if (current_position.u.LowPart == 0xFFFFFFFF
60           && GetLastError() != NO_ERROR )
61         return -1;
62
63 #ifdef DEBUG
64       printf ("__mingw_fwrite: current %I64u, actual %I64u\n",
65               current_position.QuadPart, actual_length.QuadPart);
66 #endif /* DEBUG */
67       if (current_position.QuadPart > actual_length.QuadPart)
68         {
69           static char __mingw_zeros[ZEROBLOCKSIZE];
70           long long numleft;
71
72           SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
73                           0, 0, FILE_END);
74           numleft = current_position.QuadPart - actual_length.QuadPart;
75
76 #ifdef DEBUG
77           printf ("__mingw_fwrite: Seeking %I64d bytes past end\n", numleft);
78 #endif /* DEBUG */
79           while (numleft > 0LL)
80             {
81               DWORD nzeros = (numleft > ZEROBLOCKSIZE)
82                              ? ZEROBLOCKSIZE : numleft;
83               DWORD written;
84               if (! WriteFile ((HANDLE) _get_osfhandle (fileno (fp)),
85                                __mingw_zeros, nzeros, &written, NULL))
86                 {
87                   /* Best we can hope for, or at least DJ says so. */
88                   SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
89                                   0, 0, FILE_BEGIN);
90                   return -1;
91                 }
92               if (written < nzeros)
93                 {
94                   /* Likewise. */
95                   SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
96                                   0, 0, FILE_BEGIN);
97                   return -1;
98                 }
99
100               numleft -= written;
101             }
102             FlushFileBuffers ((HANDLE) _get_osfhandle (fileno (fp)));
103         }
104     }
105   return (fwrite) (buffer, size, count, fp);
106 }