sig.c

Go to the documentation of this file.
00001 /*
00002  * $Id: sig.c,v 1.6 2003/12/01 09:10:16 troth Exp $
00003  *
00004  ****************************************************************************
00005  *
00006  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
00007  * Copyright (C) 2001, 2002, 2003  Theodore A. Roth
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  ****************************************************************************
00024  */
00025 
00026 /** 
00027  * \file sig.c
00028  * \brief Public interface to signal handlers.
00029  *
00030  * This module provides a way for the simulator to process signals generated
00031  * by the native host system. Note that these signals in this context have
00032  * nothing to do with signals or interrupts as far as a program running in the
00033  * simulator is concerned. */
00034 
00035 #include <config.h>
00036 
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <errno.h>
00041 #include <signal.h>
00042 
00043 #include "avrerror.h"
00044 #include "sig.h"
00045 
00046 static volatile int global_got_sigint = 0;
00047 
00048 /*
00049  * Private.
00050  *
00051  * Handler for SIGINT signals. 
00052  */
00053 static void
00054 signal_handle_sigint (int signo)
00055 {
00056     global_got_sigint = 1;
00057 }
00058 
00059 /**
00060  * \brief Start watching for the occurrance of the given signal.
00061  *
00062  * This function will install a signal handler which will set a flag when the
00063  * signal occurs. Once the watch has been started, periodically call
00064  * signal_has_occurred() to check if the signal was raised. 
00065  */
00066 void
00067 signal_watch_start (int signo)
00068 {
00069     struct sigaction act, oact;
00070 
00071     sigemptyset (&act.sa_mask);
00072     act.sa_flags = 0;
00073 
00074     switch (signo)
00075     {
00076         case SIGINT:
00077             global_got_sigint = 0;
00078             act.sa_handler = signal_handle_sigint;
00079             break;
00080         default:
00081             avr_warning ("Invalid signal: %d\n", signo);
00082             return;
00083     }
00084 
00085     if (sigaction (signo, &act, &oact) < 0)
00086         avr_warning ("Failed to install signal handler: sig=%d: %s\n", signo,
00087                      strerror (errno));
00088 }
00089 
00090 /**
00091  * \brief Stop watching signal.
00092  *
00093  * Restores the default signal handler for the given signal and resets the
00094  * signal flag. 
00095  */
00096 void
00097 signal_watch_stop (int signo)
00098 {
00099     struct sigaction act, oact;
00100 
00101     sigemptyset (&act.sa_mask);
00102     act.sa_flags = 0;
00103     act.sa_handler = SIG_DFL;
00104 
00105     signal_reset (signo);
00106 
00107     if (sigaction (signo, &act, &oact) < 0)
00108         avr_warning ("Failed to restore default signal handler: sig=%d: %s\n",
00109                      signo, strerror (errno));
00110 }
00111 
00112 /**
00113  * \brief Check to see if a signal has occurred.
00114  *
00115  * \return Non-zero if signal has occurred. The flag will always be reset
00116  * automatically. 
00117  */
00118 int
00119 signal_has_occurred (int signo)
00120 {
00121     int res = 0;
00122 
00123     switch (signo)
00124     {
00125         case SIGINT:
00126             res = global_got_sigint;
00127             global_got_sigint = 0;
00128             break;
00129         default:
00130             avr_warning ("Invalid signal: %d", signo);
00131     }
00132 
00133     return res;
00134 }
00135 
00136 /**
00137  * \brief Clear the flag which indicates that a signal has ocurred.
00138  *
00139  * Use signal_reset to manually reset (i.e. clear) the flag.
00140  */
00141 void
00142 signal_reset (int signo)
00143 {
00144     signal_has_occurred (signo);
00145 }

Automatically generated by Doxygen 1.5.2 on 13 Feb 2008.