jack@cscdec.UUCP (Jack Hudler) (07/18/90)
Here is something I threw together one night while I was porting some code from unix to OS/2. There is no equivalent function in the C libraries for ALARM(1) so I wrote this to simulate it. It does a very good job of it, infact if your porting code you don't have to make any changes, just include alarm.h,compile and link it in. If you compile with 'cl -DTESTING alarm.c' it will compile the small test code in at the bottom, this allows you to test the code out. Enjoy. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: alarm.c alarm.h # Wrapped by jack@cscdec on Wed Jul 18 00:41:16 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f alarm.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"alarm.c\" else echo shar: Extracting \"alarm.c\" \(3865 characters\) sed "s/^X//" >alarm.c <<'END_OF_alarm.c' X/* X * This software is Copyright 1989 by Jack Hudler. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction or this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The author make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X * X */ X/****************************** Module Header ******************************\ X* Module Name: alarm.c X* Created : 11-08-89 X* Author : Jack Hudler [jack@csccat.lonestar.org] X* Copyright : 1988 Jack Hudler. X* Function : Unix like alarm signal simulator. X\***************************************************************************/ X/* Tested using OS2 1.2 with Microsoft C 5.1 and 6.0. */ X#define INCL_DOSPROCESS X#define INCL_DOSSIGNALS X#define INCL_DOS X#include <os2.h> X#include <stdio.h> X#include <signal.h> X X#include "alarm.h" X X#define ALARM_STACK 4096 /* This maybe over kill, but the page size is 4K */ Xstatic PBYTE pbAlarmStack; Xstatic SEL selAlarmStack; Xstatic TID tidAlarm; Xstatic PID pidMain; Xstatic BOOL bAlarmInit=FALSE; Xstatic BOOL bAlarmRunning=FALSE; Xstatic ULONG ulTime; XBOOL x; X XVOID FAR alarm_thread ( VOID ) X{ X while(1) X { X bAlarmInit = TRUE; X if (bAlarmRunning) X { X DosSleep(1000L); X ulTime--; X if (ulTime==0L) X { X // send signal to the main process.. I could have put raise() here X // however that would require the use of the multithreaded library, X // and it does not contain raise()! X // I tried it with the standard library, this signaled ok, but a X // test printf in the signal would not work and even caused SEGV. X // So I signal the process through OS/2 and then the process X // signals itself. X if (bAlarmRunning) X DosFlagProcess(pidMain,FLGP_PID, PFLG_A,1); X bAlarmRunning=FALSE; X } X } X else X DosSleep(100L); X } X} X XVOID PASCAL FAR AlarmSignal(USHORT usSigArg,USHORT usSigNum) X{ X /* X * this is not executed from the thread. The thread triggers Process X * flag A which is in the main processes scope, this inturn triggers X * (via the raise) SIGUSR1 which is defined to SIGALRM. X */ X raise(SIGUSR1); X} X Xvoid alarm_init() X{ X PFNSIGHANDLER pfnPrev; X USHORT pfAction; X PIDINFO pid; X if (!DosAllocSeg( ALARM_STACK, (PSEL) &selAlarmStack, SEG_NONSHARED )) X { X OFFSETOF(pbAlarmStack) = ALARM_STACK - 2; X SELECTOROF(pbAlarmStack) = selAlarmStack; X /* Create the thread */ X if (DosCreateThread( alarm_thread, &tidAlarm, pbAlarmStack )) X { X fprintf(stderr,"Alarm thread failed to start.\n"); X exit(1); X } X /* Setup the signal handler for Process Flag A */ X if (DosSetSigHandler(AlarmSignal,&pfnPrev,&pfAction,SIGA_ACCEPT,SIG_PFLG_A)) X { X fprintf(stderr,"SigHandler Failed to install.\n"); X exit(1); X } X /* Save main process ID, we'll need it for triggering the signal */ X DosGetPID(&pid); X pidMain = pid.pid; X } X else X exit(1); X} X X X XULONG alarm(ULONG sec) X{ X if (!bAlarmInit) alarm_init(); X if (sec) X { X ulTime = sec; X bAlarmRunning = TRUE; X } X else X bAlarmRunning = FALSE; X X} X X#ifdef TESTING X/* A simple test to see if it works */ X` Xtimeout() X{ X fprintf(stderr,"ALARM TRIGGERED!!\n"); X DosBeep(1000,500); X x++; X} X Xmain() X{ X (void) signal(SIGALRM, timeout); X (void) alarm(1L); X printf("ALARM RUNNING!!\n"); X while(!x); X} X#endif END_OF_alarm.c if test 3865 -ne `wc -c <alarm.c`; then echo shar: \"alarm.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f alarm.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"alarm.h\" else echo shar: Extracting \"alarm.h\" \(44 characters\) sed "s/^X//" >alarm.h <<'END_OF_alarm.h' X#define SIGALRM SIGUSR1 XULONG alarm(ULONG); END_OF_alarm.h if test 44 -ne `wc -c <alarm.h`; then echo shar: \"alarm.h\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of shell archive. exit 0 -- Jack Computer Support Corporation Dallas,Texas Hudler Internet: jack@cscdec.lonestar.org