1 /*
   2  * Copyright (c) 1995, 2008, 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 open
  33  * file, an open socket, or another source or sink of bytes. The
  34  * main practical use for a file descriptor is to create a
  35  * <code>FileInputStream</code> or <code>FileOutputStream</code> to
  36  * contain it.
  37  * <p>
  38  * Applications should not create their own file descriptors.
  39  *
  40  * @author  Pavani Diwanji
  41  * @see     java.io.FileInputStream
  42  * @see     java.io.FileOutputStream
  43  * @since   JDK1.0
  44  */
  45 public final class FileDescriptor {
  46 
  47     private int fd;
  48 
  49     /**
  50      * A counter for tracking the FIS/FOS/RAF instances that
  51      * use this FileDescriptor. The FIS/FOS.finalize() will not release
  52      * the FileDescriptor if it is still under user by a stream.
  53      */
  54     private AtomicInteger useCount;
  55 
  56     /**
  57      * Constructs an (invalid) FileDescriptor
  58      * object.
  59      */
  60     public /**/ FileDescriptor() {
  61         fd = -1;
  62         useCount = new AtomicInteger();
  63     }
  64 
  65     private /* */ FileDescriptor(int fd) {
  66         this.fd = fd;
  67         useCount = new AtomicInteger();
  68     }
  69 
  70     /**
  71      * A handle to the standard input stream. Usually, this file
  72      * descriptor is not used directly, but rather via the input stream
  73      * known as <code>System.in</code>.
  74      *
  75      * @see     java.lang.System#in
  76      */
  77     public static final FileDescriptor in = new FileDescriptor(0);
  78 
  79     /**
  80      * A handle to the standard output stream. Usually, this file
  81      * descriptor is not used directly, but rather via the output stream
  82      * known as <code>System.out</code>.
  83      * @see     java.lang.System#out
  84      */
  85     public static final FileDescriptor out = new FileDescriptor(1);
  86 
  87     /**
  88      * A handle to the standard error stream. Usually, this file
  89      * descriptor is not used directly, but rather via the output stream
  90      * known as <code>System.err</code>.
  91      *
  92      * @see     java.lang.System#err
  93      */
  94     public static final FileDescriptor err = new FileDescriptor(2);
  95 
  96     /**
  97      * Tests if this file descriptor object is valid.
  98      *
  99      * @return  <code>true</code> if the file descriptor object represents a
 100      *          valid, open file, socket, or other active I/O connection;
 101      *          <code>false</code> otherwise.
 102      */
 103     public boolean valid() {
 104         return fd != -1;
 105     }
 106 
 107     /**
 108      * Force all system buffers to synchronize with the underlying
 109      * device.  This method returns after all modified data and
 110      * attributes of this FileDescriptor have been written to the
 111      * relevant device(s).  In particular, if this FileDescriptor
 112      * refers to a physical storage medium, such as a file in a file
 113      * system, sync will not return until all in-memory modified copies
 114      * of buffers associated with this FileDescriptor have been
 115      * written to the physical medium.
 116      *
 117      * sync is meant to be used by code that requires physical
 118      * storage (such as a file) to be in a known state  For
 119      * example, a class that provided a simple transaction facility
 120      * might use sync to ensure that all changes to a file caused
 121      * by a given transaction were recorded on a storage medium.
 122      *
 123      * sync only affects buffers downstream of this FileDescriptor.  If
 124      * any in-memory buffering is being done by the application (for
 125      * example, by a BufferedOutputStream object), those buffers must
 126      * be flushed into the FileDescriptor (for example, by invoking
 127      * OutputStream.flush) before that data will be affected by sync.
 128      *
 129      * @exception SyncFailedException
 130      *        Thrown when the buffers cannot be flushed,
 131      *        or because the system cannot guarantee that all the
 132      *        buffers have been synchronized with physical media.
 133      * @since     JDK1.1
 134      */
 135     public native void sync() throws SyncFailedException;
 136 
 137     /* This routine initializes JNI field offsets for the class */
 138     private static native void initIDs();
 139 
 140     static {
 141         initIDs();
 142     }
 143 
 144     // Set up JavaIOFileDescriptorAccess in SharedSecrets
 145     static {
 146         sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
 147             new sun.misc.JavaIOFileDescriptorAccess() {
 148                 public void set(FileDescriptor obj, int fd) {
 149                     obj.fd = fd;
 150                 }
 151 
 152                 public int get(FileDescriptor obj) {
 153                     return obj.fd;
 154                 }
 155 
 156                 public void setHandle(FileDescriptor obj, long handle) {
 157                     throw new UnsupportedOperationException();
 158                 }
 159 
 160                 public long getHandle(FileDescriptor obj) {
 161                     throw new UnsupportedOperationException();
 162                 }
 163             }
 164         );
 165     }
 166 
 167     // package private methods used by FIS, FOS and RAF
 168 
 169     int incrementAndGetUseCount() {
 170         return useCount.incrementAndGet();
 171     }
 172 
 173     int decrementAndGetUseCount() {
 174         return useCount.decrementAndGet();
 175     }
 176 }