summaryrefslogtreecommitdiff
path: root/win32/win32.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2002-12-18 02:08:12 +0000
committerGurusamy Sarathy <gsar@cpan.org>2002-12-18 02:08:12 +0000
commit4a9d61009ab1e3df94ef4ecfcc453c9ce73010a4 (patch)
tree5bb486e54adfa3de89ac2448576a0f0d61f72722 /win32/win32.c
parent87755fa7011638e8ad4f4be9619e28e676b74d12 (diff)
downloadperl-4a9d61009ab1e3df94ef4ecfcc453c9ce73010a4.tar.gz
windows: support for large files
note that this change will break binary compatibility with the default 5.8.0 build options; nevertheless I think it is worth having in 5.8.1 (people who want the compatibility can disable the option in the makefile) p4raw-id: //depot/perl@18327
Diffstat (limited to 'win32/win32.c')
-rw-r--r--win32/win32.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 633dbbdbcc..556d62145c 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -3073,6 +3073,55 @@ win32_setmode(int fd, int mode)
return setmode(fd, mode);
}
+DllExport int
+win32_chsize(int fd, Off_t size)
+{
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+ int retval = 0;
+ Off_t cur, end, extend;
+
+ cur = win32_tell(fd);
+ if (cur < 0)
+ return -1;
+ end = win32_lseek(fd, 0, SEEK_END);
+ if (end < 0)
+ return -1;
+ extend = size - end;
+ if (extend == 0) {
+ /* do nothing */
+ }
+ else if (extend > 0) {
+ /* must grow the file, padding with nulls */
+ char b[4096];
+ int oldmode = win32_setmode(fd, O_BINARY);
+ size_t count;
+ memset(b, '\0', sizeof(b));
+ do {
+ count = extend >= sizeof(b) ? sizeof(b) : (size_t)extend;
+ count = win32_write(fd, b, count);
+ if (count < 0) {
+ retval = -1;
+ break;
+ }
+ } while ((extend -= count) > 0);
+ win32_setmode(fd, oldmode);
+ }
+ else {
+ /* shrink the file */
+ win32_lseek(fd, size, SEEK_SET);
+ if (!SetEndOfFile((HANDLE)_get_osfhandle(fd))) {
+ errno = EACCES;
+ retval = -1;
+ }
+ }
+finish:
+ win32_lseek(fd, cur, SEEK_SET);
+ return retval;
+#else
+ return chsize(fd, size);
+#endif
+}
+
DllExport Off_t
win32_lseek(int fd, Off_t offset, int origin)
{