home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / msj / msjv2_2 / finddemo / finddemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-28  |  7.4 KB  |  224 lines

  1. /*
  2. Microsoft Systems Journal
  3. Volume 2; Issue 2; May, 1987
  4.  
  5. Code Listings For:
  6.  
  7.     FINDDEMO
  8.     pp. 51-59
  9.  
  10. Author(s): Charles Petzold
  11. Title:     A Compleat Guide to Writing Your First OS/2 Program
  12.  
  13.  
  14.  
  15. ==============================================================================
  16. ==============================================================================
  17. Figure 2: FINDDEMO.C
  18.  
  19. ==============================================================================
  20. */
  21.  
  22. /* finddemo.c -- program to demonstrate IPC and multitasking */
  23.  
  24. #include <doscall.h>
  25.  
  26. #define WORD  unsigned int
  27. #define DWORD unsigned long
  28.  
  29. #define NUMPROC     9                   /* number of process */
  30. #define CHILDPROG   "FINDER.EXE"
  31. #define QUEUENAME   "\\QUEUES\\FINDDEMO"
  32. #define THREADSTACK 1024
  33.  
  34. void far dispthread (void) ;
  35. void far waitthread (void) ;
  36.  
  37. WORD   queuehandle, count [NUMPROC] ;
  38. DWORD  runsem [NUMPROC], waitsem [NUMPROC] ;
  39. struct ResultCodes rc [NUMPROC] ;
  40. struct {
  41.      WORD count ;
  42.      struct {
  43.           WORD  reserved ;
  44.           DWORD far *sem ;
  45.           } index [NUMPROC] ;
  46.      } semtab ;
  47.           
  48. main ()
  49.      {
  50.      static char prompt[] = "Line number or Esc to end -->  \b" ;
  51.      struct KeyData keydata ;
  52.      WORD   index, len, i, dispID, waitID, sigaction ;
  53.      DWORD  sigaddr ;
  54.      char   dirmask [15], dispstack [THREADSTACK],
  55.             waitstack [THREADSTACK] ;
  56.  
  57.      /* 
  58.          Initialize: Set up "semtab" structure for DOSMUXSEMWAIT.
  59.          ----------  Disable Ctrl-Break and Ctrl-C exits.
  60.                      Create queue for IPC with FINDER.EXE.
  61.                      Create threads for messages from FINDER
  62.                          and waiting for FINDER terminations.
  63.                      Display text. 
  64.      */
  65.  
  66.      semtab.count = NUMPROC ;
  67.      for (index = 0 ; index < NUMPROC ; index++) {
  68.           DOSSEMSET ((DWORD) &waitsem[index]) ;          
  69.           semtab.index[index].sem = &waitsem[index] ;
  70.           }
  71.      DOSSETSIGHANDLER (0L, &sigaddr, &sigaction, 1, 1) ;
  72.      DOSSETSIGHANDLER (0L, &sigaddr, &sigaction, 1, 4) ;
  73.  
  74.      if (DOSCREATEQUEUE (&queuehandle, 0, QUEUENAME)) {
  75.           puts ("FINDDEMO: Cannot create new queue") ;
  76.           DOSEXIT (1, 1) ;
  77.           }
  78.      if (DOSCREATETHREAD (dispthread, &dispID, dispstack 
  79.                           + THREADSTACK) ||
  80.          DOSCREATETHREAD (waitthread, &waitID, waitstack 
  81.                           + THREADSTACK)) {
  82.           puts ("FINDDEMO: Cannot create threads") ;
  83.           DOSEXIT (1, 1) ;
  84.           }
  85.      displayheadings () ;
  86.  
  87.                /*
  88.                     Main Loop: Display prompt and read keyboard.
  89.                     ---------  Execute FINDER.EXE.
  90.                */
  91.      do   {
  92.           VIOSETCURPOS (18, 0, 0) ;
  93.           VIOWRTTTY (prompt, sizeof prompt - 1, 0) ;
  94.           KBDCHARIN (&keydata, 0, 0) ;
  95.  
  96.           index = keydata.char_code - '1' ;
  97.  
  98.           if (index <= NUMPROC && rc[index].TermCode_PID == 0) {
  99.                VIOWRTTTY (&keydata.char_code, 1, 0) ;
  100.                VIOWRTNCHAR (" ", 77, 7 + index, 3, 0) ;
  101.                do   {
  102.                     VIOSETCURPOS (7 + index, 3, 0) ;
  103.                     len = 13 ;
  104.                     KBDSTRINGIN (dirmask, &len, 0, 0) ;
  105.                     }
  106.                while (len == 0) ;
  107.  
  108.                dirmask [len] = '\0' ;
  109.                executeprogram (index, dirmask) ;
  110.                }
  111.           }
  112.      while (keydata.char_code != 27) ;
  113.  
  114.                /*
  115.                     Clean-up: Kill all existing FINDER.EXE processes.
  116.                     --------  Wait for processes to terminate.
  117.                               Close the queue and exit.
  118.                */
  119.  
  120.      for (index = 0 ; index < NUMPROC ; index++)
  121.           if (rc[index].TermCode_PID)
  122.                DOSKILLPROCESS (0, rc[index].TermCode_PID) ;
  123.  
  124.      for (index = 0 ; index < NUMPROC ; index++)
  125.           DOSSEMWAIT ((DWORD) &runsem [index], -1L) ;
  126.  
  127.      DOSCLOSEQUEUE (queuehandle) ;
  128.      DOSEXIT (1, 0) ;
  129.      }
  130.  
  131. displayheadings ()
  132.      {
  133.      static char heading  [] = "286DOS File Finder Demo Program",
  134.                  colheads [] = "Dir Mask     Status  Files",
  135.                  colunder [] = "--------     ------  -----" ;
  136.      char        buffer  [5] ;
  137.      WORD        row, col, i, len ;
  138.  
  139.      VIOGETCURPOS (&row, &col, 0) ;              /* get current attr */
  140.      VIOWRTTTY (" ", 1, 0) ;
  141.      len = 2 ;
  142.      VIOREADCELLSTR (buffer, &len, row, col, 0) ;
  143.      VIOSCROLLUP (0, 0, -1, -1, -1, buffer, 0) ;     /* clear screen */
  144.  
  145.      len = sizeof heading - 1 ;
  146.      col = (80 - len) / 2 ;
  147.      VIOWRTCHARSTR (heading, len, 1, col, 0) ;            /* heading */
  148.      VIOWRTNCHAR   ("\xC6",   1, 2, col - 1,   0) ;     /* underline */
  149.      VIOWRTNCHAR   ("\xCD", len, 2, col,       0) ;
  150.      VIOWRTNCHAR   ("\xB5",   1, 2, col + len, 0) ;
  151.      VIOWRTCHARSTR (colheads, sizeof colheads - 1, 5, 3, 0) ; 
  152.      VIOWRTCHARSTR (colunder, sizeof colunder - 1, 6, 3, 0) ;
  153.  
  154.      for (i = 0 ; i < NUMPROC ; i++) {                    /* numbers */
  155.           sprintf (buffer, "%d.", i + 1) ;
  156.           VIOWRTCHARSTR (buffer, 2, 7 + i, 0, 0) ;
  157.           }
  158.      }
  159.  
  160. executeprogram (index, dirmask)
  161.      WORD index ;
  162.      char *dirmask ;
  163.      {
  164.      char objbuf [32] ;
  165.      char args [128] ;
  166.  
  167.      strcat (strcpy (args, CHILDPROG), " ") ;      /* construct args */
  168.      strcat (strcat (args, dirmask), " ") ;
  169.      strcat (strcat (args, QUEUENAME), " ") ;
  170.      itoa (index, args + strlen (args), 10) ;
  171.  
  172.      count [index] = 0 ;                         /* initialize count */
  173.  
  174.      if (DOSEXECPGM (objbuf, 32, 2, args, 0, &rc[index], CHILDPROG))
  175.           {
  176.           puts ("FINDDEMO: Can't run FINDER.EXE") ;
  177.           DOSEXIT (1, 1) ;
  178.           }
  179.      VIOWRTCHARSTR ("Running", 7, index + 7, 16, 0) ;/* now executing */
  180.      DOSSEMSET   ((DWORD) &runsem [index]) ;
  181.      DOSSEMCLEAR ((DWORD) &waitsem[index]) ;
  182.      }
  183.  
  184. void far dispthread ()        /* thread to read messages from FINDER */
  185.      {                        /*   and display filenames.            */
  186.      DWORD request ;
  187.      WORD  len, index, i ;
  188.      char  far *farptr ;
  189.      char  priority, pathname [80], buffer [64] ;
  190.  
  191.      while (1) {
  192.           DOSREADQUEUE (queuehandle, &request, &len, 
  193.                          &(DWORD)farptr, 0, 0, &priority, 0L) ;
  194.           i = 0 ;
  195.           while (pathname [i++] = *farptr++) ;
  196.           index = (WORD) (request >> 16) ;
  197.           count [index] += len > 0 ;
  198.           sprintf (buffer, "%5d   %-48.48s", count [index], pathname) ;
  199.           VIOWRTCHARSTR (buffer, 56, 7 + index, 24, 0) ;
  200.           DOSFREESEG ((WORD) ((DWORD) farptr >> 16)) ;
  201.           }
  202.      }
  203.  
  204. void far waitthread ()     /* thread to wait for FINDER terminations */
  205.      {
  206.      WORD   index, PID ;
  207.      struct ResultCodes rescode ;
  208.      
  209.      while (1) {
  210.           DOSMUXSEMWAIT (&index, (WORD far *) &semtab, -1L) ;
  211.           DOSCWAIT (0, 0, &rescode, &PID, 0) ;
  212.  
  213.           for (index = 0 ; index < NUMPROC ; index++)  /* find index */
  214.                if (PID == rc[index].TermCode_PID) 
  215.                     break ;
  216.  
  217.           VIOWRTCHARSTR (rescode.TermCode_PID ? "Halted " : "Done   ",
  218.                               7, index + 7, 16, 0) ;
  219.           rc[index].TermCode_PID = 0 ;
  220.           DOSSEMCLEAR ((DWORD) &runsem [index]) ;
  221.           DOSSEMSET   ((DWORD) &waitsem[index]) ;
  222.           }
  223.      }
  224.