e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This code is free software; you can redistribute it and/or modify it
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * under the terms of the GNU General Public License version 2 only, as
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * published by the Free Software Foundation. Oracle designates this
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * particular file as subject to the "Classpath" exception as provided
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * by Oracle in the LICENSE file that accompanied this code.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This code is distributed in the hope that it will be useful, but WITHOUT
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * version 2 for more details (a copy is included in the LICENSE file that
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * accompanied this code).
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * You should have received a copy of the GNU General Public License version
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 2 along with this work; if not, write to the Free Software Foundation,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * or visit www.oracle.com if you need additional information or have any
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa * questions.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekpackage java.io;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekimport java.util.concurrent.atomic.AtomicInteger;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Instances of the file descriptor class serve as an opaque handle
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * to the underlying machine-specific structure representing an
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * open file, an open socket, or another source or sink of bytes.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The main practical use for a file descriptor is to create a
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * {@link FileInputStream} or {@link FileOutputStream} to contain it.
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa *
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa * <p>Applications should not create their own file descriptors.
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * @author Pavani Diwanji
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * @since JDK1.0
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekpublic final class FileDescriptor {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek private int fd;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek private long handle;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * A use counter for tracking the FIS/FOS/RAF instances that
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * use this FileDescriptor. The FIS/FOS.finalize() will not release
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the FileDescriptor if it is still under use by any stream.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek private AtomicInteger useCount;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Constructs an (invalid) FileDescriptor
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * object.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public /**/ FileDescriptor() {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek fd = -1;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek handle = -1;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek useCount = new AtomicInteger();
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek static {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek initIDs();
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek // Set up JavaIOFileDescriptorAccess in SharedSecrets
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek static {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek new sun.misc.JavaIOFileDescriptorAccess() {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public void set(FileDescriptor obj, int fd) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek obj.fd = fd;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public int get(FileDescriptor obj) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return obj.fd;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public void setHandle(FileDescriptor obj, long handle) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek obj.handle = handle;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public long getHandle(FileDescriptor obj) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return obj.handle;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek );
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * A handle to the standard input stream. Usually, this file
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * descriptor is not used directly, but rather via the input stream
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * known as {@code System.in}.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * @see java.lang.System#in
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public static final FileDescriptor in = standardStream(0);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * A handle to the standard output stream. Usually, this file
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * descriptor is not used directly, but rather via the output stream
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * known as {@code System.out}.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * @see java.lang.System#out
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public static final FileDescriptor out = standardStream(1);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * A handle to the standard error stream. Usually, this file
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * descriptor is not used directly, but rather via the output stream
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * known as {@code System.err}.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * @see java.lang.System#err
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public static final FileDescriptor err = standardStream(2);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /**
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Tests if this file descriptor object is valid.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * @return {@code true} if the file descriptor object represents a
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * valid, open file, socket, or other active I/O connection;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * {@code false} otherwise.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek public boolean valid() {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return ((handle != -1) || (fd != -1));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
/**
* Force all system buffers to synchronize with the underlying
* device. This method returns after all modified data and
* attributes of this FileDescriptor have been written to the
* relevant device(s). In particular, if this FileDescriptor
* refers to a physical storage medium, such as a file in a file
* system, sync will not return until all in-memory modified copies
* of buffers associated with this FileDesecriptor have been
* written to the physical medium.
*
* sync is meant to be used by code that requires physical
* storage (such as a file) to be in a known state For
* example, a class that provided a simple transaction facility
* might use sync to ensure that all changes to a file caused
* by a given transaction were recorded on a storage medium.
*
* sync only affects buffers downstream of this FileDescriptor. If
* any in-memory buffering is being done by the application (for
* example, by a BufferedOutputStream object), those buffers must
* be flushed into the FileDescriptor (for example, by invoking
* OutputStream.flush) before that data will be affected by sync.
*
* @exception SyncFailedException
* Thrown when the buffers cannot be flushed,
* or because the system cannot guarantee that all the
* buffers have been synchronized with physical media.
* @since JDK1.1
*/
public native void sync() throws SyncFailedException;
/* This routine initializes JNI field offsets for the class */
private static native void initIDs();
private static native long set(int d);
private static FileDescriptor standardStream(int fd) {
FileDescriptor desc = new FileDescriptor();
desc.handle = set(fd);
return desc;
}
// package private methods used by FIS, FOS and RAF.
int incrementAndGetUseCount() {
return useCount.incrementAndGet();
}
int decrementAndGetUseCount() {
return useCount.decrementAndGet();
}
}