[comp.binaries.ibm.pc] signal

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