• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1995, 2011, 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 public final class FileDescriptor {
50     // Android-changed: Removed parent reference counting.
51     // The creator is responsible for closing the file descriptor.
52 
53     // Android-changed: Renamed fd to descriptor.
54     // Renaming is to avoid issues with JNI/reflection fetching the descriptor value.
55     private int descriptor;
56 
57     // Android-added: Track fd owner to guard against accidental closure. http://b/110100358
58     // The owner on the libc side is an pointer-sized value that can be set to an arbitrary
59     // value (with 0 meaning 'unowned'). libcore chooses to use System.identityHashCode.
60     private long ownerId = NO_OWNER;
61 
62     // Android-added: value of ownerId indicating that a FileDescriptor is unowned.
63     /** @hide */
64     public static final long NO_OWNER = 0L;
65 
66     // Android-added: lock for release$.
67     private final Object releaseLock = new Object();
68 
69     /**
70      * Constructs an (invalid) FileDescriptor
71      * object.
72      */
FileDescriptor()73     public /**/ FileDescriptor() {
74         descriptor = -1;
75     }
76 
FileDescriptor(int descriptor)77     private /* */ FileDescriptor(int descriptor) {
78         this.descriptor = descriptor;
79     }
80 
81     /**
82      * A handle to the standard input stream. Usually, this file
83      * descriptor is not used directly, but rather via the input stream
84      * known as <code>System.in</code>.
85      *
86      * @see     java.lang.System#in
87      */
88     public static final FileDescriptor in = new FileDescriptor(0);
89 
90     /**
91      * A handle to the standard output stream. Usually, this file
92      * descriptor is not used directly, but rather via the output stream
93      * known as <code>System.out</code>.
94      * @see     java.lang.System#out
95      */
96     public static final FileDescriptor out = new FileDescriptor(1);
97 
98     /**
99      * A handle to the standard error stream. Usually, this file
100      * descriptor is not used directly, but rather via the output stream
101      * known as <code>System.err</code>.
102      *
103      * @see     java.lang.System#err
104      */
105     public static final FileDescriptor err = new FileDescriptor(2);
106 
107     /**
108      * Tests if this file descriptor object is valid.
109      *
110      * @return  <code>true</code> if the file descriptor object represents a
111      *          valid, open file, socket, or other active I/O connection;
112      *          <code>false</code> otherwise.
113      */
valid()114     public boolean valid() {
115         return descriptor != -1;
116     }
117 
118     /**
119      * Force all system buffers to synchronize with the underlying
120      * device.  This method returns after all modified data and
121      * attributes of this FileDescriptor have been written to the
122      * relevant device(s).  In particular, if this FileDescriptor
123      * refers to a physical storage medium, such as a file in a file
124      * system, sync will not return until all in-memory modified copies
125      * of buffers associated with this FileDescriptor have been
126      * written to the physical medium.
127      *
128      * sync is meant to be used by code that requires physical
129      * storage (such as a file) to be in a known state  For
130      * example, a class that provided a simple transaction facility
131      * might use sync to ensure that all changes to a file caused
132      * by a given transaction were recorded on a storage medium.
133      *
134      * sync only affects buffers downstream of this FileDescriptor.  If
135      * any in-memory buffering is being done by the application (for
136      * example, by a BufferedOutputStream object), those buffers must
137      * be flushed into the FileDescriptor (for example, by invoking
138      * OutputStream.flush) before that data will be affected by sync.
139      *
140      * @exception SyncFailedException
141      *        Thrown when the buffers cannot be flushed,
142      *        or because the system cannot guarantee that all the
143      *        buffers have been synchronized with physical media.
144      * @since     JDK1.1
145      */
sync()146     public native void sync() throws SyncFailedException;
147 
148     // Android-removed: initIDs not used to allow compile-time initialization.
149     /* This routine initializes JNI field offsets for the class */
150     //private static native void initIDs();
151 
152     // Android-added: Needed for framework to access descriptor value.
153     /**
154      * Returns the int descriptor. It's highly unlikely you should be calling this. Please discuss
155      * your needs with a libcore maintainer before using this method.
156      * @hide internal use only
157      */
getInt$()158     public final int getInt$() {
159         return descriptor;
160     }
161 
162     // Android-added: Needed for framework to access descriptor value.
163     /**
164      * Sets the int descriptor. It's highly unlikely you should be calling this. Please discuss
165      * your needs with a libcore maintainer before using this method.
166      * @hide internal use only
167      */
setInt$(int fd)168     public final void setInt$(int fd) {
169         this.descriptor = fd;
170     }
171 
172     // BEGIN Android-added: Method to clone standard file descriptors.
173     // Required as a consequence of RuntimeInit#redirectLogStreams. Cloning is used in
174     // ZygoteHooks.onEndPreload().
175     /**
176      * Clones the current native file descriptor and uses this for this FileDescriptor instance.
177      *
178      * This method does not close the current native file descriptor.
179      *
180      * @hide internal use only
181      */
cloneForFork()182     public void cloneForFork() {
183         try {
184             int newDescriptor = Os.fcntlInt(this, F_DUPFD_CLOEXEC, 0);
185             this.descriptor = newDescriptor;
186         } catch (ErrnoException e) {
187             throw new RuntimeException(e);
188         }
189     }
190     // END Android-added: Method to clone standard file descriptors.
191 
192     // BEGIN Android-added: Methods to enable ownership enforcement of Unix file descriptors.
193     /**
194      * Returns the owner ID of this FileDescriptor. It's highly unlikely you should be calling this.
195      * Please discuss your needs with a libcore maintainer before using this method.
196      * @hide internal use only
197      */
getOwnerId$()198     public long getOwnerId$() {
199         return this.ownerId;
200     }
201 
202     /**
203      * Sets the owner ID of this FileDescriptor. The owner ID does not need to be unique, but it is
204      * assumed that clashes are rare. See bionic/include/android/fdsan.h for more details.
205      *
206      * It's highly unlikely you should be calling this.
207      * Please discuss your needs with a libcore maintainer before using this method.
208      * @param owner the owner ID of the Object that is responsible for closing this FileDescriptor
209      * @hide internal use only
210      */
setOwnerId$(long newOwnerId)211     public void setOwnerId$(long newOwnerId) {
212         this.ownerId = newOwnerId;
213     }
214 
215     /**
216      * Returns a copy of this FileDescriptor, and sets this to an invalid state.
217      *
218      * The returned instance is not necessarily {@code valid()}, if the original FileDescriptor
219      * was invalid, or if another thread concurrently calls {@code release$()}.
220      *
221      * @hide internal use only
222      */
release$()223     public FileDescriptor release$() {
224       FileDescriptor result = new FileDescriptor();
225       synchronized (releaseLock) {
226           result.descriptor = this.descriptor;
227           result.ownerId = this.ownerId;
228           this.descriptor = -1;
229           this.ownerId = FileDescriptor.NO_OWNER;
230       }
231 
232       return result;
233     }
234     // END Android-added: Methods to enable ownership enforcement of Unix file descriptors.
235 
236     // Android-added: Needed for framework to test if it's a socket.
237     /**
238      * @hide internal use only
239      */
isSocket$()240     public boolean isSocket$() {
241         return isSocket(descriptor);
242     }
243 
isSocket(int descriptor)244     private static native boolean isSocket(int descriptor);
245     // Set up JavaIOFileDescriptorAccess in SharedSecrets
246     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(); } } )247         sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
248             new sun.misc.JavaIOFileDescriptorAccess() {
249                 public void set(FileDescriptor obj, int fd) {
250                     obj.descriptor = fd;
251                 }
252 
253                 public int get(FileDescriptor obj) {
254                     return obj.descriptor;
255                 }
256 
257                 public void setHandle(FileDescriptor obj, long handle) {
258                     throw new UnsupportedOperationException();
259                 }
260 
261                 public long getHandle(FileDescriptor obj) {
262                     throw new UnsupportedOperationException();
263                 }
264             }
265         );
266     }
267 // Android-removed: Removed method required for parents reference counting.
268 }
269