sighandlers.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1993-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 /*
00024 
00025 The signal blocking macros defined below were adapted from similar
00026 functions from GNU Bash, the Bourne Again SHell, copyright (C) 1994
00027 Free Software Foundation, Inc.
00028 
00029 */
00030 
00031 // This file should always be included after config.h!
00032 
00033 #if !defined (octave_sighandlers_h)
00034 #define octave_sighandlers_h 1
00035 
00036 // Include signal.h, not csignal since the latter might only define
00037 // the ANSI standard C signal interface.
00038 
00039 #include <signal.h>
00040 
00041 #include "syswait.h"
00042 #include "siglist.h"
00043 
00044 #include "base-list.h"
00045 
00046 typedef void sig_handler (int);
00047 
00048 // FIXME -- the data should probably be private...
00049 
00050 struct
00051 octave_interrupt_handler
00052 {
00053 #ifdef SIGINT
00054   sig_handler *int_handler;
00055 #endif
00056 
00057 #ifdef SIGBREAK
00058   sig_handler *brk_handler;
00059 #endif
00060 };
00061 
00062 // Nonzero means we have already printed a message for this series of
00063 // SIGPIPES.  We assume that the writer will eventually give up.
00064 extern int pipe_handler_error_count;
00065 
00066 // TRUE means we can be interrupted.
00067 extern OCTINTERP_API bool can_interrupt;
00068 
00069 extern OCTINTERP_API sig_handler *octave_set_signal_handler (int, sig_handler *,
00070                                                bool restart_syscalls = true);
00071 
00072 extern OCTINTERP_API void install_signal_handlers (void);
00073 
00074 extern OCTINTERP_API void octave_signal_handler (void);
00075 
00076 extern OCTINTERP_API octave_interrupt_handler octave_catch_interrupts (void);
00077 
00078 extern OCTINTERP_API octave_interrupt_handler octave_ignore_interrupts (void);
00079 
00080 extern OCTINTERP_API octave_interrupt_handler
00081 octave_set_interrupt_handler (const volatile octave_interrupt_handler&,
00082                               bool restart_syscalls = true);
00083 
00084 // extern void ignore_sigchld (void);
00085 
00086 // Maybe this should be in a separate file?
00087 
00088 class
00089 OCTINTERP_API
00090 octave_child
00091 {
00092 public:
00093 
00094   // Do whatever to handle event for child with PID (might not
00095   // actually be dead, could just be stopped).  Return true if
00096   // the list element corresponding to PID should be removed from
00097   // list.  This function should not call any functions that modify
00098   // the octave_child_list.
00099 
00100   typedef bool (*child_event_handler) (pid_t, int);
00101 
00102   octave_child (pid_t id = -1, child_event_handler f = 0)
00103     : pid (id), handler (f), have_status (0), status (0) { }
00104 
00105   octave_child (const octave_child& oc)
00106     : pid (oc.pid), handler (oc.handler),
00107       have_status (oc.have_status), status (oc.status) { }
00108 
00109   octave_child& operator = (const octave_child& oc)
00110     {
00111       if (&oc != this)
00112         {
00113           pid = oc.pid;
00114           handler = oc.handler;
00115           have_status = oc.have_status;
00116           status = oc.status;
00117         }
00118       return *this;
00119     }
00120 
00121   ~octave_child (void) { }
00122 
00123   // The process id of this child.
00124   pid_t pid;
00125 
00126   // The function we call if an event happens for this child.
00127   child_event_handler handler;
00128 
00129   // Nonzero if this child has stopped or terminated.
00130   sig_atomic_t have_status;
00131 
00132   // The status of this child; 0 if running, otherwise a status value
00133   // from waitpid.
00134   int status;
00135 };
00136 
00137 class
00138 OCTINTERP_API
00139 octave_child_list
00140 {
00141 protected:
00142 
00143   octave_child_list (void) { }
00144 
00145   class octave_child_list_rep : public octave_base_list<octave_child>
00146   {
00147   public:
00148 
00149     void insert (pid_t pid, octave_child::child_event_handler f);
00150 
00151     void reap (void);
00152 
00153     bool wait (void);
00154   };
00155 
00156 public:
00157 
00158   ~octave_child_list (void) { }
00159 
00160   static void insert (pid_t pid, octave_child::child_event_handler f);
00161 
00162   static void reap (void);
00163 
00164   static bool wait (void);
00165 
00166   static void remove (pid_t pid);
00167 
00168 private:
00169 
00170   static bool instance_ok (void);
00171 
00172   static octave_child_list_rep *instance;
00173 
00174   static void cleanup_instance (void) { delete instance; instance = 0; }
00175 };
00176 
00177 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines