1 /*
2 * internal.h
3 *
4 * Version: 2.2.6
5 *
6 * -----------------------------------------------------------------------------
7 *
8 * SPDX-License-Identifier: MIT
9 *
10 * Copyright (c) 2018-2024 Ryan M. Lederman <lederman@gmail.com>
11 * Copyright (c) 2018-2024 Jeffrey H. Johnson <trnsz@pobox.com>
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a copy of
14 * this software and associated documentation files (the "Software"), to deal in
15 * the Software without restriction, including without limitation the rights to
16 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
17 * the Software, and to permit persons to whom the Software is furnished to do so,
18 * subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in all
21 * copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
25 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
26 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
27 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 *
30 * -----------------------------------------------------------------------------
31 */
32
33 #ifndef _SIR_INTERNAL_H_INCLUDED
34 # define _SIR_INTERNAL_H_INCLUDED
35
36 # include "sir/helpers.h"
37 # include "sir/maps.h"
38 # include "sir/errors.h"
39
40 # if defined(__cplusplus)
41 extern "C" {
42 # endif
43
44 /**
45 * Initializes a ::sirinit structure suitable to pass to ::sir_init
46 * without modification.
47 */
48 bool _sir_makeinit(sirinit* si);
49
50 /** Initializes libsir. */
51 bool _sir_init(sirinit* si);
52
53 /** Un-initializes libsir. */
54 bool _sir_cleanup(void);
55
56 /** Evaluates whether or not libsir has been initialized. */
57 bool _sir_isinitialized(void);
58
59 /**
60 * Evaluates whether or not libsir has been initialized, and sets the last
61 * error to SIR_E_NOTREADY if not initialized.
62 */
63 bool _sir_sanity(void);
64
65 /** Validates the configuration passed to ::sir_init. */
66 bool _sir_init_sanity(const sirinit* si);
67
68 /** Resets TLS data. */
69 void _sir_reset_tls(void);
70
71 /** Updates levels for stdout. */
72 bool _sir_stdoutlevels(sirinit* si, const sir_update_config_data* data);
73
74 /** Updates options for stdout. */
75 bool _sir_stdoutopts(sirinit* si, const sir_update_config_data* data);
76
77 /** Updates levels for stderr. */
78 bool _sir_stderrlevels(sirinit* si, const sir_update_config_data* data);
79
80 /** Updates options for stderr. */
81 bool _sir_stderropts(sirinit* si, const sir_update_config_data* data);
82
83 /** Updates levels for the system logger. */
84 bool _sir_sysloglevels(sirinit* si, const sir_update_config_data* data);
85
86 /** Updates options for the system logger. */
87 bool _sir_syslogopts(sirinit* si, const sir_update_config_data* data);
88
89 /** Updates the identity for the system logger.*/
90 bool _sir_syslogid(sirinit* si, const sir_update_config_data* data);
91
92 /** Updates the category for the system logger. */
93 bool _sir_syslogcat(sirinit* si, const sir_update_config_data* data);
94
95 /** Callback for updating values in the global config. */
96 typedef bool (*sirinit_update)(sirinit*, const sir_update_config_data*);
97
98 /** Updates values in the global config. */
99 bool _sir_writeinit(const sir_update_config_data* data, sirinit_update update);
100
101 /** Locks a protected section. */
102 void* _sir_locksection(sir_mutex_id mid);
103
104 /** Unlocks a protected section. */
105 void _sir_unlocksection(sir_mutex_id mid);
106
107 /** Maps a ::sir_mutex_id to a ::sir_mutex and protected section. */
108 bool _sir_mapmutexid(sir_mutex_id mid, sir_mutex** m, void** section);
109
110 # if !defined(__WIN__)
111 /** Static initialization procedure. */
112 void _sir_init_static_once(void);
113 # else /* __WIN__ */
114 /** Static initialization procedure. */
115 BOOL CALLBACK _sir_init_static_once(PINIT_ONCE ponce, PVOID param, PVOID* ctx);
116 # endif
117
118 /** Shared one-time static data initialization routine. */
119 bool _sir_init_common_static(void);
120
121 /** Executes only one time. */
122 bool _sir_once(sir_once* once, sir_once_fn func);
123
124 /** Core output formatting. */
125 PRINTF_FORMAT_ATTR(2, 0)
126 bool _sir_logv(sir_level level, PRINTF_FORMAT const char* format, va_list args);
127
128 /** Output dispatching. */
129 bool _sir_dispatch(const sirinit* si, sir_level level, sirbuf* buf);
130
131 /** Specific destination formatting. */
132 const char* _sir_format(bool styling, sir_options opts, sirbuf* buf);
133
134 /** Initializes a ::sir_syslog_dest. */
135 bool _sir_syslog_init(const char* name, sir_syslog_dest* ctx);
136
137 /**
138 * Abstraction for setup of platform-specific implementations of system
139 * logger facilities.
140 *
141 * Called upon initialization of the library (and if the configuration is modified).
142 * Performs any necessary preparation: connecting/opening handles, etc.
143 */
144 bool _sir_syslog_open(sir_syslog_dest* ctx);
145
146 /**
147 * Abstraction for writing to platform-specific implementations of
148 * system logger facilities.
149 */
150 bool _sir_syslog_write(sir_level level, const sirbuf* buf, const sir_syslog_dest* ctx);
151
152 /**
153 * Called after updates to the global config that may require reconfiguration
154 * of the system logger.
155 */
156 bool _sir_syslog_updated(sirinit* si, const sir_update_config_data* data);
157
158 /**
159 * Abstraction for cleanup/closure of platform-specific implementations of
160 * system logger facilities.
161 *
162 * Called upon shutdown of the library (and if the configuration is modified).
163 * Performs any necessary operations: disconnecting/closing handles, etc.
164 */
165 bool _sir_syslog_close(sir_syslog_dest* ctx);
166
167 /** Resets the internal state. */
168 void _sir_syslog_reset(sir_syslog_dest* ctx);
169
170 /** Returns the formatted, human-readable form of a ::sir_level. */
171 const char* _sir_formattedlevelstr(sir_level level);
172
173 /** Retrieves the current time w/ optional milliseconds. */
174 bool _sir_clock_gettime(int clock, time_t* tbuf, long* msecbuf);
175
176 /**
177 * Returns the number of milliseconds elapsed since a point in time represented
178 * by the when parameter.
179 */
180 double _sir_msec_since(const sir_time* when, sir_time* out);
181
182 /** Returns the current process identifier. */
183 pid_t _sir_getpid(void);
184
185 /** Returns the current thread identifier. */
186 pid_t _sir_gettid(void);
187
188 /** Retrieves the current thread's name. */
189 bool _sir_getthreadname(char name[SIR_MAXPID]);
190
191 /** Sets the current thread's name. */
192 bool _sir_setthreadname(const char* name);
193
194 /** Retrieves the hostname of this machine. */
195 bool _sir_gethostname(char name[SIR_MAXHOST]);
196
197 /** Retrieves the number of available logical processors on this machine. */
198 long __sir_nprocs(bool test_mode);
199 # define _sir_nprocs() __sir_nprocs(0)
200 # define _sir_nprocs_test() __sir_nprocs(1)
201
202 # if defined(__cplusplus)
203 }
204 # endif
205
206 #endif /* !_SIR_INTERNAL_H_INCLUDED */