VirtualBox

source: kBuild/vendor/grep/3.7/gnulib-tests/ftruncate.c

Last change on this file was 3529, checked in by bird, 3 years ago

Imported grep 3.7 from grep-3.7.tar.gz (sha256: c22b0cf2d4f6bbe599c902387e8058990e1eee99aef333a203829e5fd3dbb342), applying minimal auto-props.

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1/* ftruncate emulations for native Windows.
2 Copyright (C) 1992-2021 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, see <https://www.gnu.org/licenses/>. */
16
17#include <config.h>
18
19/* Specification. */
20#include <unistd.h>
21
22#if HAVE__CHSIZE
23/* A native Windows platform. */
24
25# include <errno.h>
26
27# if _GL_WINDOWS_64_BIT_OFF_T
28
29/* Large File Support: off_t is 64-bit, but _chsize() takes only a 32-bit
30 argument. So, define a 64-bit safe SetFileSize function ourselves. */
31
32/* Ensure that <windows.h> declares GetFileSizeEx. */
33# if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
34# undef _WIN32_WINNT
35# define _WIN32_WINNT _WIN32_WINNT_WIN2K
36# endif
37
38/* Get declarations of the native Windows API functions. */
39# define WIN32_LEAN_AND_MEAN
40# include <windows.h>
41
42/* Get _get_osfhandle. */
43# if GNULIB_MSVC_NOTHROW
44# include "msvc-nothrow.h"
45# else
46# include <io.h>
47# endif
48
49static BOOL
50SetFileSize (HANDLE h, LONGLONG size)
51{
52 LARGE_INTEGER old_size;
53
54 if (!GetFileSizeEx (h, &old_size))
55 return FALSE;
56
57 if (size != old_size.QuadPart)
58 {
59 /* Duplicate the handle, so we are free to modify its file position. */
60 HANDLE curr_process = GetCurrentProcess ();
61 HANDLE tmph;
62
63 if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
64 h, /* SourceHandle */
65 curr_process, /* TargetProcessHandle */
66 (PHANDLE) &tmph, /* TargetHandle */
67 (DWORD) 0, /* DesiredAccess */
68 FALSE, /* InheritHandle */
69 DUPLICATE_SAME_ACCESS)) /* Options */
70 return FALSE;
71
72 if (size < old_size.QuadPart)
73 {
74 /* Reduce the size. */
75 LONG size_hi = (LONG) (size >> 32);
76 if (SetFilePointer (tmph, (LONG) size, &size_hi, FILE_BEGIN)
77 == INVALID_SET_FILE_POINTER
78 && GetLastError() != NO_ERROR)
79 {
80 CloseHandle (tmph);
81 return FALSE;
82 }
83 if (!SetEndOfFile (tmph))
84 {
85 CloseHandle (tmph);
86 return FALSE;
87 }
88 }
89 else
90 {
91 /* Increase the size by adding zero bytes at the end. */
92 static char zero_bytes[1024];
93 LONG pos_hi = 0;
94 LONG pos_lo = SetFilePointer (tmph, (LONG) 0, &pos_hi, FILE_END);
95 LONGLONG pos;
96 if (pos_lo == INVALID_SET_FILE_POINTER
97 && GetLastError() != NO_ERROR)
98 {
99 CloseHandle (tmph);
100 return FALSE;
101 }
102 pos = ((LONGLONG) pos_hi << 32) | (ULONGLONG) (ULONG) pos_lo;
103 while (pos < size)
104 {
105 DWORD written;
106 LONGLONG count = size - pos;
107 if (count > sizeof (zero_bytes))
108 count = sizeof (zero_bytes);
109 if (!WriteFile (tmph, zero_bytes, (DWORD) count, &written, NULL)
110 || written == 0)
111 {
112 CloseHandle (tmph);
113 return FALSE;
114 }
115 pos += (ULONGLONG) (ULONG) written;
116 }
117 }
118 /* Close the handle. */
119 CloseHandle (tmph);
120 }
121 return TRUE;
122}
123
124int
125ftruncate (int fd, off_t length)
126{
127 HANDLE handle = (HANDLE) _get_osfhandle (fd);
128
129 if (handle == INVALID_HANDLE_VALUE)
130 {
131 errno = EBADF;
132 return -1;
133 }
134 if (length < 0)
135 {
136 errno = EINVAL;
137 return -1;
138 }
139 if (!SetFileSize (handle, length))
140 {
141 switch (GetLastError ())
142 {
143 case ERROR_ACCESS_DENIED:
144 errno = EACCES;
145 break;
146 case ERROR_HANDLE_DISK_FULL:
147 case ERROR_DISK_FULL:
148 case ERROR_DISK_TOO_FRAGMENTED:
149 errno = ENOSPC;
150 break;
151 default:
152 errno = EIO;
153 break;
154 }
155 return -1;
156 }
157 return 0;
158}
159
160# else
161
162# include <io.h>
163
164# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
165# include "msvc-inval.h"
166static int
167chsize_nothrow (int fd, long length)
168{
169 int result;
170
171 TRY_MSVC_INVAL
172 {
173 result = _chsize (fd, length);
174 }
175 CATCH_MSVC_INVAL
176 {
177 result = -1;
178 errno = EBADF;
179 }
180 DONE_MSVC_INVAL;
181
182 return result;
183}
184# else
185# define chsize_nothrow _chsize
186# endif
187
188int
189ftruncate (int fd, off_t length)
190{
191 return chsize_nothrow (fd, length);
192}
193
194# endif
195#endif
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette