unify file locations
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -6,6 +6,9 @@ tmp/
|
|||||||
# Clangd
|
# Clangd
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
# Us
|
# Copied dependencies
|
||||||
|
src/sc/
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
**/build
|
**/build
|
||||||
**/compile_commands.json
|
**/compile_commands.json
|
||||||
|
|||||||
@@ -14,29 +14,10 @@ if(UNIX AND NOT APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Common compile options
|
# Common compile options
|
||||||
|
|
||||||
|
# Hide everything by default to keep libraries smaller.
|
||||||
add_compile_options("-fvisibility=hidden")
|
add_compile_options("-fvisibility=hidden")
|
||||||
|
|
||||||
# Handle 3rd party dependencies
|
|
||||||
# #############################
|
|
||||||
|
|
||||||
set(COPY_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/copy_dependencies.sh)
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND bash ${COPY_SCRIPT}
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
RESULT_VARIABLE SCRIPT_RESULT
|
|
||||||
OUTPUT_VARIABLE SCRIPT_OUTPUT
|
|
||||||
ERROR_VARIABLE SCRIPT_ERROR
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if the script executed successfully
|
|
||||||
if(NOT SCRIPT_RESULT EQUAL 0)
|
|
||||||
message(WARNING "Script execution failed: ${SCRIPT_ERROR}")
|
|
||||||
else()
|
|
||||||
message(STATUS "Running script ${COPY_SCRIPT}:\n${SCRIPT_OUTPUT}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# hiload library
|
# hiload library
|
||||||
# ##############
|
# ##############
|
||||||
|
|
||||||
@@ -45,15 +26,15 @@ add_library(hiload SHARED
|
|||||||
src/symbols.c
|
src/symbols.c
|
||||||
src/files.c
|
src/files.c
|
||||||
src/memory.c
|
src/memory.c
|
||||||
src/logger/logger.c
|
src/logger.c
|
||||||
src/moduler/moduler.c
|
src/moduler.c
|
||||||
src/moduler/elf.c
|
src/hielf.c
|
||||||
src/string/string.c
|
src/histring.c
|
||||||
src/filewatcher/filewatcher.c
|
src/filewatcher/filewatcher.c
|
||||||
src/filewatcher/filewatch.c
|
src/filewatcher/filewatch.c
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
src/logger/sc_log.c
|
3rd/sc/logger/sc_log.c
|
||||||
)
|
)
|
||||||
# TODO: Get -Wpadded back by refactoring sc_array or just surround
|
# TODO: Get -Wpadded back by refactoring sc_array or just surround
|
||||||
# all type sc_array declarations with the ignore pragma
|
# all type sc_array declarations with the ignore pragma
|
||||||
@@ -90,16 +71,19 @@ install(EXPORT hiloadTargets
|
|||||||
|
|
||||||
export(TARGETS hiload FILE hiloadConfig.cmake)
|
export(TARGETS hiload FILE hiloadConfig.cmake)
|
||||||
|
|
||||||
# auditor libraries
|
# Auditor libraries
|
||||||
# ###############
|
# ###############
|
||||||
|
|
||||||
|
# TODO: Move auditor to its own project, possibly even out of this repo.
|
||||||
|
# It has only been a side product
|
||||||
|
|
||||||
add_library(auditor-x86_64 SHARED
|
add_library(auditor-x86_64 SHARED
|
||||||
src/auditor/auditor-x86_64.c
|
solib-auditors/auditor-x86_64.c
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(auditor-x86_64 PRIVATE
|
target_compile_options(auditor-x86_64 PRIVATE
|
||||||
$<$<C_COMPILER_ID:GNU>:-Wall -Wextra>
|
$<$<C_COMPILER_ID:GNU>:-Wall -Wextra -Wpedantic>
|
||||||
$<$<C_COMPILER_ID:Clang>:-Weverything>
|
$<$<C_COMPILER_ID:Clang>:-Wall -Wextra -Wpedantic>
|
||||||
)
|
)
|
||||||
target_compile_options(auditor-x86_64 PRIVATE
|
target_compile_options(auditor-x86_64 PRIVATE
|
||||||
-Wno-unused-parameter)
|
-Wno-unused-parameter)
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
cp --verbose "3rd/sc/array/sc_array.h" "src/array/"
|
|
||||||
cp --verbose "3rd/sc/logger/sc_log.c" "src/logger/"
|
|
||||||
cp --verbose "3rd/sc/logger/sc_log.h" "src/logger/"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,224 +0,0 @@
|
|||||||
/*
|
|
||||||
* BSD-3-Clause
|
|
||||||
*
|
|
||||||
* Copyright 2021 Ozan Tezcan
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SC_ARRAY_H
|
|
||||||
#define SC_ARRAY_H
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define SC_ARRAY_VERSION "2.0.0"
|
|
||||||
|
|
||||||
#ifdef SC_HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#else
|
|
||||||
#define sc_array_realloc realloc
|
|
||||||
#define sc_array_free free
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SC_ARRAY_MAX
|
|
||||||
#define SC_ARRAY_MAX SIZE_MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define sc_array_def(T, name) \
|
|
||||||
struct sc_array_##name { \
|
|
||||||
bool oom; \
|
|
||||||
size_t cap; \
|
|
||||||
size_t size; \
|
|
||||||
/* NOLINTNEXTLINE */ \
|
|
||||||
T *elems; \
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Init array
|
|
||||||
* @param a array
|
|
||||||
*/
|
|
||||||
#define sc_array_init(a) \
|
|
||||||
do { \
|
|
||||||
memset((a), 0, sizeof(*(a))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy array
|
|
||||||
* @param a array
|
|
||||||
*/
|
|
||||||
#define sc_array_term(a) \
|
|
||||||
do { \
|
|
||||||
sc_array_free((a)->elems); \
|
|
||||||
sc_array_init(a); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add elem to array, call sc_array_oom(v) to see if 'add' failed because of out
|
|
||||||
* of memory.
|
|
||||||
*
|
|
||||||
* @param a array
|
|
||||||
* @param k elem
|
|
||||||
*/
|
|
||||||
#define sc_array_add(a, k) \
|
|
||||||
do { \
|
|
||||||
const size_t _max = SC_ARRAY_MAX / sizeof(*(a)->elems); \
|
|
||||||
size_t _cap; \
|
|
||||||
void *_p; \
|
|
||||||
\
|
|
||||||
if ((a)->cap == (a)->size) { \
|
|
||||||
if ((a)->cap > _max / 2) { \
|
|
||||||
(a)->oom = true; \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
_cap = (a)->cap == 0 ? 8 : (a)->cap * 2; \
|
|
||||||
_p = sc_array_realloc((a)->elems, \
|
|
||||||
_cap * sizeof(*((a)->elems))); \
|
|
||||||
if (_p == NULL) { \
|
|
||||||
(a)->oom = true; \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
(a)->cap = _cap; \
|
|
||||||
(a)->elems = _p; \
|
|
||||||
} \
|
|
||||||
(a)->oom = false; \
|
|
||||||
(a)->elems[(a)->size++] = k; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes items from the array without deallocating underlying memory
|
|
||||||
* @param a array
|
|
||||||
*/
|
|
||||||
#define sc_array_clear(a) \
|
|
||||||
do { \
|
|
||||||
(a)->size = 0; \
|
|
||||||
(a)->oom = false; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param a array
|
|
||||||
* @return true if last add operation failed, false otherwise.
|
|
||||||
*/
|
|
||||||
#define sc_array_oom(a) ((a)->oom)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get element at index i, if 'i' is out of range, result is undefined.
|
|
||||||
*
|
|
||||||
* @param a array
|
|
||||||
* @param i index
|
|
||||||
* @return element at index 'i'
|
|
||||||
*/
|
|
||||||
#define sc_array_at(a, i) ((a)->elems[i])
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param a array
|
|
||||||
* @return element count
|
|
||||||
*/
|
|
||||||
#define sc_array_size(a) ((a)->size)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param a array
|
|
||||||
* @param i element index, If 'i' is out of the range, result is undefined.
|
|
||||||
*/
|
|
||||||
#define sc_array_del(a, i) \
|
|
||||||
do { \
|
|
||||||
size_t idx = (i); \
|
|
||||||
assert(idx < (a)->size); \
|
|
||||||
\
|
|
||||||
const size_t _cnt = (a)->size - (idx) - 1; \
|
|
||||||
if (_cnt > 0) { \
|
|
||||||
memmove(&((a)->elems[idx]), &((a)->elems[idx + 1]), \
|
|
||||||
_cnt * sizeof(*((a)->elems))); \
|
|
||||||
} \
|
|
||||||
(a)->size--; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the element at index i, replaces last element with the deleted
|
|
||||||
* element unless deleted element is the last element. This is faster than
|
|
||||||
* moving elements but elements will no longer be in the 'add order'
|
|
||||||
*
|
|
||||||
* arr[a,b,c,d,e,f] -> sc_array_del_unordered(arr, 2) - > arr[a,b,f,d,e]
|
|
||||||
*
|
|
||||||
* @param a array
|
|
||||||
* @param i index. If 'i' is out of the range, result is undefined.
|
|
||||||
*/
|
|
||||||
#define sc_array_del_unordered(a, i) \
|
|
||||||
do { \
|
|
||||||
size_t idx = (i); \
|
|
||||||
assert(idx < (a)->size); \
|
|
||||||
(a)->elems[idx] = (a)->elems[(--(a)->size)]; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the last element. If current size is zero, result is undefined.
|
|
||||||
* @param a array
|
|
||||||
*/
|
|
||||||
#define sc_array_del_last(a) \
|
|
||||||
do { \
|
|
||||||
assert((a)->size != 0); \
|
|
||||||
(a)->size--; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts the array using qsort()
|
|
||||||
* @param a array
|
|
||||||
* @param cmp comparator, check qsort() documentation for details
|
|
||||||
*/
|
|
||||||
#define sc_array_sort(a, cmp) \
|
|
||||||
(qsort((a)->elems, (a)->size, sizeof(*(a)->elems), cmp))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns last element. If array is empty, result is undefined.
|
|
||||||
* @param a array
|
|
||||||
*/
|
|
||||||
#define sc_array_last(a) (a)->elems[(a)->size - 1]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param a array
|
|
||||||
* @param elem elem
|
|
||||||
*/
|
|
||||||
#define sc_array_foreach(a, elem) \
|
|
||||||
for (size_t _k = 1, _i = 0; _k && _i != (a)->size; _k = !_k, _i++) \
|
|
||||||
for ((elem) = (a)->elems[_i]; _k; _k = !_k)
|
|
||||||
|
|
||||||
// (type, name)
|
|
||||||
sc_array_def(int, int);
|
|
||||||
sc_array_def(unsigned int, uint);
|
|
||||||
sc_array_def(long, long);
|
|
||||||
sc_array_def(long long, ll);
|
|
||||||
sc_array_def(unsigned long, ulong);
|
|
||||||
sc_array_def(unsigned long long, ull);
|
|
||||||
sc_array_def(uint32_t, 32);
|
|
||||||
sc_array_def(uint64_t, 64);
|
|
||||||
sc_array_def(double, double);
|
|
||||||
sc_array_def(const char *, str);
|
|
||||||
sc_array_def(void *, ptr);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef COMMON_H_
|
#ifndef COMMON_H_
|
||||||
#define COMMON_H_
|
#define COMMON_H_
|
||||||
|
|
||||||
#include "logger/logger.h"
|
#include "logger.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static inline u32 has_mask(u32 flags, u32 mask) { return flags & mask; }
|
static inline u32 has_mask(u32 flags, u32 mask) { return flags & mask; }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
#include "logger/logger.h"
|
#include "logger.h"
|
||||||
#include "string/string.h"
|
#include "histring.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef FILES_H_
|
#pragma once
|
||||||
#define FILES_H_
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
@@ -38,5 +37,3 @@ HiResult file_copy(const char *filename, const char *dest);
|
|||||||
FileType file_type(const char *path);
|
FileType file_type(const char *path);
|
||||||
|
|
||||||
const char *file_name_from_path(const char *path);
|
const char *file_name_from_path(const char *path);
|
||||||
|
|
||||||
#endif // FILES_H_
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef FILEWATCH_H_
|
#ifndef FILEWATCH_H_
|
||||||
#define FILEWATCH_H_
|
#define FILEWATCH_H_
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "vector.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
typedef struct FileWatcherContext FileWatcherContext;
|
typedef struct FileWatcherContext FileWatcherContext;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef FILEWATCH_CONTEXT_H_
|
#ifndef FILEWATCH_CONTEXT_H_
|
||||||
#define FILEWATCH_CONTEXT_H_
|
#define FILEWATCH_CONTEXT_H_
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "vector.h"
|
||||||
#include "filewatcher/filewatch.h"
|
#include "filewatcher/filewatch.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
#include "filewatcher.h"
|
#include "filewatcher.h"
|
||||||
|
|
||||||
|
#include "filewatch.h"
|
||||||
|
#include "filewatch_context.h"
|
||||||
|
#include "filewatch_type.h"
|
||||||
|
|
||||||
|
#include "vector.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "logger.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -10,15 +19,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "array/array.h"
|
|
||||||
#include "array/sc_array.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "filewatch.h"
|
|
||||||
#include "filewatch_context.h"
|
|
||||||
#include "filewatch_type.h"
|
|
||||||
#include "logger/logger.h"
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
sc_array_def(FileEvent, fwevent);
|
sc_array_def(FileEvent, fwevent);
|
||||||
typedef struct sc_array_fwevent VectorFileEvent;
|
typedef struct sc_array_fwevent VectorFileEvent;
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/** Path of the file this event is about. Do not free. */
|
/** Path of the file this event is about. Do not free. */
|
||||||
const char *pathname;
|
const char *pathname;
|
||||||
/** Might not be only those given to @a file_watcher_add. */
|
/** Might contain types not explicitly given to @a file_watcher_add. */
|
||||||
FileWatchType type;
|
FileWatchType type;
|
||||||
} FileEvent;
|
} FileEvent;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "elf.h"
|
#include "hielf.h"
|
||||||
|
|
||||||
#include "logger/logger.h"
|
#include "logger.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#ifndef ELF_H_
|
#ifndef ELF_H_
|
||||||
#define ELF_H_
|
#define ELF_H_
|
||||||
|
|
||||||
// TODO: Move these into .c file after API has found its form
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <libelf.h>
|
#include <libelf.h>
|
||||||
#include <gelf.h>
|
#include <gelf.h>
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
#include "hiload/hiload.h"
|
#include "hiload/hiload.h"
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "vector.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "filewatcher/filewatch_context.h"
|
#include "filewatcher/filewatch_context.h"
|
||||||
#include "filewatcher/filewatcher.h"
|
#include "filewatcher/filewatcher.h"
|
||||||
#include "logger/logger.h"
|
#include "logger.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "moduler/moduler.h"
|
#include "moduler.h"
|
||||||
#include "string/string.h"
|
#include "string.h"
|
||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/**
|
/**
|
||||||
* Concatenate two strings into a buffer.
|
* Concatenate two strings into a buffer.
|
||||||
*
|
*
|
||||||
* If resulting string would be longer than @a buflen - 1, the resulting string
|
* If resulting string would be longer than @a buflen - 1, @a buf remains unchanged.
|
||||||
* in
|
|
||||||
* @a buf is unchanged.
|
|
||||||
*
|
*
|
||||||
|
* @param bufsize Size of the destination buffer @a buf
|
||||||
|
* @param buf The destination buffer
|
||||||
* @param first Null terminated character string
|
* @param first Null terminated character string
|
||||||
* @param second Null terminated character string
|
* @param second Null terminated character string
|
||||||
*/
|
*/
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
#ifndef LOGGER_H_
|
#ifndef LOGGER_H_
|
||||||
#define LOGGER_H_
|
#define LOGGER_H_
|
||||||
|
|
||||||
#include "logger/sc_log.h"
|
#include "../3rd/sc/logger/sc_log.h"
|
||||||
|
|
||||||
|
|
||||||
void log_set_verbose(bool value);
|
void log_set_verbose(bool value);
|
||||||
bool log_get_verbose();
|
bool log_get_verbose();
|
||||||
@@ -1,451 +0,0 @@
|
|||||||
/*
|
|
||||||
* BSD-3-Clause
|
|
||||||
*
|
|
||||||
* Copyright 2021 Ozan Tezcan
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _XOPEN_SOURCE
|
|
||||||
#define _XOPEN_SOURCE 700
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "sc_log.h"
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
#ifndef thread_local
|
|
||||||
#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
|
|
||||||
#define thread_local _Thread_local
|
|
||||||
#elif defined _WIN32 && (defined _MSC_VER || defined __ICL || \
|
|
||||||
defined __DMC__ || defined __BORLANDC__)
|
|
||||||
#define thread_local __declspec(thread)
|
|
||||||
#elif defined __GNUC__ || defined __SUNPRO_C || defined __xlC__
|
|
||||||
#define thread_local __thread
|
|
||||||
#else
|
|
||||||
#error "Cannot define thread_local"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_ATOMIC__
|
|
||||||
#define SC_ATOMIC
|
|
||||||
#include <stdatomic.h>
|
|
||||||
|
|
||||||
#define sc_atomic _Atomic
|
|
||||||
#define sc_atomic_store(var, val) \
|
|
||||||
(atomic_store_explicit(var, val, memory_order_relaxed))
|
|
||||||
#define sc_atomic_load(var) \
|
|
||||||
(atomic_load_explicit(var, memory_order_relaxed))
|
|
||||||
#else
|
|
||||||
#define sc_atomic
|
|
||||||
#define sc_atomic_store(var, val) ((*(var)) = (val))
|
|
||||||
#define sc_atomic_load(var) (*(var))
|
|
||||||
#endif
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
thread_local char sc_name[32] = "Thread";
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable : 4996)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#define localtime_r(a, b) (localtime_s(b, a) == 0 ? b : NULL)
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
struct sc_log_mutex {
|
|
||||||
CRITICAL_SECTION mtx;
|
|
||||||
};
|
|
||||||
|
|
||||||
int sc_log_mutex_init(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
InitializeCriticalSection(&mtx->mtx);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sc_log_mutex_term(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
DeleteCriticalSection(&mtx->mtx);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_mutex_lock(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&mtx->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_mutex_unlock(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
LeaveCriticalSection(&mtx->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
struct sc_log_mutex {
|
|
||||||
pthread_mutex_t mtx;
|
|
||||||
};
|
|
||||||
|
|
||||||
int sc_log_mutex_init(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
pthread_mutexattr_t attr;
|
|
||||||
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
|
|
||||||
mtx->mtx = mut;
|
|
||||||
|
|
||||||
rc = pthread_mutexattr_init(&attr);
|
|
||||||
if (rc != 0) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
|
|
||||||
rc = pthread_mutex_init(&mtx->mtx, &attr);
|
|
||||||
pthread_mutexattr_destroy(&attr);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_mutex_term(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
pthread_mutex_destroy(&mtx->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_mutex_lock(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mtx->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_mutex_unlock(struct sc_log_mutex *mtx)
|
|
||||||
{
|
|
||||||
pthread_mutex_unlock(&mtx->mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct sc_log {
|
|
||||||
FILE *fp;
|
|
||||||
char current_file[256];
|
|
||||||
char prev_file[256];
|
|
||||||
size_t file_size;
|
|
||||||
|
|
||||||
struct sc_log_mutex mtx;
|
|
||||||
sc_atomic enum sc_log_level level;
|
|
||||||
bool init;
|
|
||||||
bool to_stdout;
|
|
||||||
|
|
||||||
void *arg;
|
|
||||||
int (*cb)(void *, enum sc_log_level, const char *, va_list);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sc_log sc_log;
|
|
||||||
|
|
||||||
int sc_log_init(void)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
sc_log = (struct sc_log){0};
|
|
||||||
|
|
||||||
sc_atomic_store(&sc_log.level, SC_LOG_INFO);
|
|
||||||
sc_log.to_stdout = true;
|
|
||||||
|
|
||||||
rc = sc_log_mutex_init(&sc_log.mtx);
|
|
||||||
if (rc != 0) {
|
|
||||||
errno = rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log.init = true;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sc_log_term(void)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
if (!sc_log.init) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc_log.fp) {
|
|
||||||
rc = fclose(sc_log.fp);
|
|
||||||
if (rc != 0) {
|
|
||||||
rc = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log_mutex_term(&sc_log.mtx);
|
|
||||||
sc_log = (struct sc_log){0};
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_set_thread_name(const char *name)
|
|
||||||
{
|
|
||||||
strncpy(sc_name, name, sizeof(sc_name) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sc_strcasecmp(const char *a, const char *b)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
for (;; a++, b++) {
|
|
||||||
if (*a == 0 && *b == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = tolower(*a) - tolower(*b);
|
|
||||||
if (n != 0) {
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sc_log_set_level(const char *str)
|
|
||||||
{
|
|
||||||
size_t count = sizeof(sc_log_levels) / sizeof(sc_log_levels[0]);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
|
||||||
if (sc_strcasecmp(str, sc_log_levels[i].str) == 0) {
|
|
||||||
#ifdef SC_ATOMIC
|
|
||||||
sc_atomic_store(&sc_log.level, sc_log_levels[i].id);
|
|
||||||
#else
|
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
|
||||||
sc_log.level = sc_log_levels[i].id;
|
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_set_stdout(bool enable)
|
|
||||||
{
|
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
|
||||||
sc_log.to_stdout = enable;
|
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sc_log_set_file(const char *prev, const char *current)
|
|
||||||
{
|
|
||||||
int rc = 0, saved_errno = 0;
|
|
||||||
long size;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
|
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
|
||||||
|
|
||||||
if (sc_log.fp != NULL) {
|
|
||||||
fclose(sc_log.fp);
|
|
||||||
sc_log.fp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log.prev_file[0] = '\0';
|
|
||||||
sc_log.current_file[0] = '\0';
|
|
||||||
|
|
||||||
if (prev == NULL || current == NULL) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(prev) >= sizeof(sc_log.prev_file) - 1 ||
|
|
||||||
strlen(current) >= sizeof(sc_log.current_file) - 1) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(sc_log.prev_file, prev, strlen(prev) + 1);
|
|
||||||
memcpy(sc_log.current_file, current, strlen(current) + 1);
|
|
||||||
|
|
||||||
fp = fopen(sc_log.current_file, "a+");
|
|
||||||
if (fp == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fprintf(fp, "\n") < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = ftell(fp);
|
|
||||||
if (size < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log.file_size = (size_t) size;
|
|
||||||
sc_log.fp = fp;
|
|
||||||
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
error:
|
|
||||||
rc = -1;
|
|
||||||
saved_errno = errno;
|
|
||||||
|
|
||||||
if (fp != NULL) {
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
out:
|
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
|
||||||
errno = saved_errno;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sc_log_set_callback(void *arg, int (*cb)(void *, enum sc_log_level,
|
|
||||||
const char *, va_list))
|
|
||||||
{
|
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
|
||||||
sc_log.arg = arg;
|
|
||||||
sc_log.cb = cb;
|
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sc_log_print_header(FILE *fp, enum sc_log_level level)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
time_t t;
|
|
||||||
struct tm result, *tm;
|
|
||||||
|
|
||||||
t = time(NULL);
|
|
||||||
tm = localtime_r(&t, &result);
|
|
||||||
|
|
||||||
if (tm == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = fprintf(fp, "[%d-%02d-%02d %02d:%02d:%02d][%-5s][%s] ",
|
|
||||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
|
||||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
|
||||||
sc_log_levels[level].str, sc_name);
|
|
||||||
if (rc < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sc_log_stdout(enum sc_log_level level, const char *fmt, va_list va)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
FILE *dest = level == SC_LOG_ERROR ? stderr : stdout;
|
|
||||||
|
|
||||||
rc = sc_log_print_header(dest, level);
|
|
||||||
if (rc < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = vfprintf(dest, fmt, va);
|
|
||||||
if (rc < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sc_log_file(enum sc_log_level level, const char *fmt, va_list va)
|
|
||||||
{
|
|
||||||
int rc, size;
|
|
||||||
|
|
||||||
rc = sc_log_print_header(sc_log.fp, level);
|
|
||||||
if (rc < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = vfprintf(sc_log.fp, fmt, va);
|
|
||||||
if (size < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log.file_size += size;
|
|
||||||
|
|
||||||
if (sc_log.file_size > (size_t) SC_LOG_FILE_SIZE) {
|
|
||||||
fclose(sc_log.fp);
|
|
||||||
(void) rename(sc_log.current_file, sc_log.prev_file);
|
|
||||||
|
|
||||||
sc_log.fp = fopen(sc_log.current_file, "w+");
|
|
||||||
if (sc_log.fp == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log.file_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sc_log_log(enum sc_log_level level, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
va_list va;
|
|
||||||
|
|
||||||
// Use relaxed atomics to avoid locking cost, e.g., DEBUG logs when
|
|
||||||
// level=INFO will get away without any synchronization on most
|
|
||||||
// platforms.
|
|
||||||
#ifdef SC_ATOMIC
|
|
||||||
enum sc_log_level curr;
|
|
||||||
|
|
||||||
curr = sc_atomic_load(&sc_log.level);
|
|
||||||
if (level < curr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sc_log_mutex_lock(&sc_log.mtx);
|
|
||||||
|
|
||||||
#ifndef SC_ATOMIC
|
|
||||||
if (level < sc_log.level) {
|
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (sc_log.to_stdout) {
|
|
||||||
va_start(va, fmt);
|
|
||||||
rc |= sc_log_stdout(level, fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc_log.fp != NULL) {
|
|
||||||
va_start(va, fmt);
|
|
||||||
rc |= sc_log_file(level, fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sc_log.cb) {
|
|
||||||
va_start(va, fmt);
|
|
||||||
rc |= sc_log.cb(sc_log.arg, level, fmt, va);
|
|
||||||
va_end(va);
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log_mutex_unlock(&sc_log.mtx);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
* BSD-3-Clause
|
|
||||||
*
|
|
||||||
* Copyright 2021 Ozan Tezcan
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
|
||||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SC_LOG_H
|
|
||||||
#define SC_LOG_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define SC_LOG_VERSION "2.0.0"
|
|
||||||
|
|
||||||
enum sc_log_level
|
|
||||||
{
|
|
||||||
SC_LOG_DEBUG,
|
|
||||||
SC_LOG_INFO,
|
|
||||||
SC_LOG_WARN,
|
|
||||||
SC_LOG_ERROR,
|
|
||||||
SC_LOG_OFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
static const struct sc_log_level_pair
|
|
||||||
{
|
|
||||||
const enum sc_log_level id;
|
|
||||||
const char *str;
|
|
||||||
} sc_log_levels[] = {
|
|
||||||
{SC_LOG_DEBUG, "DEBUG"},
|
|
||||||
{SC_LOG_INFO, "INFO" },
|
|
||||||
{SC_LOG_WARN, "WARN" },
|
|
||||||
{SC_LOG_ERROR, "ERROR"},
|
|
||||||
{SC_LOG_OFF, "OFF" },
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
// Internal function
|
|
||||||
int sc_log_log(enum sc_log_level level, const char *fmt, ...);
|
|
||||||
|
|
||||||
// Max file size to rotate, should not be more than 4 GB.
|
|
||||||
#define SC_LOG_FILE_SIZE (2 * 1024 * 1024)
|
|
||||||
|
|
||||||
// Define SC_LOG_PRINT_FILE_NAME to print file name and line no in the log line.
|
|
||||||
#ifdef SC_LOG_PRINT_FILE_NAME
|
|
||||||
#define sc_log_ap(fmt, ...) \
|
|
||||||
"(%s:%d) " fmt, strrchr("/" __FILE__, '/') + 1, __LINE__, __VA_ARGS__
|
|
||||||
#else
|
|
||||||
#define sc_log_ap(fmt, ...) fmt, __VA_ARGS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sc_log_init() call once in your application before using log functions.
|
|
||||||
* sc_log_term() call once to clean up, you must not use logger after this call.
|
|
||||||
* These functions are not thread-safe, should be called from a single thread.
|
|
||||||
*
|
|
||||||
* @return '0' on success, negative value on error, errno will be set.
|
|
||||||
*/
|
|
||||||
int sc_log_init(void);
|
|
||||||
int sc_log_term(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set thread name.
|
|
||||||
*
|
|
||||||
* Call once from each thread if you want to set thread name.
|
|
||||||
* @param name Thread name
|
|
||||||
*/
|
|
||||||
void sc_log_set_thread_name(const char *name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set log level.
|
|
||||||
*
|
|
||||||
* @param level One of "DEBUG", "INFO", "WARN", "ERROR", "OFF"
|
|
||||||
* @return '0' on success, negative value on invalid level string
|
|
||||||
*/
|
|
||||||
int sc_log_set_level(const char *level);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable stdout logging.
|
|
||||||
*
|
|
||||||
* @param enable 'true' to enable, 'false' to disable logging to stdout.
|
|
||||||
*/
|
|
||||||
void sc_log_set_stdout(bool enable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable file logging.
|
|
||||||
*
|
|
||||||
* Log files will be rotated to prevent generating very big files. Once current
|
|
||||||
* log file reaches 'SC_LOG_FILE_SIZE' (see definition above), it will be
|
|
||||||
* renamed as `prev` and the latest logs will always be in the 'current' file.
|
|
||||||
*
|
|
||||||
* e.g., sc_log_set_file("/tmp/log.0.txt", "/tmp/log-latest.txt");
|
|
||||||
*
|
|
||||||
* To disable logging into file: sc_log_set_file(NULL, NULL);
|
|
||||||
*
|
|
||||||
* @param prev file path for previous log file, 'NULL' to disable
|
|
||||||
* @param current file path for latest log file, 'NULL' to disable
|
|
||||||
* @return 0 on success, -1 on error, errno will be set.
|
|
||||||
*/
|
|
||||||
int sc_log_set_file(const char *prev, const char *current);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enabled logging to callback.
|
|
||||||
*
|
|
||||||
* @param arg user arg to callback.
|
|
||||||
* @param cb log callback.
|
|
||||||
*/
|
|
||||||
void sc_log_set_callback(void *arg,
|
|
||||||
int (*cb)(void *arg, enum sc_log_level level,
|
|
||||||
const char *fmt, va_list va));
|
|
||||||
|
|
||||||
// e.g., sc_log_error("Errno: %d, reason: %s", errno, strerror(errno));
|
|
||||||
#define sc_log_debug(...) (sc_log_log(SC_LOG_DEBUG, sc_log_ap(__VA_ARGS__, "")))
|
|
||||||
#define sc_log_info(...) (sc_log_log(SC_LOG_INFO, sc_log_ap(__VA_ARGS__, "")))
|
|
||||||
#define sc_log_warn(...) (sc_log_log(SC_LOG_WARN, sc_log_ap(__VA_ARGS__, "")))
|
|
||||||
#define sc_log_error(...) (sc_log_log(SC_LOG_ERROR, sc_log_ap(__VA_ARGS__, "")))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include "array/sc_array.h"
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "logger/logger.h"
|
#include "logger.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static inline int ptr_in_range(uptr ptr, uptr start, uptr end) {
|
static inline int ptr_in_range(uptr ptr, uptr start, uptr end) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#ifndef MEMORY_H_
|
#pragma once
|
||||||
#define MEMORY_H_
|
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "vector.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -48,5 +47,3 @@ HiResult memory_find_pointer(uptr ptr,
|
|||||||
|
|
||||||
MemoryRegionSpan memory_get_module_span(const VectorMemoryRegion *const regions,
|
MemoryRegionSpan memory_get_module_span(const VectorMemoryRegion *const regions,
|
||||||
const char module_name[static 1]);
|
const char module_name[static 1]);
|
||||||
|
|
||||||
#endif // MEMORY_H_
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "logger/logger.h"
|
#include "hielf.h"
|
||||||
|
#include "histring.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "moduler/elf.h"
|
|
||||||
#include "string/string.h"
|
|
||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
@@ -135,7 +135,8 @@ static HiResult gather_patchable_symbols(struct sc_array_sym *symbols,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *sym_addr = (void *)((uintptr_t)module_base + sym.st_value);
|
void *sym_addr = (void *)((uintptr_t)module_base + sym.st_value);
|
||||||
SymbolBind binding = symbol_bind_from_efibind(GELF_ST_BIND(sym.st_info));
|
SymbolBind binding =
|
||||||
|
symbol_bind_from_efibind(GELF_ST_BIND(sym.st_info));
|
||||||
SymbolType type = symbol_type_from_efitype(GELF_ST_TYPE(sym.st_info));
|
SymbolType type = symbol_type_from_efitype(GELF_ST_TYPE(sym.st_info));
|
||||||
size_t size = sym.st_size;
|
size_t size = sym.st_size;
|
||||||
|
|
||||||
@@ -273,7 +274,8 @@ PatchData moduler_create_patch(ModuleData *module) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char file_append[32];
|
char file_append[32];
|
||||||
if (strftime(file_append, sizeof(file_append), ".%Y%m%d%H%M%S.patch", t) == 0) {
|
if (strftime(file_append, sizeof(file_append), ".%Y%m%d%H%M%S.patch", t) ==
|
||||||
|
0) {
|
||||||
log_error("Failed to create patch filename.\n");
|
log_error("Failed to create patch filename.\n");
|
||||||
return (PatchData){0};
|
return (PatchData){0};
|
||||||
}
|
}
|
||||||
@@ -282,7 +284,6 @@ PatchData moduler_create_patch(ModuleData *module) {
|
|||||||
size_t written =
|
size_t written =
|
||||||
hi_str_concat_buf(sizeof(filename), filename, module->name, file_append);
|
hi_str_concat_buf(sizeof(filename), filename, module->name, file_append);
|
||||||
|
|
||||||
|
|
||||||
if (written == 0) {
|
if (written == 0) {
|
||||||
log_error("Failed to concat %s and %s\n", module->name, ".patch");
|
log_error("Failed to concat %s and %s\n", module->name, ".patch");
|
||||||
return (PatchData){0};
|
return (PatchData){0};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef MODULER_H_
|
#ifndef MODULER_H_
|
||||||
#define MODULER_H_
|
#define MODULER_H_
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "vector.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "symbols.h"
|
#include "symbols.h"
|
||||||
#include "array/sc_array.h"
|
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#ifndef SYMBOLS_H_
|
#pragma once
|
||||||
#define SYMBOLS_H_
|
|
||||||
|
|
||||||
#include "array/array.h"
|
#include "vector.h"
|
||||||
#include "array/sc_array.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -21,7 +19,8 @@ typedef enum {
|
|||||||
HI_SYMBOL_TYPE_TLS,
|
HI_SYMBOL_TYPE_TLS,
|
||||||
} SymbolType;
|
} SymbolType;
|
||||||
|
|
||||||
typedef struct Symbol {
|
typedef struct Symbol Symbol;
|
||||||
|
struct Symbol {
|
||||||
const char *name;
|
const char *name;
|
||||||
SymbolBind binding;
|
SymbolBind binding;
|
||||||
SymbolType type;
|
SymbolType type;
|
||||||
@@ -29,7 +28,7 @@ typedef struct Symbol {
|
|||||||
void *address;
|
void *address;
|
||||||
void **got_entry;
|
void **got_entry;
|
||||||
void *orig_address;
|
void *orig_address;
|
||||||
} Symbol;
|
};
|
||||||
|
|
||||||
sc_array_def(Symbol, sym);
|
sc_array_def(Symbol, sym);
|
||||||
typedef struct sc_array_sym VectorSymbol;
|
typedef struct sc_array_sym VectorSymbol;
|
||||||
@@ -56,4 +55,3 @@ Symbol *symbol_find(VectorSymbol *symbols, Symbol *symbol);
|
|||||||
SymbolBind symbol_bind_from_efibind(u32 efi_bind);
|
SymbolBind symbol_bind_from_efibind(u32 efi_bind);
|
||||||
SymbolType symbol_type_from_efitype(u32 efi_type);
|
SymbolType symbol_type_from_efitype(u32 efi_type);
|
||||||
|
|
||||||
#endif // SYMBOLS_H_
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#ifndef ARRAY_H_
|
#pragma once
|
||||||
#define ARRAY_H_
|
|
||||||
|
|
||||||
#include "array/sc_array.h"
|
#include "../3rd/sc/array/sc_array.h"
|
||||||
|
|
||||||
typedef struct sc_array_32 VectorU32;
|
typedef struct sc_array_32 VectorU32;
|
||||||
typedef struct sc_array_64 VectorU64;
|
typedef struct sc_array_64 VectorU64;
|
||||||
typedef struct sc_array_double VectorDouble;
|
typedef struct sc_array_double VectorDouble;
|
||||||
typedef struct sc_array_str VectorStr;
|
typedef struct sc_array_str VectorStr;
|
||||||
typedef struct sc_array_ptr VectorPtr;
|
typedef struct sc_array_ptr VectorPtr;
|
||||||
|
|
||||||
#endif // ARRAY_H_
|
|
||||||
Reference in New Issue
Block a user