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