[comp.os.os2] And alarm

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