Line data Source code
1 : /*
2 : * Copyright (C) 2011 Andrea Mazzoleni
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef __SUPPORT_H
19 : #define __SUPPORT_H
20 :
21 : /****************************************************************************/
22 : /* lock */
23 :
24 : /**
25 : * Initialize and destroy the locks.
26 : */
27 : void lock_init(void);
28 : void lock_done(void);
29 :
30 : /**
31 : * Lock used for printf.
32 : *
33 : * In Windows printf() is not atomic, and multiple threads
34 : * will have output interleaved.
35 : *
36 : * Note that even defining __USE_MINGW_ANSI_STDIO the problem persists.
37 : *
38 : * See for example:
39 : *
40 : * Weird output when I use pthread and printf.
41 : * http://stackoverflow.com/questions/13190254/weird-output-when-i-use-pthread-and-printf
42 : *
43 : * This is also required in other OS because we split output in stdlog in
44 : * two fprintf calls.
45 : */
46 : void lock_msg(void);
47 : void unlock_msg(void);
48 :
49 : /**
50 : * Lock used for memory counter.
51 : */
52 : void lock_memory(void);
53 : void unlock_memory(void);
54 :
55 : /****************************************************************************/
56 : /* log */
57 :
58 : /**
59 : * Fatal error messages.
60 : *
61 : * Messages printed before an early termination.
62 : *
63 : * These messages go in the log file and in stderr unconditionally.
64 : */
65 : void log_fatal(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
66 :
67 : /**
68 : * Unexpected error messages.
69 : *
70 : * Messages reporting error conditions that don't prevent the program to run.
71 : *
72 : * Some of them could be also serious errors, like "silent errors".
73 : * In such case, the summary result is always printed as error,
74 : * and we are sure to notify the user in some way.
75 : *
76 : * These messages go in the log file if specified, otherwise they go in stderr.
77 : */
78 : void log_error(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
79 :
80 : /**
81 : * Expected error messages, without fallback to stderr.
82 : *
83 : * These errors are "someway" expected, and then they never go to screen.
84 : * For example, when undeleting missing files, the messages for missing files
85 : * are not shown.
86 : *
87 : * These messages go in the log file if specified, otherwise they are lost.
88 : */
89 : void log_expected(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
90 :
91 : /**
92 : * Tag messages.
93 : *
94 : * Messages are in tag format, like "tag:entry:...".
95 : *
96 : * These messages never go on the screen, but only in the log file if specified.
97 : *
98 : * Note that this function, allows not \n terminated strings.
99 : *
100 : * These messages are buffered. Use msg_flush() to flush them.
101 : */
102 : void log_tag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
103 :
104 : /**
105 : * Flush the log.
106 : */
107 : void log_flush(void);
108 :
109 : /**
110 : * Pointer to log function.
111 : */
112 : typedef void fptr(const char* format, ...);
113 :
114 : /****************************************************************************/
115 : /* message */
116 :
117 : /**
118 : * Message levels.
119 : *
120 : * The levels control the amount of information printed on the screen.
121 : * Note that log_fatal(), log_error(), log_expected() and log_tag() are not affected by this option.
122 : *
123 : * From the most quiet to the most verbose.
124 : */
125 : #define MSG_STATUS -3
126 : #define MSG_INFO -2
127 : #define MSG_PROGRESS -1
128 : #define MSG_BAR 0
129 : #define MSG_VERBOSE 1
130 :
131 : /**
132 : * Selected message level.
133 : */
134 : extern int msg_level;
135 :
136 : /**
137 : * State messages.
138 : *
139 : * Messages that tell what the program is doing or did, but limited to few lines.
140 : * They are status information, and summary results.
141 : */
142 : void msg_status(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
143 :
144 : /**
145 : * Info messages.
146 : *
147 : * Messages that tell what was done.
148 : * Potentially a lot of messages are possible. They can still be on the screen,
149 : * as losing them we don't lose information.
150 : *
151 : * These messages never go in the log file, because there is always a corresponding log_tag().
152 : */
153 : void msg_info(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
154 :
155 : /**
156 : * Progress messages.
157 : *
158 : * Message that tell the progress of program.
159 : *
160 : * These messages also go in the log file.
161 : */
162 : void msg_progress(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
163 :
164 : /**
165 : * Progress bar messages.
166 : *
167 : * Message that show the percentage of the progress.
168 : *
169 : * These messages never go in the log file.
170 : *
171 : * These messages are buffered. Use msg_flush() to flush them.
172 : */
173 : void msg_bar(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
174 :
175 : /**
176 : * Verbose messages.
177 : *
178 : * Message that tell what is already expected.
179 : *
180 : * These messages also go in the log file.
181 : */
182 : void msg_verbose(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
183 :
184 : /**
185 : * Flush the output.
186 : */
187 : void msg_flush(void);
188 :
189 : /****************************************************************************/
190 : /* print */
191 :
192 : /**
193 : * Print a repeated char.
194 : */
195 : void printc(char c, size_t pad);
196 :
197 : /**
198 : * Print a string with right space padding.
199 : */
200 : void printr(const char* str, size_t pad);
201 :
202 : /**
203 : * Print a string with left space padding.
204 : */
205 : void printl(const char* str, size_t pad);
206 :
207 : /**
208 : * Print a probability with space padding.
209 : */
210 : void printp(double v, size_t pad);
211 :
212 : /****************************************************************************/
213 : /* string */
214 :
215 : #define ESC_MAX (PATH_MAX*2 + 1)
216 :
217 : /**
218 : * Escape a string for the log.
219 : *
220 : * \param buffer Preallocated buffer of ESC_MAX size.
221 : *
222 : * Chars ':', '\n', '\r' and '\' are escaped to '\d', '\\n', '\\r' and '\\'.
223 : */
224 : const char* esc_tag(const char* str, char* buffer);
225 :
226 : /**
227 : * Escape a string for the shell.
228 : *
229 : * \param buffer Preallocated buffer of ESC_MAX size.
230 : */
231 : const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer);
232 332127 : static inline const char* esc_shell(const char* str, char* buffer)
233 : {
234 332127 : return esc_shell_multi(&str, 1, buffer);
235 : }
236 :
237 : /**
238 : * Polish a string.
239 : *
240 : * Not printable chars are replaced by spaces.
241 : *
242 : * Note that the passed string is modified.
243 : */
244 : char* strpolish(char* s);
245 :
246 : /**
247 : * Split a string in multiple tokens separated by delimiters.
248 : *
249 : * Multiple delimiters are grouped together.
250 : */
251 : unsigned strsplit(char** split_map, unsigned split_max, char* line, const char* delimiters);
252 :
253 : /****************************************************************************/
254 : /* path */
255 :
256 : /**
257 : * Copy a path limiting the size.
258 : * Abort if too long.
259 : */
260 : void pathcpy(char* dst, size_t size, const char* src);
261 :
262 : /**
263 : * Concatenate a path limiting the size.
264 : * Abort if too long.
265 : */
266 : void pathcat(char* dst, size_t size, const char* src);
267 :
268 : /**
269 : * Concatenate a path limiting the size.
270 : * Abort if too long.
271 : */
272 : void pathcatc(char* dst, size_t size, char c);
273 :
274 : /**
275 : * Import a path limiting the size.
276 : * In Windows all the backslash are converted to the C standard of forward slash.
277 : * Abort if too long.
278 : */
279 : void pathimport(char* dst, size_t size, const char* src);
280 :
281 : /**
282 : * Export a path limiting the size.
283 : * In Windows all the C slashes are converted to the Windows backslash.
284 : * Abort if too long.
285 : */
286 : void pathexport(char* dst, size_t size, const char* src);
287 :
288 : /**
289 : * Print a path.
290 : * Abort if too long.
291 : */
292 : void pathprint(char* dst, size_t size, const char* format, ...) __attribute__((format(attribute_printf, 3, 4)));
293 :
294 : /**
295 : * Ensure the presence of a terminating slash, if it isn't empty.
296 : * Abort if too long.
297 : */
298 : void pathslash(char* dst, size_t size);
299 :
300 : /**
301 : * Cut everything after the latest slash.
302 : */
303 : void pathcut(char* dst);
304 :
305 : /**
306 : * Compare two paths.
307 : * In Windows it's case insensitive and assumes \ equal at /.
308 : */
309 : int pathcmp(const char* a, const char* b);
310 :
311 : /****************************************************************************/
312 : /* file-system */
313 :
314 : /**
315 : * Create all the ancestor directories if missing.
316 : * The file name, after the last /, is ignored.
317 : */
318 : int mkancestor(const char* file);
319 :
320 : /**
321 : * Change the modification time of an open file.
322 : */
323 : int fmtime(int f, int64_t mtime_sec, int mtime_nsec);
324 :
325 : /**
326 : * Change the modification time of a file or link.
327 : * Note that links are NOT deferenced.
328 : */
329 : int lmtime(const char* path, int64_t mtime_sec, int mtime_nsec);
330 :
331 : /****************************************************************************/
332 : /* advise */
333 :
334 : /**
335 : * Advise modes.
336 : */
337 : #define ADVISE_DEFAULT 0 /**< Default mode. */
338 : #define ADVISE_NONE 1 /**< Bare read/write mode. */
339 : #define ADVISE_SEQUENTIAL 2 /**< Sequential mode. */
340 : #define ADVISE_FLUSH 3 /**< Flush mode. */
341 : #define ADVISE_FLUSH_WINDOW 4 /**< Flush mode with a window of 8MB. */
342 : #define ADVISE_DISCARD 5 /**< Discard the cache after every operation. */
343 : #define ADVISE_DISCARD_WINDOW 6 /**< Discard the cache with a window of 8MB. */
344 : #define ADVISE_DIRECT 7 /**< Direct mode. */
345 :
346 : #define ADVISE_WINDOW_SIZE (8 * 1024 * 1024) /**< Window size. */
347 :
348 : struct advise_struct {
349 : int mode;
350 : data_off_t dirty_begin;
351 : data_off_t dirty_end;
352 : };
353 :
354 : void advise_init(struct advise_struct* advise, int mode);
355 : int advise_flags(struct advise_struct* advise);
356 : int advise_open(struct advise_struct* advise, int f);
357 : int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
358 : int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
359 :
360 : /****************************************************************************/
361 : /* memory */
362 :
363 : /**
364 : * Return the size of the allocated memory.
365 : */
366 : size_t malloc_counter_get(void);
367 :
368 : /**
369 : * Safe malloc.
370 : * If no memory is available, it aborts.
371 : */
372 : void* malloc_nofail(size_t size);
373 :
374 : /**
375 : * Safe cmalloc.
376 : * If no memory is available, it aborts.
377 : */
378 : void* calloc_nofail(size_t count, size_t size);
379 :
380 : /**
381 : * Safe strdup.
382 : * If no memory is available, it aborts.
383 : */
384 : char* strdup_nofail(const char* str);
385 :
386 : /**
387 : * Helper for printing an error about a failed allocation.
388 : */
389 : void malloc_fail(size_t size);
390 :
391 : /****************************************************************************/
392 : /* smartctl */
393 :
394 : /**
395 : * Read smartctl attributes from a stream.
396 : * Return 0 on success.
397 : */
398 : int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* smart, char* serial, char* vendor, char* model);
399 :
400 : /**
401 : * Flush smartctl output from a stream.
402 : */
403 : int smartctl_flush(FILE* f, const char* file, const char* name);
404 :
405 : /****************************************************************************/
406 : /* thread */
407 :
408 : #if HAVE_PTHREAD
409 : /**
410 : * Control when to signal the condition variables.
411 : *
412 : * Default is inside the mutex.
413 : *
414 : * Ensure to change that before starting any thread.
415 : */
416 : int thread_cond_signal_outside;
417 :
418 : /**
419 : * Thread wrappers to handle error conditions.
420 : */
421 : void thread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t* attr);
422 : void thread_mutex_destroy(pthread_mutex_t* mutex);
423 : void thread_mutex_lock(pthread_mutex_t* mutex);
424 : void thread_mutex_unlock(pthread_mutex_t* mutex);
425 : void thread_cond_init(pthread_cond_t* cond, pthread_condattr_t* attr);
426 : void thread_cond_destroy(pthread_cond_t* cond);
427 : void thread_cond_signal(pthread_cond_t* cond);
428 : void thread_cond_broadcast(pthread_cond_t* cond);
429 : void thread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
430 : void thread_cond_signal_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex);
431 : void thread_cond_broadcast_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex);
432 : void thread_create(pthread_t* thread, pthread_attr_t* attr, void *(* func)(void *), void *arg);
433 : void thread_join(pthread_t thread, void** retval);
434 : #endif
435 :
436 : #endif
437 :
|