package posix; /** A posix signal. A posix signal represents an external event of some sort. For instance, SIGINTR means that a user interrupt signal was raised by the tty driver - usually because the user pressed the INTR key (typically ^C).

Some posix signals represent internal software errors. For example SIGBUS means that a load or store was attempted with incorrect alignment. We do not handle these internal events for Java - only the JVM could do something sensible with them. Furthermore, some posix signals are probably used by the JVM itself. For example, SIGCHLD means that a process started via Runtime.exec() has terminated. For this reason, only selected signals are exported via static constants.

Each Signal is in one of three states. SIG_DFL means that the default action is taken when the signal is received. This usually means stopping the JVM process. Whether any cleanup takes place depends on the JVM. SIG_IGN means that the signal is ignored. SIG_EVT means that the signal is converted to a JDK1.1 style Java event.

WARNING

The Signal class will not crash. However, whether or not a given signal can actually be trapped is highly dependent on both OS and JVM implementation. When multiple threads listen to the same signal, posix does not specify which thread gets the signal. So do not rely on a signal being trapped on all platforms. This may be rectified in the future if JNI provides some kind of signal interface, or posix provides some way of reliably distributing signals to multiple threads. @author Stuart D. Gathman Copyright (C) 1998 Business Management Systems, Inc.

This code is distributed under the GNU Library General Public License

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library 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 Library General Public License for more details.

You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ public class Signal { private final int sig; private int action = SIG_DFL; private SignalListener listener = null; private static int MAXSIG = 64; private static Signal[] s = new Signal[MAXSIG]; public static final Signal SIGHUP = new Signal(0); public static final Signal SIGINT = new Signal(1); public static final Signal SIGQUIT = new Signal(2); public static final Signal SIGUSR1 = new Signal(3); public static final Signal SIGUSR2 = new Signal(4); /** Paging space is low, or power failure. */ public static final Signal SIGDANGER = new Signal(5); /** The process is being terminated. */ public static final Signal SIGTERM = new Signal(6); public static final int SIG_DFL = 0; // default action (usually stop) public static final int SIG_IGN = 1; // ignore public static final int SIG_EVT = 2; // trap signal public void setAction(int action) { if (action == SIG_EVT) start(); // start signal waiting Thread sigaction(sig,action); this.action = action; } public final int getAction() { return action; } public void addSignalListener(SignalListener l) { listener = SignalMulticaster.add(listener,l); } public void removeSignalListener(SignalListener l) { listener = SignalMulticaster.del(listener,l); } /** Send a SignalEvent to all listeners. */ public void processSignal() { SignalListener l = listener; if (l != null) { SignalEvent e = new SignalEvent(this); l.signalReceived(e); } } static void pollSignals() { int i = sigwait(); if (i < 0) throw new InternalError("signal mutex error"); if (s[i] != null) { try { s[i].processSignal(); } catch (Throwable t) { t.printStackTrace(); } } } private static Thread signalThread = null; private synchronized static void start() { if (signalThread == null) { signalThread = new Thread() { public void run() { for (;;) { pollSignals(); } } }; signalThread.setDaemon(true); signalThread.start(); } } private Signal(int sig) { this.sig = sig; s[sig] = this; } /** Wait for signals. Mark which signals occured in the byte[]. */ static native int sigwait(); /** Send signal to process using posix call. @return 0 on success or errno */ public static native int kill(int pid,int sig); /** Send this Signal to another process. @param the Posix process id */ public void kill(int pid) throws IPCException { int rc = kill(pid,sig); if (rc > 0) throw new IPCException("kill",rc); } private static native void sigaction(int sig,int action); { System.loadLibrary("posix"); } }