1 /*
2  * Copyright (c) 1995, 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 android.system.ErrnoException;
29 import android.system.Os;
30 import static android.system.OsConstants.F_DUPFD_CLOEXEC;
31 
32 import java.util.concurrent.atomic.AtomicInteger;
33 
34 /**
35  * Instances of the file descriptor class serve as an opaque handle
36  * to the underlying machine-specific structure representing an open
37  * file, an open socket, or another source or sink of bytes. The
38  * main practical use for a file descriptor is to create a
39  * <code>FileInputStream</code> or <code>FileOutputStream</code> to
40  * contain it.
41  * <p>
42  * Applications should not create their own file descriptors.
43  *
44  * @author  Pavani Diwanji
45  * @see     java.io.FileInputStream
46  * @see     java.io.FileOutputStream
47  * @since   JDK1.0
48  */
49 // Android-changed: Removed parent reference counting. Creator is responsible for closing
50 // the file descriptor.
51 public final class FileDescriptor {
52 
53     private int descriptor;
54 
55     /**
56      * Constructs an (invalid) FileDescriptor
57      * object.
58      */
FileDescriptor()59     public FileDescriptor() {
60         descriptor = -1;
61     }
62 
FileDescriptor(int descriptor)63     private FileDescriptor(int descriptor) {
64         this.descriptor = descriptor;
65     }
66 
67     /**
68      * A handle to the standard input stream. Usually, this file
69      * descriptor is not used directly, but rather via the input stream
70      * known as <code>System.in</code>.
71      *
72      * @see     java.lang.System#in
73      */
74     public static final FileDescriptor in = dupFd(0);
75 
76     /**
77      * A handle to the standard output stream. Usually, this file
78      * descriptor is not used directly, but rather via the output stream
79      * known as <code>System.out</code>.
80      * @see     java.lang.System#out
81      */
82     public static final FileDescriptor out = dupFd(1);
83 
84     /**
85      * A handle to the standard error stream. Usually, this file
86      * descriptor is not used directly, but rather via the output stream
87      * known as <code>System.err</code>.
88      *
89      * @see     java.lang.System#err
90      */
91     public static final FileDescriptor err = dupFd(2);
92 
93     /**
94      * Tests if this file descriptor object is valid.
95      *
96      * @return  <code>true</code> if the file descriptor object represents a
97      *          valid, open file, socket, or other active I/O connection;
98      *          <code>false</code> otherwise.
99      */
valid()100     public boolean valid() {
101         return descriptor != -1;
102     }
103 
104     /**
105      * Force all system buffers to synchronize with the underlying
106      * device.  This method returns after all modified data and
107      * attributes of this FileDescriptor have been written to the
108      * relevant device(s).  In particular, if this FileDescriptor
109      * refers to a physical storage medium, such as a file in a file
110      * system, sync will not return until all in-memory modified copies
111      * of buffers associated with this FileDescriptor have been
112      * written to the physical medium.
113      *
114      * sync is meant to be used by code that requires physical
115      * storage (such as a file) to be in a known state  For
116      * example, a class that provided a simple transaction facility
117      * might use sync to ensure that all changes to a file caused
118      * by a given transaction were recorded on a storage medium.
119      *
120      * sync only affects buffers downstream of this FileDescriptor.  If
121      * any in-memory buffering is being done by the application (for
122      * example, by a BufferedOutputStream object), those buffers must
123      * be flushed into the FileDescriptor (for example, by invoking
124      * OutputStream.flush) before that data will be affected by sync.
125      *
126      * @exception SyncFailedException
127      *        Thrown when the buffers cannot be flushed,
128      *        or because the system cannot guarantee that all the
129      *        buffers have been synchronized with physical media.
130      * @since     JDK1.1
131      */
sync()132     public native void sync() throws SyncFailedException;
133 
134     /**
135      * Returns the int descriptor. It's highly unlikely you should be calling this. Please discuss
136      * your needs with a libcore maintainer before using this method.
137      * @hide internal use only
138      */
139     // Android-added.
getInt$()140     public final int getInt$() {
141         return descriptor;
142     }
143 
144     /**
145      * Sets the int descriptor. It's highly unlikely you should be calling this. Please discuss
146      * your needs with a libcore maintainer before using this method.
147      * @hide internal use only
148      */
149     // Android-added.
setInt$(int fd)150     public final void setInt$(int fd) {
151         this.descriptor = fd;
152     }
153 
154     /**
155      * @hide internal use only
156      */
157     // Android-added.
isSocket$()158     public boolean isSocket$() {
159         return isSocket(descriptor);
160     }
161 
162     // Android-added.
dupFd(int fd)163     private static FileDescriptor dupFd(int fd) {
164         try {
165             return new FileDescriptor(Os.fcntlInt(new FileDescriptor(fd), F_DUPFD_CLOEXEC, 0));
166         } catch (ErrnoException e) {
167             throw new RuntimeException(e);
168         }
169     }
170 
isSocket(int descriptor)171     private static native boolean isSocket(int descriptor);
172     // Set up JavaIOFileDescriptorAccess in SharedSecrets
173     static {
sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess( new sun.misc.JavaIOFileDescriptorAccess() { public void set(FileDescriptor obj, int fd) { obj.descriptor = fd; } public int get(FileDescriptor obj) { return obj.descriptor; } public void setHandle(FileDescriptor obj, long handle) { throw new UnsupportedOperationException(); } public long getHandle(FileDescriptor obj) { throw new UnsupportedOperationException(); } } )174         sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
175                 new sun.misc.JavaIOFileDescriptorAccess() {
176                     public void set(FileDescriptor obj, int fd) {
177                         obj.descriptor = fd;
178                     }
179 
180                     public int get(FileDescriptor obj) {
181                         return obj.descriptor;
182                     }
183 
184                     public void setHandle(FileDescriptor obj, long handle) {
185                         throw new UnsupportedOperationException();
186                     }
187 
188                     public long getHandle(FileDescriptor obj) {
189                         throw new UnsupportedOperationException();
190                     }
191                 }
192         );
193     }
194 
195 
196 }
197