home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / TIMEXSRC.ZIP / BA_MISC.C < prev    next >
C/C++ Source or Header  |  1990-03-29  |  9KB  |  357 lines

  1. /* ba_misc.c -- Miscellaneous routines for TIMEXBA
  2.  
  3.     February 1990    Mark E. Mallett, Personal Workstation Magazine
  4.  
  5. This file contains routines for TIMEXBA that don't fit into the
  6. other modules, classification-wise.
  7.  
  8. Included are the following routines:
  9.  
  10.         err_report      Error report routine for errhand stuff
  11.         get_sem         Access a resource via a semaphore
  12.         log             Log a message
  13.         log_begin       Begin logging
  14.         log_end         End logging
  15.         rel_sem         Release a semaphore
  16.         set_priority    Set thread priority
  17.  
  18. */
  19.  
  20. #define INCL_BASE
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <sys/types.h>
  25. #include <time.h>
  26. #include <os2.h>
  27.  
  28. #include "timex.h"
  29. #include "ba_timex.h"
  30.  
  31.  
  32. /* Local definitions */
  33.  
  34.  
  35. /* External data referenced */
  36.  
  37. extern  char    *Logfname;              /* Logfile name */
  38.  
  39. /* External routines used */
  40.  
  41. extern  void    bufdtm( char *bufP, time_t timeval );
  42.  
  43. /* Local data publicly available */
  44.  
  45.  
  46. /* Local routines and forward declarations */
  47.  
  48.         void    log_begin( void );
  49.         void    log_end( void );
  50.  
  51. /* Private data */
  52.  
  53. static  int     LogC;           /* Log group count */
  54. static  HFILE   LogH;           /* Logfile handle */
  55. static  HFILE   Stdinsave;      /* Saved stdin */
  56. static  HFILE   Stdoutsave;     /* Saved stdout */
  57. static  HFILE   Stderrsave;     /* Saved stderr */
  58.  
  59. /*
  60.  
  61. *//* get_sem( facP, itemP, sem )
  62.  
  63.         Access a semaphore
  64.  
  65. Accepts :
  66.  
  67.         facP            Name of facility making the request
  68.         itemP           Descriptive name of the semaphore
  69.         sem             Semaphore to acquire
  70.  
  71. Returns :
  72.  
  73.  
  74. */
  75.  
  76. void
  77. get_sem(
  78.         char            *facP,          /* Facility name */
  79.         char            *itemP,         /* Semaphore description */
  80.         HSEM            sem             /* Semaphore to acquire */
  81. ) {
  82.         int             status;
  83.  
  84.     /* Attempt to open the semaphore */
  85.     status = DosSemWait( sem, (long) -1 );
  86.     if ( status != 0 )
  87.         error( EC_SEMAPHORE, "get_sem() can't access %s semaphore for %s",
  88.                         itemP, facP );
  89. }
  90. /*
  91.  
  92. *//* rel_sem( facP, itemP, sem )
  93.  
  94.         Release a semaphore
  95.  
  96. Accepts :
  97.  
  98.         facP            Name of facility making the request
  99.         itemP           Descriptive name of the semaphore
  100.         sem             Semaphore to release
  101.  
  102. Returns :
  103.  
  104.  
  105. */
  106.  
  107. void
  108. rel_sem(
  109.         char            *facP,          /* Facility name */
  110.         char            *itemP,         /* Semaphore description */
  111.         HSEM            sem             /* Semaphore to release */
  112. ) {
  113.         int             status;
  114.  
  115.     status = DosSemClear( sem );
  116.     if ( status != 0 )
  117.         error( EC_SEMAPHORE, "rel_sem() can't release %s semaphore for %s",
  118.                 itemP, facP );
  119.  
  120. }
  121. /*
  122.  
  123. *//* set_priority( tid, class, value )
  124.  
  125.         Set a thread priority
  126.  
  127. Accepts :
  128.  
  129.         tid             Thread ID (0 for self )
  130.         class           New priority class
  131.         value           New priority value
  132.  
  133. Returns :
  134.  
  135. */
  136.  
  137. void
  138. set_priority(
  139.         TID             tid,            /* Thread ID */
  140.         int             class,          /* New priority class */
  141.         int             value           /* New priority value */
  142. ) {
  143.         int             status;
  144.  
  145.     /* Since set priority can only be done via a relative adjustment,
  146.        to set an absolute priority we first have to set to the
  147.        minimum, then offset that by the desired priority */
  148.     DosSetPrty( PRTYS_THREAD, class, -31, tid );
  149.     status = DosSetPrty( PRTYS_THREAD, class, value, tid );
  150.     if ( status != 0 )
  151.         warning( EC_NOTOK, "Can't set priority to class=%d value=%d",
  152.                          class, value );
  153. }
  154. /*
  155.  
  156. *//* err_report( cond, msgP )
  157.  
  158.         Print an error message on behalf of intercept_error.
  159.  
  160. Accepts :
  161.  
  162.         code            Error code reported
  163.         msgP            Error message given.
  164.  
  165. Returns :
  166.  
  167.         0
  168.  
  169. */
  170.  
  171. void
  172. err_report(
  173.         int             code,           /* Error code */
  174.         char            *msgP           /* Message text */
  175.           ) {
  176.  
  177.     log( "timex(%d): %s", code, msgP );
  178.  
  179. }
  180. /*
  181.  
  182. *//* log( fmtP, args... )
  183.  
  184.         Format a message to the log file
  185.  
  186. Accepts :
  187.  
  188.         fmtP            printf-style format string
  189.         args            printf arguments.  Quantity is limited.
  190.  
  191. Returns :
  192.  
  193.         Nothing.  Formats the string and writes to the log file
  194.  
  195. Notes :
  196.  
  197.         Handling of the arguments is kludgy.
  198.  
  199. */
  200.  
  201. void
  202. log(
  203.         char            *fmtP,          /* message format string */
  204.         int             a1,
  205.         int             a2,
  206.         int             a3,
  207.         int             a4,
  208.         int             a5,
  209.         int             a6,
  210.         int             a7,
  211.         int             a8,
  212.         int             a9,
  213.         int             a10
  214.     ) {
  215.  
  216.         USHORT          len;
  217.         char            *strP;          /* String ptr */
  218.         char            buf[200];       /* Message buffer */
  219.  
  220.     strP = &buf[0];
  221.     bufdtm( strP, time( (time_t *)NULL ) );
  222.     strP += strlen( strP );
  223.     *strP++ = ':';
  224.     *strP++ = ' ';
  225.     sprintf( strP, fmtP, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 );
  226.  
  227.     log_begin();
  228.     if ( LogH != 0xffff ) {
  229.         /* Append CRLF to the string */
  230.         strP = &buf[ strlen( &buf[0] ) ];
  231.         *strP++ = '\r';
  232.         *strP++ = '\n';
  233.         *strP = NUL;
  234.  
  235.         DosWrite( LogH, &buf[0], strlen( &buf[0] ), &len );
  236.     }
  237.     else
  238.         fprintf( stderr, "%s\n", &buf[0] );
  239.  
  240.     log_end();
  241. }
  242. /*
  243.  
  244. *//* log_begin(), log_end()
  245.  
  246.         Begin and end a group of logging
  247.  
  248. Accepts :
  249.  
  250. Returns :
  251.  
  252.         LogFP           Set or not set depending on open status
  253.  
  254. Notes :
  255.  
  256.         The log_begin() / log_end() sequence is used to keep the log file
  257.         open while a bunch of log writes is being made.  This avoids the
  258.         overhead of opening the file for each batch of writes.  It also
  259.         helps generalize the log open/close procedure.  begin/end sequences
  260.         can be nested.
  261.  
  262.         log_begin() also points stdout and stderr to the log file, and
  263.         closes stdin.  This is done for the benefit of exec'ed programs,
  264.         which will point to the log file by default.  log_end() resets
  265.         the handles to their prior state.
  266.  
  267. */
  268.  
  269. void
  270. log_begin( void ) {
  271.  
  272.         USHORT          status;
  273.         USHORT          action;
  274.         ULONG           fileptr;
  275.         HFILE           dupH;
  276.  
  277.     /* Protect this code section... */
  278.     DosEnterCritSec();
  279.  
  280.     if ( ++LogC == 1 ) {
  281.         /* Try to open the logfile */
  282.         status = DosOpen( Logfname, &LogH, &action, 0L, 0,
  283.                           FILE_CREATE|FILE_OPEN,
  284.                           OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYNONE|
  285.                                 OPEN_FLAGS_WRITE_THROUGH,
  286.                           0L );
  287.  
  288.         if ( status != 0 )
  289.             LogH = 0xffff;
  290.         else {
  291.  
  292.             /* Make sure stdout and stderr are written */
  293.             fflush( stdout );
  294.             fflush( stderr );
  295.  
  296.             /* Remember stdin, stdout, stderr handles */
  297.             Stdinsave = 0xffff;
  298.             DosDupHandle( 0, &Stdinsave );
  299.  
  300.             Stdoutsave = 0xffff;
  301.             DosDupHandle( 1, &Stdoutsave );
  302.             DosClose( 1 );
  303.             dupH = 1;
  304.             DosDupHandle( LogH, &dupH );
  305.  
  306.             Stderrsave = 0xffff;
  307.             DosDupHandle( 2, &Stderrsave );
  308.             DosClose( 2 );
  309.             dupH = 2;
  310.             DosDupHandle( LogH, &dupH );
  311.  
  312.             /* Close stdin now that it can't be taken over */
  313.             DosClose( 0 );
  314.         }
  315.     }
  316.  
  317.     /* Set to the end of the logfile if it's open */
  318.     if ( LogH != 0xffff )
  319.         DosChgFilePtr( LogH, 0L, FILE_END, &fileptr );
  320.  
  321.     DosExitCritSec();
  322.  
  323. }
  324.  
  325. void
  326. log_end( void ) {
  327.  
  328.         HFILE   dupH;                   /* For duplicating handles */
  329.  
  330.     DosEnterCritSec();                  /* Protect this section */
  331.  
  332.     if ( --LogC == 0 ) {
  333.         if ( LogH != 0xffff ) {
  334.             /* Reset stdin et al */
  335.             dupH = 0;
  336.             DosDupHandle( Stdinsave, &dupH );
  337.             DosClose( Stdinsave );
  338.  
  339.             DosClose( 1 );
  340.             dupH = 1;
  341.             DosDupHandle( Stdoutsave, &dupH );
  342.             DosClose( Stdoutsave );
  343.  
  344.             DosClose( 2 );
  345.             dupH = 2;
  346.             DosDupHandle( Stderrsave, &dupH );
  347.             DosClose( Stderrsave );
  348.  
  349.             DosClose( LogH );
  350.             LogH = 0xffff;
  351.         }
  352.     }
  353.  
  354.     DosExitCritSec();
  355. }
  356.  
  357.