diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 2002-12-18 02:08:12 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 2002-12-18 02:08:12 +0000 |
commit | 4a9d61009ab1e3df94ef4ecfcc453c9ce73010a4 (patch) | |
tree | 5bb486e54adfa3de89ac2448576a0f0d61f72722 /win32/win32.c | |
parent | 87755fa7011638e8ad4f4be9619e28e676b74d12 (diff) | |
download | perl-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.c | 49 |
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) { |