1 /*
   2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.util.concurrent.atomic.AtomicInteger;
  29 
  30 /**
  31  * Instances of the file descriptor class serve as an opaque handle
  32  * to the underlying machine-specific structure representing an
  33  * open file, an open socket, or another source or sink of bytes.
  34  * The main practical use for a file descriptor is to create a
  35  * {@link FileInputStream} or {@link FileOutputStream} to contain it.
  36  *
  37  * <p>Applications should not create their own file descriptors.
  38  *
  39  * @author  Pavani Diwanji
  40  * @since   JDK1.0
  41  */
  42 public final class FileDescriptor {
  43 
  44     private int fd;
  45 
  46     private long handle;
  47 
  48     /**
  49      * A use counter for tracking the FIS/FOS/RAF instances that
  50      * use this FileDescriptor. The FIS/FOS.finalize() will not release
  51      * the FileDescriptor if it is still under use by any stream.
  52      */
  53     private AtomicInteger useCount;
  54 
  55 
  56     /**
  57      * Constructs an (invalid) FileDescriptor
  58      * object.
  59      */
  60     public /**/ FileDescriptor() {
  61         fd = -1;
  62         handle = -1;
  63         useCount = new AtomicInteger();
  64     }
  65 
  66     static {
  67         initIDs();
  68     }
  69 
  70     // Set up JavaIOFileDescriptorAccess in SharedSecrets
  71     static {
  72         sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
  73             new sun.misc.JavaIOFileDescriptorAccess() {
  74                 public void set(FileDescriptor obj, int fd) {
  75                     obj.fd = fd;
  76                 }
  77 
  78                 public int get(FileDescriptor obj) {
  79                     return obj.fd;
  80                 }
  81 
  82                 public void setHandle(FileDescriptor obj, long handle) {
  83                     obj.handle = handle;
  84                 }
  85 
  86                 public long getHandle(FileDescriptor obj) {
  87                     return obj.handle;
  88                 }
  89             }
  90         );
  91     }
  92 
  93     /**
  94      * A handle to the standard input stream. Usually, this file
  95      * descriptor is not used directly, but rather via the input stream
  96      * known as {@code System.in}.
  97      *
  98      * @see     java.lang.System#in
  99      */
 100     public static final FileDescriptor in = standardStream(0);
 101 
 102     /**
 103      * A handle to the standard output stream. Usually, this file
 104      * descriptor is not used directly, but rather via the output stream
 105      * known as {@code System.out}.
 106      * @see     java.lang.System#out
 107      */
 108     public static final FileDescriptor out = standardStream(1);
 109 
 110     /**
 111      * A handle to the standard error stream. Usually, this file
 112      * descriptor is not used directly, but rather via the output stream
 113      * known as {@code System.err}.
 114      *
 115      * @see     java.lang.System#err
 116      */
 117     public static final FileDescriptor err = standardStream(2);
 118 
 119     /**
 120      * Tests if this file descriptor object is valid.
 121      *
 122      * @return  {@code true} if the file descriptor object represents a
 123      *          valid, open file, socket, or other active I/O connection;
 124      *          {@code false} otherwise.
 125      */
 126     public boolean valid() {
 127         return ((handle != -1) || (fd != -1));
 128     }
 129 
 130     /**
 131      * Force all system buffers to synchronize with the underlying
 132      * device.  This method returns after all modified data and
 133      * attributes of this FileDescriptor have been written to the
 134      * relevant device(s).  In particular, if this FileDescriptor
 135      * refers to a physical storage medium, such as a file in a file
 136      * system, sync will not return until all in-memory modified copies
 137      * of buffers associated with this FileDesecriptor have been
 138      * written to the physical medium.
 139      *
 140      * sync is meant to be used by code that requires physical
 141      * storage (such as a file) to be in a known state  For
 142      * example, a class that provided a simple transaction facility
 143      * might use sync to ensure that all changes to a file caused
 144      * by a given transaction were recorded on a storage medium.
 145      *
 146      * sync only affects buffers downstream of this FileDescriptor.  If
 147      * any in-memory buffering is being done by the application (for
 148      * example, by a BufferedOutputStream object), those buffers must
 149      * be flushed into the FileDescriptor (for example, by invoking
 150      * OutputStream.flush) before that data will be affected by sync.
 151      *
 152      * @exception SyncFailedException
 153      *        Thrown when the buffers cannot be flushed,
 154      *        or because the system cannot guarantee that all the
 155      *        buffers have been synchronized with physical media.
 156      * @since     JDK1.1
 157      */
 158     public native void sync() throws SyncFailedException;
 159 
 160     /* This routine initializes JNI field offsets for the class */
 161     private static native void initIDs();
 162 
 163     private static native long set(int d);
 164 
 165     private static FileDescriptor standardStream(int fd) {
 166         FileDescriptor desc = new FileDescriptor();
 167         desc.handle = set(fd);
 168         return desc;
 169     }
 170 
 171     // package private methods used by FIS, FOS and RAF.
 172 
 173     int incrementAndGetUseCount() {
 174         return useCount.incrementAndGet();
 175     }
 176 
 177     int decrementAndGetUseCount() {
 178         return useCount.decrementAndGet();
 179     }
 180 }