dhesi@bsu-cs.UUCP (Rahul Dhesi) (08/27/88)
The signal() function, if trapping SIGINT only, can be easily
implemented using Turbo C 1.0. Here is source code and a manual.
[ No binary in this small package, so as an experiment I'm posting
this as a shar archive. -- R.D ]
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# signal.c
# signal.man
# This archive created: Wed Aug 24 03:44:04 1988
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'signal.c'" '(2380 characters)'
if test -f 'signal.c'
then
echo shar: "will not over-write existing file 'signal.c'"
else
sed 's/^X//' << \SHAR_EOF > 'signal.c'
X/*
Xsignal.c - a signal package for Turbo C 1.0.
X
XThis program and accompanying documentation, henceforth collectively known as
X"this software", are copyrighted thus: (C) Copyright 1987 Rahul Dhesi, all
Xrights reserved. This software may be used and distributed in any way
Xwhatsoever, whether commercial or noncommercial, with the following
Xexceptions: (a) this paragraph and this copyright notice must be included
Xunchanged; (b) it is forbidden to copy this software for distribution as
Xpart of any collection over which a compilation copyright is claimed.
XNotwithstanding the above, there are no restrictions of any kind on the
Xmachine-readable object code produced by compiling this program with a C
Xcompiler.
X
X -- Rahul Dhesi 1987/08/08
X*/
X
X/*
XNote: When assigning an address to the variable `handler', a race
Xcondition can theoretically occur if a user interrupt occurs during
Xthe assignment. However, current versions of MS-DOS cause a user
Xinterrupt to take effect only during system calls, so in practice it
Xwon't happen.
X*/
X
X/* The following include files are already supplied with Turbo C */
X#include <signal.h>
X#include <errno.h>
X
X/*
XNOTE: For best results, edit your <signal.h> file, provided with
XTurbo C, to include the following declaration at the end:
X int (*_Cdecl signal (int sig, int (*action)())) ();
X*/
X
Xvoid ctrlbrk (int (*fptr)(void));
X
Xstatic int (*handler)() = SIG_DFL;
Xint main_handler();
X
Xint (*_Cdecl signal (int sig, int (*action) ())) ()
X{
X int (*retval) ();
X static int installed = 0;
X if (sig != SIGINT) {
X errno = EINVAL;
X return SIG_ERR; /* error return */
X }
X if (!installed) {
X ctrlbrk (main_handler); /* ctrlbrk() is in Turbo C library */
X installed = 1;
X }
X
X retval = handler;
X handler = action;
X return (retval);
X}
X
X#define ABORT_PGM 0
X#define RESUME_PGM 1
X
X/* Every keyboard interrupt is handled here first */
Xint main_handler()
X{
X int (*old_handler)(void);
X
X if (handler == SIG_IGN)
X return (RESUME_PGM);
X if (handler == SIG_DFL)
X return (ABORT_PGM);
X old_handler = handler; /* Save user's handler address */
X handler = SIG_DFL; /* Reset handler, like System V does */
X (*old_handler)(); /* call the user's handler */
X return (RESUME_PGM);
X}
SHAR_EOF
fi
echo shar: "extracting 'signal.man'" '(2962 characters)'
if test -f 'signal.man'
then
echo shar: "will not over-write existing file 'signal.man'"
else
sed 's/^X//' << \SHAR_EOF > 'signal.man'
X--------------------------------------------------------------------
Xsignal
X--------------------------------------------------------------------
X
XNAME
X
X signal -- implements trapping of user interrupts
X
XUSAGE
X
X int (*signal (int sig, int (*action))) ()
X
XPROTOTYPE IN
X
X signal.h /* but you must add it yourself */
X
XDESCRIPTION
X
XThe function `signal' is used to establish an action routine for servicing a
Xuser interrupt. Under MS-DOS, typing Ctrl-C causes a user interrupt. (On
XIBM-compatible systems the Ctrl-Break key will cause the same user
Xinterrupt, and may work when a Ctrl-C fails.)
X
XThe first argument to `signal', sig, is a number identifying the signal for
Xwhich an action is established. The value for sig must be SIGINT.
X
XThe second parameter, `action', specifies the action to be taken when SIGINT
Xoccurs. It is either the name of a user-defined function or one of the
Xconstants SIG_DFL (default, which aborts the process) or SIG_IGN (ignore,
Xwhich causes SIGINT to be ignored; however, in the case of MS-DOS, a '^C'
Xis always echoed to the controlling device).
X
XThere are no special restrictions on what the action function may do,
Xincluding continuing execution, returning normally or with a longjmp
Xstatement, or terminating executing with exit(). If the function returns
Xnormally, execution continues where it was interrupted by the occurrence of
Xthe SIGINT signal, except that any MS-DOS system call that was in progress
Xmay need to be restarted.
X
XBefore the user-defined function is called, the action on the event is
Xrestored to be SIG_DFL. Thus a second SIGINT event will cause termination
Xof the process unless the signal handler takes care to restore its action
Xwith a call to `signal'. Even if it does so, however, a race condition
Xstill exists and two SIGINTs occurring rapidly will terminate the process.
X(But nobody types that fast.)
X
XRETURN VALUE
X
XIf the specified signal is not SIGINT, the return value is SIG_ERR, which is
Xdefined in `signal.h', and errno is set to EINVAL. Otherwise the return
Xvalue is the value of `action' that was supplied to `signal' in the most
Xrecent legal call, or SIG_DFL if `signal' has never been called.
X
XNOTE
X
XA header file `signal.h' is already provided with Turbo C. Revise it by
Xadding the following line at the end:
X
X int (*_Cdecl signal (int sig, int (*action)())) (); /* R.D */
X
XAUTHOR
X
X Rahul Dhesi
X
XEXAMPLE
X
X#include <stdio.h>
X#include <signal.h>
X
Xint my_handler()
X{
X signal (SIGINT, SIG_IGN); /* ignore signals for now */
X fflush (stdout);
X printf ("\n<Break>\n");
X fflush (stdout);
X signal (SIGINT, my_handler); /* reinstall signal handler */
X}
X
Xunsigned _stklen = 4000; /* reserve stack */
X
Xmain()
X{
X int c;
X signal (SIGINT, my_handler);
X printf ("Control C is being trapped\n");
X printf ("Type Q then <return> to exit\n");
X for (;;) {
X c = getchar();
X if (c == 'q' || c == 'Q' || c == EOF)
X break;
X }
X}
SHAR_EOF
fi
exit 0
# End of shell archive