1 /* Public Domain Curses */
2 
3 #include <curspriv.h>
4 
5 /*man-start**************************************************************
6 
7 debug
8 -----
9 
10 ### Synopsis
11 
12     void traceon(void);
13     void traceoff(void);
14     void PDC_debug(const char *, ...);
15 
16 ### Description
17 
18    traceon() and traceoff() toggle the recording of debugging
19    information to the file "trace". Although not standard, similar
20    functions are in some other curses implementations.
21 
22    PDC_debug() is the function that writes to the file, based on
23    whether traceon() has been called. It's used from the PDC_LOG()
24    macro.
25 
26    The environment variable PDC_TRACE_FLUSH controls whether the
27    trace file contents are fflushed after each write.  The default
28    is not. Set it to enable this (may affect performance).
29 
30 ### Portability
31                              X/Open    BSD    SYS V
32     traceon                     -       -       -
33     traceoff                    -       -       -
34     PDC_debug                   -       -       -
35 
36 **man-end****************************************************************/
37 
38 #include <stdlib.h>
39 #include <string.h>
40 #include <sys/types.h>
41 #include <time.h>
42 
43 FILE *pdc_dbfp = NULL;
44 static bool want_fflush = FALSE;
45 
PDC_debug(const char * fmt,...)46 void PDC_debug(const char *fmt, ...)
47 {
48     va_list args;
49     char hms[9];
50     time_t now;
51 
52     if (!pdc_dbfp)
53         return;
54 
55     time(&now);
56     strftime(hms, 9, "%H:%M:%S", localtime(&now));
57     fprintf(pdc_dbfp, "At: %8.8ld - %s ", (long) clock(), hms);
58 
59     va_start(args, fmt);
60     vfprintf(pdc_dbfp, fmt, args);
61     va_end(args);
62 
63     /* If you are crashing and losing debugging information, enable this
64        by setting the environment variable PDC_TRACE_FLUSH. This may
65        impact performance. */
66 
67     if (want_fflush)
68         fflush(pdc_dbfp);
69 
70     /* If with PDC_TRACE_FLUSH enabled you are still losing logging in
71        crashes, you may need to add a platform-dependent mechanism to
72        flush the OS buffers as well (such as fsync() on POSIX) -- but
73        expect terrible performance. */
74 }
75 
traceon(void)76 void traceon(void)
77 {
78     char *env;
79 
80     if (pdc_dbfp)
81         fclose(pdc_dbfp);
82 
83     /* open debug log file append */
84     pdc_dbfp = fopen("trace", "a");
85     if (!pdc_dbfp)
86     {
87         fprintf(stderr,
88             "PDC_debug(): Unable to open debug log file\n");
89         return;
90     }
91 
92     if ((env = getenv("PDC_TRACE_FLUSH")))
93         want_fflush = atoi(env);
94 
95     PDC_LOG(("traceon() - called\n"));
96 }
97 
traceoff(void)98 void traceoff(void)
99 {
100     if (!pdc_dbfp)
101         return;
102 
103     PDC_LOG(("traceoff() - called\n"));
104 
105     fclose(pdc_dbfp);
106     pdc_dbfp = NULL;
107     want_fflush = FALSE;
108 }
109