1 /*
2 * Copyright 2003-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 }