/****************************************************************************** * This file is part of a software distribution, which is furnished under the * * terms of a license. Use of this software by any means is subject to this * * license and signifies the acceptance of the licensing terms stated * * therein. Please see the file LICENSE in the top-level directory of this * * software distribution for detailed copyright disclaimers and licensing * * terms. * ****************************************************************************** * Copryight (c) by Andreas S. Wetzel - All rights reserved. * ******************************************************************************/ /* $Id: sigctl.c,v 1.2 2001/03/19 14:54:02 mickey Exp $ */ #include #include #include #include #if HAVE_STROPTS_H && HAVE_SYS_CONF_H #include #include #endif /*** Globals ***/ u_char is_handler = 0; /* 0 = user mode ; 1 = sighandler */ /*** Externals ***/ extern VCONN sconn; extern void resize(void); /*** Code ***/ void v_io_init(void) { #if HAVE_SIGACTION struct sigaction sa; sa.sa_handler = (void *)rcv_sv_msg; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGWINCH); #if defined(SA_RESTART) sa.sa_flags = SA_RESTART; #else sa.sa_flags = 0; #endif sigaction(SIGIO, &sa, NULL); #else /*** SIGVEC ***/ struct sigvec sv; sv.sv_handler = (void *)rcv_sv_msg; sv.sv_mask = sigmask(SIGALRM); sv.sv_mask |= sigmask(SIGWINCH); sv.sv_flags = 0; sigvec(SIGIO, &sv, NULL); #endif async_io(1); } void v_timer_init(void) { struct itimerval it; #if HAVE_SIGACTION struct sigaction sa; sa.sa_handler = (void *)heartbeat; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGWINCH); #if defined(SA_RESTART) sa.sa_flags = SA_RESTART; #else sa.sa_flags = 0; #endif sigaction(SIGALRM, &sa, NULL); #else /*** SIGVEC ***/ struct sigvec sv; sv.sv_handler = (void *)heartbeat; sv.sv_mask = sigmask(SIGIO); sv.sv_mask |= sigmask(SIGWINCH); sv.sv_flags = 0; sigvec(SIGALRM, &sv, NULL); #endif it.it_interval.tv_sec = it.it_value.tv_sec = 1; it.it_interval.tv_usec = it.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &it, NULL); } void v_winch_init(void) { #if HAVE_SIGACTION struct sigaction sa; sa.sa_handler = (void *)resize; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGALRM); #if defined(SA_RESTART) sa.sa_flags = SA_RESTART; #else sa.sa_flags = 0; #endif sigaction(SIGWINCH, &sa, NULL); #else /*** SIGVEC ***/ struct sigvec sv; sv.sv_handler = (void *)resize; sv.sv_mask = sigmask(SIGIO); sv.sv_mask |= sigmask(SIGALRM); sv.sv_flags = 0; sigvec(SIGWINCH, &sv, NULL); #endif } void v_io_end(void) { #if HAVE_SIGACTION struct sigaction sa; async_io(0); sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGIO, &sa, NULL); #else struct sigvec sv; async_io(0); sv.sv_handler = SIG_IGN; sigemptyset(&sv.sv_mask); sv.sv_flags = 0; sigvec(SIGIO, &sv, NULL); #endif } void v_timer_end(void) { struct itimerval it = {{0,0},{0,0}}; #if HAVE_SIGACTION struct sigaction sa; setitimer(ITIMER_REAL, &it, NULL); sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGALRM, &sa, NULL); #else struct sigvec sv; setitimer(ITIMER_REAL, &it, NULL); sv.sv_handler = SIG_IGN; sigemptyset(&sv.sv_mask); sv.sv_flags = 0; sigvec(SIGALRM, &sv, NULL); #endif } void v_winch_end(void) { #if HAVE_SIGACTION struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGWINCH, &sa, NULL); #else struct sigvec sv; sv.sv_handler = SIG_IGN; sigemptyset(&sv.sv_mask); sv.sv_flags = 0; sigvec(SIGWINCH, &sv, NULL); #endif } void vlock(u_char mode, u_char items) { sigset_t smask; static u_char locks_vio = 0; static u_char locks_vtimer = 0; static u_char locks_vwinch = 0; u_char has_changed = 0; /* * We do nothing if we are called * from within a signal handler. */ if(is_handler) return; if(mode == LOCK) { /* * Lock the given set of signals * Signals are locked only if the number * of locks for this signal equals zero * and the signal is not already locked * by another instance. */ sigemptyset(&smask); if(items & V_IO) { if(locks_vio == 0) { sigaddset(&smask, SIGIO); has_changed = 1; } ++locks_vio; } if(items & V_TIMER) { if(locks_vtimer == 0) { sigaddset(&smask, SIGALRM); has_changed = 1; } ++locks_vtimer; } if(items & V_WINCH) { if(locks_vwinch == 0) { sigaddset(&smask, SIGWINCH); has_changed = 1; } ++locks_vwinch; } if(has_changed) { #if HAVE_SIGPROCMASK sigprocmask(SIG_BLOCK, &smask, NULL); #else sigblock(smask); #endif } } else if(mode == UNLOCK) { /* * Unlock the given set of signals * Signals are unlocked only if the last * lock for the signal is removed and if * no other instance had locked the signal * before the first lock was made. */ sigemptyset(&smask); if(items & V_IO) { switch(locks_vio) { case 0: break; case 1: sigaddset(&smask, SIGIO); has_changed = locks_vio--; break; default: --locks_vio; break; } } if(items & V_TIMER) { switch(locks_vtimer) { case 0: break; case 1: sigaddset(&smask, SIGALRM); has_changed = locks_vtimer--; break; default: --locks_vtimer; break; } } if(items & V_WINCH) { switch(locks_vwinch) { case 0: break; case 1: sigaddset(&smask, SIGWINCH); has_changed = locks_vwinch--; break; default: --locks_vwinch; break; } } if(has_changed) { #if HAVE_SIGPROCMASK sigprocmask(SIG_UNBLOCK, &smask, NULL); #else sigset_t tmp; tmp = sigblock(0); tmp &= ~smask; sigsetmask(tmp); #endif } } } void async_io(int x) { if(x) { fcntl(sconn.fd, F_SETOWN, getpid()); #if HAVE_STROPTS_H && HAVE_SYS_CONF_H ioctl(sconn.fd, I_SETSIG, S_RDNORM); #elif defined(O_ASYNC) fcntl(sconn.fd, F_SETFL, O_ASYNC); #elif defined(FASYNC) fcntl(sconn.fd, F_SETFL, FASYNC); #else #error *** YOU BLEW IT! *** cannot determine how to set descriptors to async i/o #endif } else { #if HAVE_STROPTS_H && HAVE_SYS_CONF_H ioctl(sconn.fd, I_SETSIG, 0); #else fcntl(sconn.fd, F_SETFL, 0); #endif } }