home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / condor40.zip / CONDOR / src / util_lib / dprintf.c < prev    next >
C/C++ Source or Header  |  1989-09-02  |  8KB  |  308 lines

  1. /* 
  2. ** Copyright 1986, 1987, 1988, 1989 University of Wisconsin
  3. ** 
  4. ** Permission to use, copy, modify, and distribute this software and its
  5. ** documentation for any purpose and without fee is hereby granted,
  6. ** provided that the above copyright notice appear in all copies and that
  7. ** both that copyright notice and this permission notice appear in
  8. ** supporting documentation, and that the name of the University of
  9. ** Wisconsin not be used in advertising or publicity pertaining to
  10. ** distribution of the software without specific, written prior
  11. ** permission.  The University of Wisconsin makes no representations about
  12. ** the suitability of this software for any purpose.  It is provided "as
  13. ** is" without express or implied warranty.
  14. ** 
  15. ** THE UNIVERSITY OF WISCONSIN DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. ** THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. ** FITNESS. IN NO EVENT SHALL THE UNIVERSITY OF WISCONSIN  BE LIABLE FOR
  18. ** ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. ** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ** ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  21. ** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22. ** 
  23. ** Authors:  Allan Bricker and Michael J. Litzkow,
  24. **              University of Wisconsin, Computer Sciences Dept.
  25. ** 
  26. */ 
  27.  
  28.  
  29. /************************************************************************
  30. **
  31. **    Generic logging function.  Prints the message on DebugFP with a date if
  32. **    any bits in "flags" are set in DebugFlags.  If locking is desired,
  33. **    DebugLock should contain the name of the lock file.  If log length
  34. **    management is desired, MaxLog should contain the maximum length of the
  35. **    log in bytes.  (The log will be copied to "DebugFile.old", so MaxLog
  36. **    should be half of the space you are willing to devote.  If both log 
  37. **    length management and locking are desired, the lock file should not be
  38. **    the same as the log file.  Along with the date, other identifying
  39. **    information can be logged with the message by supplying the function
  40. **    (*DebugId)() which takes DebugFP as an argument.
  41. **
  42. ************************************************************************/
  43.  
  44. #include <stdio.h>
  45. #include <varargs.h>
  46. #include <time.h>
  47. #include <errno.h>
  48. #include <sys/file.h>
  49. #include <sys/param.h>
  50.  
  51. #include "condor_sys.h"
  52. #include "debug.h"
  53. #include "clib.h"
  54.  
  55. FILE    *debug_lock();
  56.  
  57. extern int    errno;
  58.  
  59. int        DebugFlags = D_ALWAYS;
  60. FILE    *DebugFP = stderr;
  61. int        MaxLog;
  62. char    *DebugFile;
  63. char    *DebugLock;
  64. int        (*DebugId)();
  65.  
  66. int        LockFd = -1;
  67.  
  68. char *DebugFlagNames[] = {
  69.     "D_ALWAYS", "D_TERMLOG", "D_SYSCALLS", "D_CKPT", "D_XDR", "D_MALLOC", 
  70.     "D_NOHEADER", "D_LOAD", "D_EXPR", "D_PROC", "D_JOB", "D_MACHINE",
  71.     "D_FULLDEBUG", "D_UNDEF13", "D_UNDEF14", "D_UNDEF15", "D_UNDEF16",
  72.     "D_UNDEF17", "D_UNDEF18", "D_UNDEF19", "D_UNDEF20", "D_UNDEF21",
  73.     "D_UNDEF22", "D_UNDEF23", "D_UNDEF24", "D_UNDEF25", "D_UNDEF26",
  74.     "D_UNDEF27", "D_UNDEF28", "D_UNDEF29", "D_UNDEF30", "D_UNDEF31",
  75. };
  76.  
  77. /*
  78. **    Initialize the DebugFP to a specific file number.
  79. */
  80. dprintf_init( fd )
  81. int fd;
  82. {
  83.     FILE *fp = fdopen( fd, "a" );
  84.  
  85.     if( fp != NULL ) {
  86.         DebugFP = fp;
  87.     } else {
  88.         dprintf(D_ALWAYS, "dprintf_init: failed to fdopen(%d)\n", fd );
  89.     }
  90. }
  91.  
  92. int InDBX = 0;
  93.  
  94. /*
  95. ** Print a nice log message, but only if "flags" are included in the
  96. ** current debugging flags.
  97. */
  98. /* VARARGS1 */
  99. dprintf(va_alist)
  100. va_dcl
  101. {
  102.     va_list pvar;
  103.     int flags;
  104.     char *fmt;
  105.     struct tm *tm, *localtime();
  106.     long *clock;
  107.     int scm;
  108.     int saved_errno;
  109.     int    omask;
  110.  
  111.     va_start(pvar);
  112.  
  113.     flags = va_arg(pvar, int);
  114.  
  115.         /* See if this is one of the messages we are logging */
  116.     if( !(flags&DebugFlags) ) {
  117.         goto VA_END;
  118.     }
  119.  
  120.     saved_errno = errno;
  121.  
  122.  
  123.     scm = SetSyscalls( SYS_LOCAL | SYS_UNRECORDED );
  124.  
  125.         /* Block any signal handlers which might try to print something */
  126.     if( ! InDBX ) {
  127.         /* Blocking signals makes dbx hang */
  128.         omask = sigblock( ~0 );
  129.     } else {
  130.         omask = 0;
  131.     }
  132.  
  133.         /* Open and lock the log file */
  134.     (void)debug_lock();
  135.  
  136.         /* Print the message with the time and a nice identifier */
  137.     if( ((DebugFlags|flags) & D_NOHEADER) == 0 ) {
  138.         (void)time(  (time_t *)&clock );
  139.         tm = localtime( (time_t *)&clock );
  140.         fprintf( DebugFP, "%d/%d %02d:%02d ", tm->tm_mon + 1, tm->tm_mday,
  141.                                     tm->tm_hour, tm->tm_min );
  142.  
  143.         if( DebugId ) {
  144.             (*DebugId)( DebugFP );
  145.         }
  146.     }
  147.  
  148.     fmt = va_arg(pvar, char *);
  149.  
  150. #if vax || i386 || bobcat || ibm032
  151.     {
  152.         int *argaddr = &va_arg(pvar, int);
  153.         _doprnt( fmt, argaddr, DebugFP );
  154.     }
  155. #else vax || i386 || bobcat || ibm032
  156.     vfprintf( DebugFP, fmt, pvar );
  157. #endif vax || i386 || bobcat || ibm032
  158.  
  159.         /* Close and unlock the log file */
  160.     debug_unlock();
  161.  
  162.         /* Let them signal handlers go!! */
  163.     (void) sigsetmask( omask );
  164.  
  165.     (void) SetSyscalls( scm );
  166.  
  167.     errno = saved_errno;
  168.  
  169. VA_END:
  170.     va_end(pvar);
  171. }
  172.  
  173. FILE *
  174. debug_lock()
  175. {
  176.     int    length;
  177.  
  178.         /* Acquire the lock */
  179.     if( DebugLock ) {
  180.         if( LockFd < 0 ) {
  181.             LockFd = open(DebugLock,O_CREAT|O_WRONLY,0600);
  182.             if( LockFd < 0 ) {
  183.                 if( errno == EMFILE ) {
  184.                     fd_panic( __LINE__, __FILE__ );
  185.                 }
  186.                 fprintf( DebugFP, "Can't open \"%s\"\n", DebugLock );
  187.                 exit( errno );
  188.             }
  189.         }
  190.  
  191.         if( flock(LockFd,LOCK_EX) < 0 ) {
  192.             fprintf( DebugFP, "Can't get exclusive lock on \"%s\"\n",
  193.                             DebugLock);
  194.             exit( errno );
  195.         }
  196.     }
  197.  
  198.     if( DebugFile ) {
  199.         errno = 0;
  200.         DebugFP = fopen(DebugFile, "a");
  201.  
  202.         if( DebugFP == NULL ) {
  203.             if( errno == EMFILE ) {
  204.                 fd_panic( __LINE__, __FILE__ );
  205.             }
  206.             fprintf(stderr, "Could not open DebugFile <%s>\n", DebugFile);
  207.             exit( errno );
  208.         }
  209.             /* Seek to the end */
  210.         if( (length=lseek(fileno(DebugFP),0,2)) < 0 ) {
  211.             fprintf( DebugFP, "Can't seek to end of DebugFP file\n" );
  212.             exit( errno );
  213.         }
  214.  
  215.             /* If it's too big, preserve it and start a new one */
  216.         if( MaxLog && length > MaxLog ) {
  217.             fprintf( DebugFP, "MaxLog = %d, length = %d\n", MaxLog, length );
  218.             preserve_log_file();
  219.         }
  220.     }
  221.     return DebugFP;
  222. }
  223.  
  224. debug_unlock()
  225. {
  226.     (void)fflush( DebugFP );
  227.  
  228.     if( DebugLock ) {
  229.             /* Don't forget to unlock the file */
  230.         if( flock(LockFd,LOCK_UN) < 0 ) {
  231.             fprintf(DebugFP,"Can't release exclusive lock on \"%s\"\n",
  232.                                                             DebugLock );
  233.             exit( errno );
  234.         }
  235.     }
  236.  
  237.     if( DebugFile ) {
  238.         (void)fclose( DebugFP );
  239.         DebugFP = NULL;
  240.     }
  241. }
  242.  
  243.  
  244. /*
  245. ** Copy the log file to a backup, then truncate the current one.
  246. */
  247. preserve_log_file()
  248. {
  249.     char    old[MAXPATHLEN + 4];
  250.     int        fd;
  251.     int        oumask;
  252.  
  253.     (void)sprintf( old, "%s.old", DebugFile );
  254.     fprintf( DebugFP, "Saving log file to \"%s\"\n", old );
  255.     (void)fflush( DebugFP );
  256.  
  257.  
  258.     if( rename(DebugFile,old) < 0 ) {
  259.         fprintf( DebugFP, "Can't link %s to %s\n", DebugFile, old );
  260.         perror( "rename" );
  261.         exit( errno );
  262.     }
  263.  
  264.     /* The log file MUST be group writeable */
  265.     oumask = umask( 0 );
  266.     if( (fd=open(DebugFile,O_CREAT|O_WRONLY,0664)) < 0 ) {
  267.         if( errno == EMFILE ) {
  268.             fd_panic( __LINE__, __FILE__ );
  269.         }
  270.         fprintf( DebugFP, "Can't re-open \"%s\"\n", DebugFile );
  271.         perror( "open" );
  272.         exit( errno );
  273.     }
  274.     (void) umask( oumask );
  275.  
  276.     (void)close( fileno(DebugFP) );
  277. #ifdef LINT
  278.     ((DebugFP)->_file) = fd;
  279. #else
  280.     fileno(DebugFP) = fd;
  281. #endif LINT
  282. }
  283.  
  284. /*
  285. ** Can't open log or lock file becuase we are out of fd's.  Try to let
  286. ** somebody know what happened.
  287. */
  288. fd_panic( line, file )
  289. int        line;
  290. char    *file;
  291. {
  292.     (void)close( 0 );
  293.     if( DebugFile ) {
  294.         DebugFP = fopen(DebugFile, "a");
  295.     }
  296.  
  297.     if( DebugFP == NULL ) {
  298.         exit( EMFILE );
  299.     }
  300.         /* Seek to the end */
  301.     (void)lseek( fileno(DebugFP), 0, 2 );
  302.  
  303.     fprintf( DebugFP,
  304.     "**** PANIC -- OUT OF FILE DESCRIPTORS at line %d in %s\n", line, file );
  305.     (void)fflush( DebugFP );
  306.     exit( EMFILE );
  307. }
  308.