• 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 // Android-changed: Removed parent reference counting. Creator is responsible for closing
50 // the file descriptor.
51 public final class FileDescriptor {
52 
53     // Android-changed: Renamed fd to descriptor to avoid issues with JNI/reflection
54     // 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     /**
67      * Constructs an (invalid) FileDescriptor
68      * object.
69      */
FileDescriptor()70     public /**/ FileDescriptor() {
71         descriptor = -1;
72     }
73 
FileDescriptor(int descriptor)74     private /* */ FileDescriptor(int descriptor) {
75         this.descriptor = descriptor;
76     }
77 
78     /**
79      * A handle to the standard input stream. Usually, this file
80      * descriptor is not used directly, but rather via the input stream
81      * known as <code>System.in</code>.
82      *
83      * @see     java.lang.System#in
84      */
85     // Android-changed: Duplicates of FDs needed for RuntimeInit#redirectLogStreams
86     public static final FileDescriptor in = dupFd(0);
87 
88     /**
89      * A handle to the standard output stream. Usually, this file
90      * descriptor is not used directly, but rather via the output stream
91      * known as <code>System.out</code>.
92      * @see     java.lang.System#out
93      */
94     // Android-changed: Duplicates of FDs needed for RuntimeInit#redirectLogStreams
95     public static final FileDescriptor out = dupFd(1);
96 
97     /**
98      * A handle to the standard error stream. Usually, this file
99      * descriptor is not used directly, but rather via the output stream
100      * known as <code>System.err</code>.
101      *
102      * @see     java.lang.System#err
103      */
104     // Android-changed: Duplicates of FDs needed for RuntimeInit#redirectLogStreams
105     public static final FileDescriptor err = dupFd(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 intialization
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: Methods to enable ownership enforcement of Unix file descriptors.
173     /**
174      * Returns the owner ID of this FileDescriptor. It's highly unlikely you should be calling this.
175      * Please discuss your needs with a libcore maintainer before using this method.
176      * @hide internal use only
177      */
getOwnerId$()178     public long getOwnerId$() {
179         return this.ownerId;
180     }
181 
182     /**
183      * Sets the owner ID of this FileDescriptor. The owner ID does not need to be unique, but it is
184      * assumed that clashes are rare. See bionic/include/android/fdsan.h for more details.
185      *
186      * It's highly unlikely you should be calling this.
187      * Please discuss your needs with a libcore maintainer before using this method.
188      * @param owner the owner ID of the Object that is responsible for closing this FileDescriptor
189      * @hide internal use only
190      */
setOwnerId$(long newOwnerId)191     public void setOwnerId$(long newOwnerId) {
192         this.ownerId = newOwnerId;
193     }
194 
195     /**
196      * Returns a copy of this FileDescriptor, and sets this to an invalid state.
197      * @hide internal use only
198      */
release$()199     public FileDescriptor release$() {
200       FileDescriptor result = new FileDescriptor();
201       result.descriptor = this.descriptor;
202       result.ownerId = this.ownerId;
203       this.descriptor = -1;
204       this.ownerId = FileDescriptor.NO_OWNER;
205       return result;
206     }
207     // END Android-added: Methods to enable ownership enforcement of Unix file descriptors.
208 
209     /**
210      * @hide internal use only
211      */
212     // Android-added: Needed for framework to test if it's a socket
isSocket$()213     public boolean isSocket$() {
214         return isSocket(descriptor);
215     }
216 
217     // Android-added: Needed for RuntimeInit#redirectLogStreams.
dupFd(int fd)218     private static FileDescriptor dupFd(int fd) {
219         try {
220             return new FileDescriptor(Os.fcntlInt(new FileDescriptor(fd), F_DUPFD_CLOEXEC, 0));
221         } catch (ErrnoException e) {
222             throw new RuntimeException(e);
223         }
224     }
225 
isSocket(int descriptor)226     private static native boolean isSocket(int descriptor);
227     // Set up JavaIOFileDescriptorAccess in SharedSecrets
228     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(); } } )229         sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
230             new sun.misc.JavaIOFileDescriptorAccess() {
231                 public void set(FileDescriptor obj, int fd) {
232                     obj.descriptor = fd;
233                 }
234 
235                 public int get(FileDescriptor obj) {
236                     return obj.descriptor;
237                 }
238 
239                 public void setHandle(FileDescriptor obj, long handle) {
240                     throw new UnsupportedOperationException();
241                 }
242 
243                 public long getHandle(FileDescriptor obj) {
244                     throw new UnsupportedOperationException();
245                 }
246             }
247         );
248     }
249 // Android-removed: Removed method required for parents reference counting
250 }
251