Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6322678

FileInputStream(FileDescriptor) throws IOException when reading a file if FD is invalid

    Details

    • Subcomponent:
    • Resolved In Build:
      b06
    • CPU:
      other, x86, sparc
    • OS:
      solaris, windows_nt, windows_2000, windows_xp, windows_2008
    • Verification:
      Not verified

      Backports

        Description

        OPERATING SYSTEM
        Windows XP
        FULL JDK VERSION
        java version "1.5.0_04"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
        Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode)
        DESCRIPTION
        The problem relates to the use of the api constructor method
        FileInputStream(FileDescriptor), in combination with the class's getFD()
        method and its finalizer method. The constructor creates a new
        FileInputStream Object based on an existing FileDescriptor Object.
        By first creating a FileInputStream using a different constructor,
        and then calling getFD(), the FileInputStream(FileDescriptor)
        constructor can be used to create another FileInputStream.
        This means we have two FileInputStreams using the same FileDescriptor class,
        and so the same native fd. If one of these objects hten becomes eligible for
        gc, the finalizer can run, which will close the native fd, even though
        the other FileInputStream object is still using it.
        A testcase that reproduces this problem is specified below:
        ==============
        import java.io.*;
        public class FIS {
          public static void main(String[] args) {
            try {
               /*Create initial FIS for file */
                FileInputStream fis1 = new FileInputStream("thefile.txt");
              /* Get the FileDescriptor from the fis */
                FileDescriptor fd = fis1.getFD();
              /* Create a new FIS based on the existing FD (so the two FIS's share the same native fd) */
                FileInputStream fis2 = new FileInputStream(fd);
              /* allow fis1 to be gc'ed */
              fis1 = null;
              int ret = 0;
              while(ret >= 0) {
                /* encourage gc */
                  System.gc();
                /* read from fis2 - when fis1 is gc'ed and finalizer is run, read will fail */
                  System.out.println("about to read");
                  ret = fis2.read();
              }
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
        ===============
        This would be a problem whenever a FileDescripter from any existing Stream
        is passed into a FileInputStream or in fact to any Stream which has a
        constructor that takes a FileDescriptor and has a finalizer that closes
        the fd (i.e. FileOutputStream would have the same problem.)
        This looks like an api issue.
        The finalizer seems a sensible thing to have, so that if we forget to close
        the FileInputStream, it (and the native fd) are closed at some point.
        However, this logic requires that a native fd is uniquely associated with
        a single stream, but this is not guaranteed when you can create a FileInputStream
        based on an existing FileDescriptor object(and so existing native fd).

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  jhangalsunw Jayalaxmi Hangal (Inactive)
                  Reporter:
                  elarsen Erik Larsen (Inactive)
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  2 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Imported:
                    Indexed: