home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IPCX.ZIP / SIG.C < prev    next >
C/C++ Source or Header  |  1989-09-20  |  6KB  |  210 lines

  1. /* sig.c RHS 5/1/89
  2.  *
  3.  * signal handler example
  4.  *
  5.     This program lets you observe how one process can use the OS2 signalling
  6.      mechanism to pass signals between two processes. To use it, first run the
  7.     program in one session with:
  8.  
  9.     SIG
  10.  
  11.     Note the process ID it prints. This will be the receiver of the signals.
  12.     Then you can run subsequent instances of SIG in other sessions by passing
  13.     them the process ID of the first instance as a command line argument:
  14.  
  15.     SIG n
  16.  
  17.     where 'n' is the process ID printed by the first instance.
  18.  
  19.  */
  20.  
  21. #define INCL_DOS
  22. #define INCL_VIO
  23. #define INCL_KBD
  24. #define INCL_ERRORS
  25.  
  26. #include<os2.h>
  27. #include<mt\stdio.h>
  28. #include<mt\memory.h>
  29. #include<mt\string.h>
  30. #include<mt\stdlib.h>
  31. #include<mt\process.h>
  32.  
  33. #define    SEMNAME    "\\sem\\ssem.sem"
  34.  
  35. #define    THREADSTACK    400
  36. char keyboard_thread_stack[THREADSTACK];
  37.  
  38. unsigned pid = 0;
  39. unsigned signaler = FALSE;
  40. USHORT prevaction0, prevaction1, prevaction2, prevaction3, prevaction4,
  41.     prevaction5;
  42. PFNSIGHANDLER prevhandler0, prevhandler1, prevhandler2, prevhandler3,
  43.     prevhandler4, prevhandler5;
  44.  
  45. #define MAXSIGS        3
  46.  
  47. char *signames[MAXSIGS] =    {    "Flag A", "Flag B",    "Flag C"    };
  48.  
  49. USHORT signum[MAXSIGS] =    {    PFLG_A, PFLG_B, PFLG_C };
  50.  
  51. void main(int argc, char **argv);
  52. PID OS2GetPid(void);
  53. void APIENTRY sighandler(USHORT arg, USHORT num);
  54. void error_exit(USHORT err, char *msg);
  55. void keyboard_thread(void);
  56.  
  57.  
  58. void APIENTRY sighandler(USHORT arg, USHORT num)
  59.     {
  60.     USHORT retval;
  61.     PFNSIGHANDLER prevhandler = NULL;
  62.     USHORT prevaction = 0;
  63.  
  64.         /* acknowledge immediately        */
  65.     retval = DosSetSigHandler((PFNSIGHANDLER)sighandler,&prevhandler,
  66.             &prevaction,SIGA_ACKNOWLEDGE,num);
  67.     
  68.     switch(num)
  69.         {
  70.         case SIG_CTRLC:
  71.             printf("%u received ^C...",pid);
  72.             break;
  73.         case SIG_KILLPROCESS:
  74.             printf("%u notified of pending termination, terminating...",pid);
  75.             DosExit(EXIT_PROCESS,0);
  76.             break;
  77.         case SIG_CTRLBREAK:
  78.             printf("%u received ^Break...",pid);
  79.             break;
  80.         case SIG_PFLG_A:                        /* FLAG_A received            */
  81.             printf("%u received signal, Flag A, arg=%u...",pid,arg);
  82.             break;
  83.         case SIG_PFLG_B:
  84.             printf("%u received signal, Flag B, arg=%u...",pid,arg);
  85.             break;
  86.         case SIG_PFLG_C:
  87.             printf("%u received signal, Flag C, arg=%u...",pid,arg);
  88.             break;
  89.         default:
  90.             printf("%u received unknown signal (%u), arg=%u", pid, num, arg);
  91.             break;
  92.         }
  93.  
  94.     if(retval)
  95.         printf("unable to acknowledge signal, retval=%u.\n",retval);
  96.     else
  97.         printf("acknowledged.\n");
  98.     return;
  99.     }
  100.  
  101. void main(int argc, char **argv)
  102.     {
  103.     unsigned retval,receiver_pid, signal = 0;
  104.     HSYSSEM semhandle;
  105.     KBDKEYINFO kbdkeyinfo;
  106.  
  107.     pid = OS2GetPid();
  108.     printf("%s loaded, pid=%u\n",argv[0],pid);
  109.  
  110.     if(retval = DosCreateSem(CSEM_PUBLIC,&semhandle,SEMNAME))
  111.         {
  112.         if(retval != ERROR_ALREADY_EXISTS)
  113.             error_exit(retval,"DosCreateSem");
  114.  
  115.         signaler = TRUE;                                        /* set flag                 */
  116.         if(argc != 2)
  117.             error_exit(0,"main");
  118.         receiver_pid = atoi(argv[1]);
  119.         }
  120.     else
  121.         {
  122.         if(_beginthread(keyboard_thread,keyboard_thread_stack,THREADSTACK,NULL)
  123.                 == -1)
  124.             error_exit(-1,"_beginthread");
  125.  
  126.             /* set up signal handler to be sighandler function, pass address
  127.                 of prevhandler and prevaction even though there weren't any
  128.                 previous.
  129.              */
  130.         if(retval = DosSetSigHandler(sighandler,&prevhandler0,&prevaction0,
  131.                 SIGA_ACCEPT,SIG_CTRLC))
  132.             error_exit(retval,"DosSetSigHandler(0)");
  133.         if(retval = DosSetSigHandler(sighandler,&prevhandler1,&prevaction1,
  134.                 SIGA_ACCEPT,SIG_KILLPROCESS))
  135.             error_exit(retval,"DosSetSigHandler(1)");
  136.         if(retval = DosSetSigHandler(sighandler,&prevhandler2,&prevaction2,
  137.                 SIGA_ACCEPT,SIG_CTRLBREAK))
  138.             error_exit(retval,"DosSetSigHandler(2)");
  139.         if(retval = DosSetSigHandler(sighandler,&prevhandler3,&prevaction3,
  140.                 SIGA_ACCEPT,SIG_PFLG_A))
  141.             error_exit(retval,"DosSetSigHandler(3)");
  142.         if(retval = DosSetSigHandler(sighandler,&prevhandler4,&prevaction4,
  143.                 SIGA_ACCEPT,SIG_PFLG_B))
  144.             error_exit(retval,"DosSetSigHandler(4)");
  145.         if(retval = DosSetSigHandler(sighandler,&prevhandler5,&prevaction5,
  146.                 SIGA_ACCEPT,SIG_PFLG_C))
  147.             error_exit(retval,"DosSetSigHandler(5)");
  148.         }
  149.  
  150.     while(TRUE)
  151.         {
  152.         if(signaler)                                        /* if another copy out there*/
  153.             {
  154.                 /* signal it (and not its children) with FLAG_A */
  155.             if(retval = DosFlagProcess(receiver_pid,FLGP_PID,signum[signal],
  156.                     pid))
  157.                 error_exit(retval,"DosFlagProcess");
  158.             else
  159.                 printf("Sender (%u): sent signal to %u: %s\n",pid,
  160.                     receiver_pid, signames[signal]);
  161.             if(++signal >= MAXSIGS)
  162.                 signal = 0;
  163.                                                                 /* check for key press        */
  164.             retval = KbdCharIn(&kbdkeyinfo,IO_NOWAIT,0);
  165.             if(!retval || (retval != ERROR_SIGNAL_PENDING))
  166.                                                                 /* if pressed, break out    */
  167.                 if(kbdkeyinfo.fbStatus & FINAL_CHAR_IN)
  168.                     break;
  169.             DosSleep(100L);                                /* sleep again                    */
  170.             }
  171.         else
  172.             DosSleep(10000L);                                /* don't wake too often        */
  173.         }
  174.     }
  175.  
  176.  
  177. PID OS2GetPid(void)
  178.     {
  179.     PLINFOSEG ldt;
  180.     SEL gdt_descriptor, ldt_descriptor;   /* infoseg descriptors */
  181.  
  182.     if(DosGetInfoSeg(&gdt_descriptor, &ldt_descriptor))
  183.         return 0;
  184.  
  185.     ldt = MAKEPLINFOSEG(ldt_descriptor);
  186.     return ldt->pidCurrent;
  187.     }
  188.  
  189.  
  190. void error_exit(USHORT err, char *msg)
  191.     {
  192.     printf("Error %u returned from %s\n",err,msg);
  193.     DosExit(EXIT_PROCESS,0);
  194.     }
  195.  
  196. void keyboard_thread(void)
  197.     {
  198.     KBDKEYINFO kbdkeyinfo;
  199.  
  200.     while(TRUE)
  201.         {
  202.         if(!KbdCharIn(&kbdkeyinfo,IO_WAIT,0))
  203.             DosExit(EXIT_PROCESS,0);
  204.         }
  205.     }
  206.  
  207.  
  208.  
  209.  
  210.