/* * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package sun.misc;import java.util.Hashtable;/** * This class provides ANSI/ISO C signal support. A Java program can register * signal handlers for the current process. There are two restrictions: * <ul> * <li> * Java code cannot register a handler for signals that are already used * by the Java VM implementation. The <code>Signal.handle</code> * function raises an <code>IllegalArgumentException</code> if such an attempt * is made. * <li> * When <code>Signal.handle</code> is called, the VM internally registers a * special C signal handler. There is no way to force the Java signal handler * to run synchronously before the C signal handler returns. Instead, when the * VM receives a signal, the special C signal handler creates a new thread * (at priority <code>Thread.MAX_PRIORITY</code>) to * run the registered Java signal handler. The C signal handler immediately * returns. Note that because the Java signal handler runs in a newly created * thread, it may not actually be executed until some time after the C signal * handler returns. * </ul> * <p> * Signal objects are created based on their names. For example: * <blockquote><pre> * new Signal("INT"); * </blockquote></pre> * constructs a signal object corresponding to <code>SIGINT</code>, which is * typically produced when the user presses <code>Ctrl-C</code> at the command line. * The <code>Signal</code> constructor throws <code>IllegalArgumentException</code> * when it is passed an unknown signal. * <p> * This is an example of how Java code handles <code>SIGINT</code>: * <blockquote><pre> * SignalHandler handler = new SignalHandler () { * public void handle(Signal sig) { * ... // handle SIGINT * } * }; * Signal.handle(new Signal("INT"), handler); * </blockquote></pre> * * @author Sheng Liang * @author Bill Shannon * @see sun.misc.SignalHandler * @since 1.2 */public final class Signal { private static Hashtable handlers = new Hashtable(4); private static Hashtable signals = new Hashtable(4); private int number; private String name; /* Returns the signal number */ public int getNumber() { return number; } /** * Returns the signal name. * * @return the name of the signal. * @see sun.misc.Signal#Signal(String name) */ public String getName() { return name; } /** * Compares the equality of two <code>Signal</code> objects. * * @param other the object to compare with. * @return whether two <code>Signal</code> objects are equal. */ public boolean equals(Object other) { if (this == other) { return true; } if (other == null || !(other instanceof Signal)) { return false; } Signal other1 = (Signal)other; return name.equals(other1.name) && (number == other1.number); } /** * Returns a hashcode for this Signal. * * @return a hash code value for this object. */ public int hashCode() { return number; } /** * Returns a string representation of this signal. For example, "SIGINT" * for an object constructed using <code>new Signal ("INT")</code>. * * @return a string representation of the signal */ public String toString() { return "SIG" + name; } /** * Constructs a signal from its name. * * @param name the name of the signal. * @exception IllegalArgumentException unknown signal * @see sun.misc.Signal#getName() */ public Signal(String name) { number = findSignal(name); this.name = name; if (number < 0) { throw new IllegalArgumentException("Unknown signal: " + name); } } /** * Registers a signal handler. * * @param sig a signal * @param handler the handler to be registered with the given signal. * @result the old handler * @exception IllegalArgumentException the signal is in use by the VM * @see sun.misc.Signal#raise(Signal sig) * @see sun.misc.SignalHandler * @see sun.misc.SignalHandler#SIG_DFL * @see sun.misc.SignalHandler#SIG_IGN */ public static synchronized SignalHandler handle(Signal sig, SignalHandler handler) throws IllegalArgumentException { long newH = (handler instanceof NativeSignalHandler) ? ((NativeSignalHandler)handler).getHandler() : 2; long oldH = handle0(sig.number, newH); if (oldH == -1) { throw new IllegalArgumentException ("Signal already used by VM or OS: " + sig); } signals.put(new Integer(sig.number), sig); synchronized (handlers) { SignalHandler oldHandler = (SignalHandler)handlers.get(sig); handlers.remove(sig); if (newH == 2) { handlers.put(sig, handler); } if (oldH == 0) { return SignalHandler.SIG_DFL; } else if (oldH == 1) { return SignalHandler.SIG_IGN; } else if (oldH == 2) { return oldHandler; } else { return new NativeSignalHandler(oldH); } } } /** * Raises a signal in the current process. * * @param sig a signal * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler) */ public static void raise(Signal sig) throws IllegalArgumentException { if (handlers.get(sig) == null) { throw new IllegalArgumentException("Unhandled signal: " + sig); } raise0(sig.number); } /* Called by the VM to execute Java signal handlers. */ private static void dispatch(final int number) { final Signal sig = (Signal)signals.get(new Integer(number)); final SignalHandler handler = (SignalHandler)handlers.get(sig); Runnable runnable = new Runnable () { public void run() { // Don't bother to reset the priority. Signal handler will // run at maximum priority inherited from the VM signal // dispatch thread. // Thread.currentThread().setPriority(Thread.NORM_PRIORITY); handler.handle(sig); } }; if (handler != null) { new Thread(runnable, sig + " handler").start(); } } /* Find the signal number, given a name. Returns -1 for unknown signals. */ private static native int findSignal(String sigName); /* Registers a native signal handler, and returns the old handler. * Handler values: * 0 default handler * 1 ignore the signal * 2 call back to Signal.dispatch * other arbitrary native signal handlers */ private static native long handle0(int sig, long nativeH); /* Raise a given signal number */ private static native void raise0(int sig);}
/*
* Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.util.Hashtable;
/**
* This class provides ANSI/ISO C signal support. A Java program can register
* signal handlers for the current process. There are two restrictions:
* <ul>
* <li>
* Java code cannot register a handler for signals that are already used
* by the Java VM implementation. The <code>Signal.handle</code>
* function raises an <code>IllegalArgumentException</code> if such an attempt
* is made.
* <li>
* When <code>Signal.handle</code> is called, the VM internally registers a
* special C signal handler. There is no way to force the Java signal handler
* to run synchronously before the C signal handler returns. Instead, when the
* VM receives a signal, the special C signal handler creates a new thread
* (at priority <code>Thread.MAX_PRIORITY</code>) to
* run the registered Java signal handler. The C signal handler immediately
* returns. Note that because the Java signal handler runs in a newly created
* thread, it may not actually be executed until some time after the C signal
* handler returns.
* </ul>
* <p>
* Signal objects are created based on their names. For example:
* <blockquote><pre>
* new Signal("INT");
* </blockquote></pre>
* constructs a signal object corresponding to <code>SIGINT</code>, which is
* typically produced when the user presses <code>Ctrl-C</code> at the command line.
* The <code>Signal</code> constructor throws <code>IllegalArgumentException</code>
* when it is passed an unknown signal.
* <p>
* This is an example of how Java code handles <code>SIGINT</code>:
* <blockquote><pre>
* SignalHandler handler = new SignalHandler () {
* public void handle(Signal sig) {
* ... // handle SIGINT
* }
* };
* Signal.handle(new Signal("INT"), handler);
* </blockquote></pre>
*
* @author Sheng Liang
* @author Bill Shannon
* @see sun.misc.SignalHandler
* @since 1.2
*/
public final class Signal {
private static Hashtable handlers = new Hashtable(4);
private static Hashtable signals = new Hashtable(4);
private int number;
private String name;
/* Returns the signal number */
public int getNumber() {
return number;
}
/**
* Returns the signal name.
*
* @return the name of the signal.
* @see sun.misc.Signal#Signal(String name)
*/
public String getName() {
return name;
}
/**
* Compares the equality of two <code>Signal</code> objects.
*
* @param other the object to compare with.
* @return whether two <code>Signal</code> objects are equal.
*/
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || !(other instanceof Signal)) {
return false;
}
Signal other1 = (Signal)other;
return name.equals(other1.name) && (number == other1.number);
}
/**
* Returns a hashcode for this Signal.
*
* @return a hash code value for this object.
*/
public int hashCode() {
return number;
}
/**
* Returns a string representation of this signal. For example, "SIGINT"
* for an object constructed using <code>new Signal ("INT")</code>.
*
* @return a string representation of the signal
*/
public String toString() {
return "SIG" + name;
}
/**
* Constructs a signal from its name.
*
* @param name the name of the signal.
* @exception IllegalArgumentException unknown signal
* @see sun.misc.Signal#getName()
*/
public Signal(String name) {
number = findSignal(name);
this.name = name;
if (number < 0) {
throw new IllegalArgumentException("Unknown signal: " + name);
}
}
/**
* Registers a signal handler.
*
* @param sig a signal
* @param handler the handler to be registered with the given signal.
* @result the old handler
* @exception IllegalArgumentException the signal is in use by the VM
* @see sun.misc.Signal#raise(Signal sig)
* @see sun.misc.SignalHandler
* @see sun.misc.SignalHandler#SIG_DFL
* @see sun.misc.SignalHandler#SIG_IGN
*/
public static synchronized SignalHandler handle(Signal sig,
SignalHandler handler)
throws IllegalArgumentException {
long newH = (handler instanceof NativeSignalHandler) ?
((NativeSignalHandler)handler).getHandler() : 2;
long oldH = handle0(sig.number, newH);
if (oldH == -1) {
throw new IllegalArgumentException
("Signal already used by VM or OS: " + sig);
}
signals.put(new Integer(sig.number), sig);
synchronized (handlers) {
SignalHandler oldHandler = (SignalHandler)handlers.get(sig);
handlers.remove(sig);
if (newH == 2) {
handlers.put(sig, handler);
}
if (oldH == 0) {
return SignalHandler.SIG_DFL;
} else if (oldH == 1) {
return SignalHandler.SIG_IGN;
} else if (oldH == 2) {
return oldHandler;
} else {
return new NativeSignalHandler(oldH);
}
}
}
/**
* Raises a signal in the current process.
*
* @param sig a signal
* @see sun.misc.Signal#handle(Signal sig, SignalHandler handler)
*/
public static void raise(Signal sig) throws IllegalArgumentException {
if (handlers.get(sig) == null) {
throw new IllegalArgumentException("Unhandled signal: " + sig);
}
raise0(sig.number);
}
/* Called by the VM to execute Java signal handlers. */
private static void dispatch(final int number) {
final Signal sig = (Signal)signals.get(new Integer(number));
final SignalHandler handler = (SignalHandler)handlers.get(sig);
Runnable runnable = new Runnable () {
public void run() {
// Don't bother to reset the priority. Signal handler will
// run at maximum priority inherited from the VM signal
// dispatch thread.
// Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
handler.handle(sig);
}
};
if (handler != null) {
new Thread(runnable, sig + " handler").start();
}
}
/* Find the signal number, given a name. Returns -1 for unknown signals. */
private static native int findSignal(String sigName);
/* Registers a native signal handler, and returns the old handler.
* Handler values:
* 0 default handler
* 1 ignore the signal
* 2 call back to Signal.dispatch
* other arbitrary native signal handlers
*/
private static native long handle0(int sig, long nativeH);
/* Raise a given signal number */
private static native void raise0(int sig);
}