From ce05139c56abbf21a0c8f81150542ed213d07581 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 24 Jul 2002 17:48:41 +0000 Subject: natFileDescriptorWin32.cc (setLength): New method. 2002-07-24 Tom Tromey Tony Kimball * java/io/natFileDescriptorWin32.cc (setLength): New method. * java/io/natFileDescriptorPosix.cc (setLength): New method. * java/io/RandomAccessFile.java (setLength): New method. * java/io/natFileDescriptorEcos.cc (setLength): New method. * java/io/FileDescriptor.java (setLength): New method. Co-Authored-By: Tony Kimball From-SVN: r55715 --- libjava/ChangeLog | 9 ++++++ libjava/java/io/FileDescriptor.java | 3 +- libjava/java/io/RandomAccessFile.java | 7 +++- libjava/java/io/natFileDescriptorEcos.cc | 5 +++ libjava/java/io/natFileDescriptorPosix.cc | 34 +++++++++++++++++++ libjava/java/io/natFileDescriptorWin32.cc | 54 ++++++++++++++++++++++++++++++- 6 files changed, 109 insertions(+), 3 deletions(-) (limited to 'libjava') diff --git a/libjava/ChangeLog b/libjava/ChangeLog index ff3c72f..75ec4b7 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,12 @@ +2002-07-24 Tom Tromey + Tony Kimball + + * java/io/natFileDescriptorWin32.cc (setLength): New method. + * java/io/natFileDescriptorPosix.cc (setLength): New method. + * java/io/RandomAccessFile.java (setLength): New method. + * java/io/natFileDescriptorEcos.cc (setLength): New method. + * java/io/FileDescriptor.java (setLength): New method. + 2002-07-24 Mark Wielaard * java/lang/reflect/natField.cc (setAddr): Check isAccessible(). diff --git a/libjava/java/io/FileDescriptor.java b/libjava/java/io/FileDescriptor.java index 427a26a..08f8edf 100644 --- a/libjava/java/io/FileDescriptor.java +++ b/libjava/java/io/FileDescriptor.java @@ -1,6 +1,6 @@ // FileDescriptor.java - Open file or device -/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation This file is part of libgcj. @@ -65,6 +65,7 @@ public final class FileDescriptor native void write (byte[] b, int offset, int len) throws IOException, NullPointerException, IndexOutOfBoundsException; native void close () throws IOException; + native void setLength (long pos) throws IOException; // EOF_TRUNC is true if a request to seek past the end of file // should actually stop at the end of file. If false, then a seek // past the end is ok (and if a subsequent write occurs the file diff --git a/libjava/java/io/RandomAccessFile.java b/libjava/java/io/RandomAccessFile.java index 418974c..81b7050 100644 --- a/libjava/java/io/RandomAccessFile.java +++ b/libjava/java/io/RandomAccessFile.java @@ -1,6 +1,6 @@ // RandomAccessFile.java -/* Copyright (C) 1998, 1999, 2001 Free Software Foundation +/* Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation This file is part of libgcj. @@ -40,6 +40,11 @@ public class RandomAccessFile implements DataOutput, DataInput return fd.getFilePointer(); } + public void setLength (long pos) throws IOException + { + fd.setLength(pos); + } + public long length () throws IOException { return fd.length(); diff --git a/libjava/java/io/natFileDescriptorEcos.cc b/libjava/java/io/natFileDescriptorEcos.cc index 8e1dd95..96744f4 100644 --- a/libjava/java/io/natFileDescriptorEcos.cc +++ b/libjava/java/io/natFileDescriptorEcos.cc @@ -95,6 +95,11 @@ java::io::FileDescriptor::close (void) { } +void +java::io::FileDescriptor::setLength (long) +{ +} + jint java::io::FileDescriptor::seek (jlong pos, jint whence, jboolean) { diff --git a/libjava/java/io/natFileDescriptorPosix.cc b/libjava/java/io/natFileDescriptorPosix.cc index bfe0009..fb11d62 100644 --- a/libjava/java/io/natFileDescriptorPosix.cc +++ b/libjava/java/io/natFileDescriptorPosix.cc @@ -17,6 +17,8 @@ details. */ #include #include #include +#include +#include #ifdef HAVE_SYS_IOCTL_H #define BSD_COMP /* Get FIONREAD on Solaris2. */ @@ -189,6 +191,38 @@ java::io::FileDescriptor::close (void) throw new IOException (JvNewStringLatin1 (strerror (errno))); } +void +java::io::FileDescriptor::setLength (jlong pos) +{ + struct stat sb; + off_t orig; + + if (::fstat (fd, &sb)) + throw new IOException (JvNewStringLatin1 (strerror (errno))); + + if ((jlong) sb.st_size == pos) + return; + + orig = ::lseek (fd, (off_t) 0, SEEK_CUR); + if (orig == -1) + throw new IOException (JvNewStringLatin1 (strerror (errno))); + + // If the file is too short, we extend it. We can't rely on + // ftruncate() extending the file. So we lseek() to 1 byte less + // than we want, and then we write a single byte at the end. + if ((jlong) sb.st_size < pos) + { + if (::lseek (fd, (off_t) (pos - 1), SEEK_SET) == -1) + throw new IOException (JvNewStringLatin1 (strerror (errno))); + char out = '\0'; + int r = ::write (fd, &out, 1); + if (r <= 0 || ::lseek (fd, orig, SEEK_SET) == -1) + throw new IOException (JvNewStringLatin1 (strerror (errno))); + } + else if (::ftruncate (fd, (off_t) pos)) + throw new IOException (JvNewStringLatin1 (strerror (errno))); +} + jint java::io::FileDescriptor::seek (jlong pos, jint whence, jboolean eof_trunc) { diff --git a/libjava/java/io/natFileDescriptorWin32.cc b/libjava/java/io/natFileDescriptorWin32.cc index f72e39c..e004057 100644 --- a/libjava/java/io/natFileDescriptorWin32.cc +++ b/libjava/java/io/natFileDescriptorWin32.cc @@ -1,6 +1,6 @@ // natFileDescriptorWin32.cc - Native part of FileDescriptor class. -/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of libgcj. @@ -186,6 +186,58 @@ java::io::FileDescriptor::close (void) throw new IOException (JvNewStringLatin1 (winerr ())); } +void +java::io::FileDescriptor::setLength(jlong pos) +{ + LONG liOrigFilePointer; + LONG liNewFilePointer; + LONG liEndFilePointer; + + // Get the original file pointer. + if (SetFilePointer((HANDLE) fd, (LONG) 0, &liOrigFilePointer, + FILE_CURRENT) != (BOOL) 0 + && (GetLastError() != NO_ERROR)) + throw new IOException (JvNewStringLatin1 (winerr ())); + + // Get the length of the file. + if (SetFilePointer((HANDLE) fd, (LONG) 0, &liEndFilePointer, + FILE_END) != (BOOL) 0 + && (GetLastError() != NO_ERROR)) + throw new IOException (JvNewStringLatin1 (winerr ())); + + if ((jlong)liEndFilePointer == pos) + { + // Restore the file pointer. + if (liOrigFilePointer != liEndFilePointer) + { + if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer, + FILE_BEGIN) != (BOOL) 0 + && (GetLastError() != NO_ERROR)) + throw new IOException (JvNewStringLatin1 (winerr ())); + } + return; + } + + // Seek to the new end of file. + if (SetFilePointer((HANDLE) fd, (LONG) pos, &liNewFilePointer, + FILE_BEGIN) != (BOOL) 0 + && (GetLastError() != NO_ERROR)) + throw new IOException (JvNewStringLatin1 (winerr ())); + + // Truncate the file at this point. + if (SetEndOfFile((HANDLE) fd) != (BOOL) 0 && (GetLastError() != NO_ERROR)) + throw new IOException (JvNewStringLatin1 (winerr ())); + + if (liOrigFilePointer < liNewFilePointer) + { + // Restore the file pointer. + if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer, + FILE_BEGIN) != (BOOL) 0 + && (GetLastError() != NO_ERROR)) + throw new IOException (JvNewStringLatin1 (winerr ())); + } +} + jint java::io::FileDescriptor::seek (jlong pos, jint whence, jboolean eof_trunc) { -- cgit v1.1