📄 dhcp-interrupt.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-interrupt.c,v 1.5 2003/05/25 03:37:36 actmodern Exp $ * * Copyright 2002 Thamer Alharbash * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Utility routines. * */#define MODULE_NAME "dhcp-interrupt"#include "dhcp-local.h"#include "dhcp-libutil.h"/* wrap for volatile integers, or proper sig_atomic_t types. */#ifdef HAVE_SIG_ATOMIC_Tstatic sig_atomic_t have_shutdown = 0;static sig_atomic_t have_hup = 0;static sig_atomic_t have_alarm = 0;#elsestatic volatile int have_shutdown = 0;static volatile int have_hup = 0;static volatile int have_alarm = 0;#endif/* All handlers do is setup atomic variables. *//* term handler. */RETSIGTYPE handle_shutdown(int i){ have_shutdown = 1; return (RETSIGTYPE) 0;}/* hup handler. */RETSIGTYPE handle_hup(int i){ have_hup = 1; return (RETSIGTYPE) 0;}/* alarm handler. */static RETSIGTYPE handle_alarm(int i){ have_alarm = 1; return (RETSIGTYPE) 0;}int peek_interrupt_type(void){ if(have_alarm) return INTERRUPT_ALARM; if(have_hup) return INTERRUPT_HUP; if(have_shutdown) return INTERRUPT_TERM; return INTERRUPT_NONE;} /* check which variables ere setup and return. * clear before returning. */int got_interrupt_type(void){ if(have_shutdown) { have_shutdown = 0; return INTERRUPT_TERM; } if(have_hup) { have_hup = 0; return INTERRUPT_HUP; } if(have_alarm) { have_alarm = 0; return INTERRUPT_ALARM; } return INTERRUPT_NONE;}/* will trigger alarm for one time only. */void set_alarm(uint32_t alarm_time){ add_interrupt_handler(SIGALRM, handle_alarm); alarm(alarm_time); return;}/* remove alarm. */void remove_alarm(void){ have_alarm = 0; alarm(0); /* reset alarm to fire off immediately. */ while(!alarm); /* should happen _very_ soon. */ have_alarm = 0; /* now remove: this also makes sure we don't have a pending * SIGARLM. */ remove_interrupt(SIGALRM); return;}/* add signal handler. */void add_interrupt_handler(int sigtype, void (*sighandler) (int)){ struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = sighandler; sigfillset(&sa.sa_mask); if(sigaction(sigtype, &sa, NULL)) FATAL_MESSAGE("could not set signal handler for: %d", sigtype); return;}/* block all signals. */void block_interrupts(void){ sigset_t signal_mask; sigfillset(&signal_mask); sigprocmask(SIG_SETMASK, &signal_mask, NULL); return;}/* unblock signals temporarily so we can receive pending signals. */int check_for_interrupts(void){ /* Easiest way to do this is unblock all signals, * then block them again. */ sigset_t signal_mask, o_mask; sigemptyset(&signal_mask); sigprocmask(SIG_SETMASK, &signal_mask, &o_mask); /* here we get all the signals. */ sigprocmask(SIG_SETMASK, &o_mask, NULL); if(have_shutdown || have_alarm || have_hup) return 1; else return 0;}/* suspend indefinetly for a signal (useful for alarm). */void suspend_for_interrupts(void){ sigset_t signal_mask; sigemptyset(&signal_mask); sigsuspend(&signal_mask);}/* remove an interrupt. */void remove_interrupt(int sig){ sigset_t signal_set; sigemptyset(&signal_set); sigaddset(&signal_set, sig); if(sigpending(&signal_set)) { add_interrupt_handler(sig, SIG_IGN); sigfillset(&signal_set); sigdelset(&signal_set, sig); sigsuspend(&signal_set); add_interrupt_handler(sig, SIG_DFL); } return;}int user_interrupt(void){ sigset_t signal_mask; sigemptyset(&signal_mask); sigpending(&signal_mask); if(sigismember(&signal_mask, SIGQUIT) || sigismember(&signal_mask, SIGINT) || sigismember(&signal_mask, SIGTERM)) return 1; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -