Signal.java revision 14107:550572253bd8
17030SN/A/* 213803Stvaleev * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 37030SN/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 47030SN/A * 57030SN/A * This code is free software; you can redistribute it and/or modify it 67030SN/A * under the terms of the GNU General Public License version 2 only, as 77030SN/A * published by the Free Software Foundation. Oracle designates this 87030SN/A * particular file as subject to the "Classpath" exception as provided 97030SN/A * by Oracle in the LICENSE file that accompanied this code. 107030SN/A * 117030SN/A * This code is distributed in the hope that it will be useful, but WITHOUT 127030SN/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137030SN/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 147030SN/A * version 2 for more details (a copy is included in the LICENSE file that 157030SN/A * accompanied this code). 167030SN/A * 177030SN/A * You should have received a copy of the GNU General Public License version 187030SN/A * 2 along with this work; if not, write to the Free Software Foundation, 197030SN/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 207030SN/A * 217030SN/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 227030SN/A * or visit www.oracle.com if you need additional information or have any 237030SN/A * questions. 247030SN/A */ 257030SN/A 267030SN/Apackage sun.misc; 277030SN/A 287030SN/Aimport java.util.Objects; 297030SN/A 307030SN/A/** 317030SN/A * This class provides ANSI/ISO C signal support. A Java program can register 327030SN/A * signal handlers for the current process. There are two restrictions: 337030SN/A * <ul> 347030SN/A * <li> 357030SN/A * Java code cannot register a handler for signals that are already used 367030SN/A * by the Java VM implementation. The <code>Signal.handle</code> 377030SN/A * function raises an <code>IllegalArgumentException</code> if such an attempt 387030SN/A * is made. 397030SN/A * <li> 407030SN/A * When <code>Signal.handle</code> is called, the VM internally registers a 417030SN/A * special C signal handler. There is no way to force the Java signal handler 427030SN/A * to run synchronously before the C signal handler returns. Instead, when the 437030SN/A * VM receives a signal, the special C signal handler creates a new thread 447030SN/A * (at priority <code>Thread.MAX_PRIORITY</code>) to 457030SN/A * run the registered Java signal handler. The C signal handler immediately 467030SN/A * returns. Note that because the Java signal handler runs in a newly created 477030SN/A * thread, it may not actually be executed until some time after the C signal 487030SN/A * handler returns. 497030SN/A * </ul> 507030SN/A * <p> 517030SN/A * Signal objects are created based on their names. For example: 527030SN/A * <blockquote><pre> 537030SN/A * new Signal("INT"); 547030SN/A * </pre></blockquote> 557030SN/A * constructs a signal object corresponding to <code>SIGINT</code>, which is 567030SN/A * typically produced when the user presses <code>Ctrl-C</code> at the command line. 577030SN/A * The <code>Signal</code> constructor throws <code>IllegalArgumentException</code> 587030SN/A * when it is passed an unknown signal. 597030SN/A * <p> 607030SN/A * This is an example of how Java code handles <code>SIGINT</code>: 617030SN/A * <blockquote><pre> 627030SN/A * SignalHandler handler = new SignalHandler () { 637030SN/A * public void handle(Signal sig) { 647030SN/A * ... // handle SIGINT 657030SN/A * } 667030SN/A * }; 677030SN/A * Signal.handle(new Signal("INT"), handler); 687030SN/A * </pre></blockquote> 697030SN/A * 707030SN/A * @author Sheng Liang 717030SN/A * @author Bill Shannon 727030SN/A * @see sun.misc.SignalHandler 737645SN/A * @since 1.2 748001SN/A */ 758001SN/Apublic final class Signal { 768001SN/A 777030SN/A // Delegate to jdk.internal.misc.Signal. 787030SN/A private final jdk.internal.misc.Signal iSignal; 797030SN/A 807030SN/A /* Returns the signal number */ 817819SN/A public int getNumber() { 827030SN/A return iSignal.getNumber(); 837030SN/A } 847030SN/A 857030SN/A /** 867030SN/A * Returns the signal name. 877819SN/A * 887030SN/A * @return the name of the signal. 897030SN/A * @see sun.misc.Signal#Signal(String name) 907030SN/A */ 917030SN/A public String getName() { 927030SN/A return iSignal.getName(); 937030SN/A } 947030SN/A 957030SN/A /** 967030SN/A * Compares the equality of two <code>Signal</code> objects. 977030SN/A * 987030SN/A * @param other the object to compare with. 997030SN/A * @return whether two <code>Signal</code> objects are equal. 1007819SN/A */ 1017030SN/A public boolean equals(Object other) { 1027030SN/A if (this == other) { 1037030SN/A return true; 1047030SN/A } 1057030SN/A if (other == null || !(other instanceof Signal)) { 1067030SN/A return false; 1077030SN/A } 1087030SN/A Signal other1 = (Signal)other; 1097030SN/A return iSignal.equals(other1.iSignal); 1107030SN/A } 1117030SN/A 1127030SN/A /** 1137030SN/A * Returns a hashcode for this Signal. 1147030SN/A * 1157030SN/A * @return a hash code value for this object. 1167030SN/A */ 1177030SN/A public int hashCode() { 1187030SN/A return getNumber(); 1197030SN/A } 1207030SN/A 1217030SN/A /** 1227030SN/A * Returns a string representation of this signal. For example, "SIGINT" 1237030SN/A * for an object constructed using <code>new Signal ("INT")</code>. 1247030SN/A * 1257030SN/A * @return a string representation of the signal 1267030SN/A */ 1277030SN/A public String toString() { 1287030SN/A return iSignal.toString(); 1297030SN/A } 1307030SN/A 1317030SN/A /** 1327030SN/A * Constructs a signal from its name. 1337030SN/A * 1347030SN/A * @param name the name of the signal. 1357030SN/A * @exception IllegalArgumentException unknown signal 1367030SN/A * @see sun.misc.Signal#getName() 1377030SN/A */ 1387030SN/A public Signal(String name) { 1397030SN/A iSignal = new jdk.internal.misc.Signal(name); 1407030SN/A } 1417030SN/A 1427030SN/A /** 1438001SN/A * Registers a signal handler. 1448001SN/A * 1457030SN/A * @param sig a signal 1467030SN/A * @param handler the handler to be registered with the given signal. 1477030SN/A * @return the old handler 1487030SN/A * @exception IllegalArgumentException the signal is in use by the VM 1497030SN/A * @see sun.misc.Signal#raise(Signal sig) 1507030SN/A * @see sun.misc.SignalHandler 1517030SN/A * @see sun.misc.SignalHandler#SIG_DFL 1527030SN/A * @see sun.misc.SignalHandler#SIG_IGN 1537030SN/A */ 1547030SN/A public static synchronized SignalHandler handle(Signal sig, 1557030SN/A SignalHandler handler) 1567030SN/A throws IllegalArgumentException { 1577030SN/A jdk.internal.misc.Signal.Handler oldHandler = jdk.internal.misc.Signal.handle(sig.iSignal, 1587030SN/A InternalMiscHandler.of(sig, handler)); 1597030SN/A return SunMiscHandler.of(sig.iSignal, oldHandler); 1607030SN/A } 1617030SN/A 1627030SN/A /** 1637030SN/A * Raises a signal in the current process. 1647030SN/A * 1657030SN/A * @param sig a signal 1667030SN/A * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler) 1677030SN/A */ 1687030SN/A public static void raise(Signal sig) throws IllegalArgumentException { 1697030SN/A jdk.internal.misc.Signal.raise(sig.iSignal); 1707030SN/A } 1717030SN/A 1727030SN/A /* 1737030SN/A * Wrapper class to proxy a SignalHandler to a jdk.internal.misc.Signal.Handler. 1747030SN/A */ 1757030SN/A static final class InternalMiscHandler implements jdk.internal.misc.Signal.Handler { 1767030SN/A private final SignalHandler handler; 1777030SN/A private final Signal signal; 1787030SN/A 1797030SN/A static jdk.internal.misc.Signal.Handler of(Signal signal, SignalHandler handler) { 1807030SN/A if (handler == SignalHandler.SIG_DFL) { 1817030SN/A return jdk.internal.misc.Signal.Handler.SIG_DFL; 1827030SN/A } else if (handler == SignalHandler.SIG_IGN) { 1837030SN/A return jdk.internal.misc.Signal.Handler.SIG_IGN; 1847030SN/A } else if (handler instanceof SunMiscHandler) { 1857030SN/A return ((SunMiscHandler)handler).iHandler; 1867030SN/A } else { 1877030SN/A return new InternalMiscHandler(signal, handler); 1887030SN/A } 1897030SN/A } 1907030SN/A 1917030SN/A private InternalMiscHandler(Signal signal, SignalHandler handler) { 1927030SN/A this.handler = handler; 1937030SN/A this.signal = signal; 1947030SN/A } 1957030SN/A 1967030SN/A @Override 1977030SN/A public void handle(jdk.internal.misc.Signal ignore) { 1987030SN/A handler.handle(signal); 1997030SN/A } 2007030SN/A } 2017030SN/A 2027030SN/A /* 2038001SN/A * Wrapper class to proxy a jdk.internal.misc.Signal.Handler to a SignalHandler. 2047030SN/A */ 2057030SN/A static final class SunMiscHandler implements SignalHandler { 2067030SN/A private final jdk.internal.misc.Signal iSignal; 2077030SN/A private final jdk.internal.misc.Signal.Handler iHandler; 2087030SN/A 2097030SN/A static SignalHandler of(jdk.internal.misc.Signal signal, jdk.internal.misc.Signal.Handler handler) { 2107030SN/A if (handler == jdk.internal.misc.Signal.Handler.SIG_DFL) { 2117030SN/A return SignalHandler.SIG_DFL; 2127030SN/A } else if (handler == jdk.internal.misc.Signal.Handler.SIG_IGN) { 2137030SN/A return SignalHandler.SIG_IGN; 2147030SN/A } else if (handler instanceof InternalMiscHandler) { 2157030SN/A return ((InternalMiscHandler) handler).handler; 2167030SN/A } else { 2177030SN/A return new SunMiscHandler(signal, handler); 2187030SN/A } 2197030SN/A } 2207030SN/A 2217030SN/A SunMiscHandler(jdk.internal.misc.Signal iSignal, jdk.internal.misc.Signal.Handler iHandler) { 2227030SN/A this.iSignal = iSignal; 2237030SN/A this.iHandler = iHandler; 2247030SN/A } 2257030SN/A 2267030SN/A @Override 2277030SN/A public void handle(Signal sig) { 2287030SN/A iHandler.handle(iSignal); 2298001SN/A } 2307030SN/A 2317030SN/A public String toString() { 2327030SN/A return iHandler.toString(); 2337819SN/A } 2347819SN/A } 2357030SN/A} 2367030SN/A