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