tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

log.c
Go to the documentation of this file.
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include "tmux.h"
28 
29 static FILE *log_file;
30 static int log_level;
31 
32 static void log_event_cb(int, const char *);
33 static void log_vwrite(const char *, va_list);
34 
35 /* Log callback for libevent. */
36 static void
37 log_event_cb(__unused int severity, const char *msg)
38 {
39  log_debug("%s", msg);
40 }
41 
42 /* Increment log level. */
43 void
45 {
46  log_level++;
47 }
48 
49 /* Get log level. */
50 int
52 {
53  return (log_level);
54 }
55 
56 /* Open logging to file. */
57 void
58 log_open(const char *name)
59 {
60  char *path;
61 
62  if (log_level == 0)
63  return;
64  log_close();
65 
66  xasprintf(&path, "tmux-%s-%ld.log", name, (long)getpid());
67  log_file = fopen(path, "a");
68  free(path);
69  if (log_file == NULL)
70  return;
71 
72  setvbuf(log_file, NULL, _IOLBF, 0);
73  event_set_log_callback(log_event_cb);
74 }
75 
76 /* Toggle logging. */
77 void
78 log_toggle(const char *name)
79 {
80  if (log_level == 0) {
81  log_level = 1;
82  log_open(name);
83  log_debug("log opened");
84  } else {
85  log_debug("log closed");
86  log_level = 0;
87  log_close();
88  }
89 }
90 
91 /* Close logging. */
92 void
93 log_close(void)
94 {
95  if (log_file != NULL)
96  fclose(log_file);
97  log_file = NULL;
98 
99  event_set_log_callback(NULL);
100 }
101 
102 /* Write a log message. */
103 static void
104 log_vwrite(const char *msg, va_list ap)
105 {
106  char *fmt, *out;
107  struct timeval tv;
108 
109  if (log_file == NULL)
110  return;
111 
112  if (vasprintf(&fmt, msg, ap) == -1)
113  return;
114  if (stravis(&out, fmt, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL) == -1) {
115  free(fmt);
116  return;
117  }
118 
119  gettimeofday(&tv, NULL);
120  if (fprintf(log_file, "%lld.%06d %s\n", (long long)tv.tv_sec,
121  (int)tv.tv_usec, out) != -1)
122  fflush(log_file);
123 
124  free(out);
125  free(fmt);
126 }
127 
128 /* Log a debug message. */
129 void
130 log_debug(const char *msg, ...)
131 {
132  va_list ap;
133 
134  if (log_file == NULL)
135  return;
136 
137  va_start(ap, msg);
138  log_vwrite(msg, ap);
139  va_end(ap);
140 }
141 
142 /* Log a critical error with error string and die. */
143 __dead void
144 fatal(const char *msg, ...)
145 {
146  char *fmt;
147  va_list ap;
148 
149  va_start(ap, msg);
150  if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
151  exit(1);
152  log_vwrite(fmt, ap);
153  va_end(ap);
154  exit(1);
155 }
156 
157 /* Log a critical error and die. */
158 __dead void
159 fatalx(const char *msg, ...)
160 {
161  char *fmt;
162  va_list ap;
163 
164  va_start(ap, msg);
165  if (asprintf(&fmt, "fatal: %s", msg) == -1)
166  exit(1);
167  log_vwrite(fmt, ap);
168  va_end(ap);
169  exit(1);
170 }
#define __unused
Definition: compat.h:60
int vasprintf(char **, const char *, va_list)
int asprintf(char **, const char *,...)
#define __dead
Definition: compat.h:63
const char * name
Definition: layout-set.c:38
void fatal(const char *msg,...)
Definition: log.c:144
void log_close(void)
Definition: log.c:93
void fatalx(const char *msg,...)
Definition: log.c:159
static void log_vwrite(const char *, va_list)
Definition: log.c:104
void log_add_level(void)
Definition: log.c:44
void log_toggle(const char *name)
Definition: log.c:78
int log_get_level(void)
Definition: log.c:51
static int log_level
Definition: log.c:30
void log_debug(const char *msg,...)
Definition: log.c:130
static FILE * log_file
Definition: log.c:29
void log_open(const char *name)
Definition: log.c:58
static void log_event_cb(int, const char *)
Definition: log.c:37
int xasprintf(char **ret, const char *fmt,...)
Definition: xmalloc.c:109