/* * Cross Development System for Atari ST * Copyright (c) 1988, Memorial University of Newfoundland * * Signal routine - the signals are actually done by calling the _do_signal * routine - similiar to kill() I guess. * * 1.3 ERS added SIGABRT handling, generally fixed up stuff * 1.2 ERS added kill, changed _do_signal to an internal function * */ #include #include #include #include extern int __check_signals; /* used in console i/o routines */ #define SIG_EXIT 10 /* exit code */ struct sigarray_str { __Sigfunc s_func; }; /* SIG_DFL == 0, so everything is implicitly set to this */ static struct sigarray_str sig_array[NSIG] ; void _init_signal() /* needed for dumping */ { bzero(sig_array, sizeof(sig_array)); /* for now */ } __Sigfunc signal(sig, func) int sig; __Sigfunc func; { __Sigfunc oldfunc; switch (sig) { case SIGINT: case SIGQUIT: if (func != SIG_IGN) __check_signals |= (sig==SIGINT ? 1 : 2); else __check_signals &= (sig==SIGINT ? ~1 : ~2); /* falltrough */ case SIGALRM: case SIGABRT: oldfunc = sig_array[sig].s_func; sig_array[sig].s_func = func; break; default: errno = EINVAL; oldfunc = SIG_ERR; } return oldfunc; } static void _do_signal(sig) int sig; { __Sigfunc func; if (sig >= 0 && sig < NSIG) { func = sig_array[sig].s_func; if (func == SIG_DFL) switch (sig) { case SIGQUIT: case SIGINT: case SIGALRM: case SIGABRT: psignal(sig, "fatal signal received"); _exit(SIG_EXIT + sig); } else if (func != SIG_IGN) (*func)(sig); /* else ignore it */ } } int kill(pid, sig) int pid, sig; { if (pid != getpid()) { errno = EACCESS; /* I don't know if this is right */ return -1; } _do_signal(sig); return 0; }