X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcommon%2Fcommon.c;h=c8890cd2cab5748690d8951fb4fea9aab3ce795d;hb=87c882849d73c8567c517d630d4fba6d48b555cb;hp=4aa8fcd2a70e3ec9a890182fbf7f89350c97936f;hpb=ae83436ea714ed6a8a97c54f8128ab6b63ed557d;p=babeltrace.git diff --git a/src/common/common.c b/src/common/common.c index 4aa8fcd2..c8890cd2 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -22,8 +22,9 @@ * SOFTWARE. */ +#define BT_LOG_OUTPUT_LEVEL log_level #define BT_LOG_TAG "COMMON" -#include "logging.h" +#include "logging/log.h" #include #include @@ -45,9 +46,10 @@ #ifndef __MINGW32__ #include +#include #endif -#define SYSTEM_PLUGIN_PATH INSTALL_LIBDIR "/babeltrace2/plugins" +#define SYSTEM_PLUGIN_PATH BABELTRACE_PLUGINS_DIR #define HOME_ENV_VAR "HOME" #define HOME_PLUGIN_SUBPATH "/.local/lib/babeltrace2/plugins" @@ -115,8 +117,15 @@ bool bt_common_is_setuid_setgid(void) } #endif /* __MINGW32__ */ +#ifdef __MINGW32__ +static +const char *bt_get_home_dir(int log_level) +{ + return g_get_home_dir(); +} +#else /* __MINGW32__ */ static -char *bt_secure_getenv(const char *name) +char *bt_secure_getenv(const char *name, int log_level) { if (bt_common_is_setuid_setgid()) { BT_LOGD("Disregarding environment variable for setuid/setgid binary: " @@ -126,20 +135,13 @@ char *bt_secure_getenv(const char *name) return getenv(name); } -#ifdef __MINGW32__ -static -const char *bt_get_home_dir(void) -{ - return g_get_home_dir(); -} -#else /* __MINGW32__ */ static -const char *bt_get_home_dir(void) +const char *bt_get_home_dir(int log_level) { char *val = NULL; struct passwd *pwd; - val = bt_secure_getenv(HOME_ENV_VAR); + val = bt_secure_getenv(HOME_ENV_VAR, log_level); if (val) { goto end; } @@ -155,13 +157,13 @@ end: #endif /* __MINGW32__ */ BT_HIDDEN -char *bt_common_get_home_plugin_path(void) +char *bt_common_get_home_plugin_path(int log_level) { char *path = NULL; const char *home_dir; size_t length; - home_dir = bt_get_home_dir(); + home_dir = bt_get_home_dir(log_level); if (!home_dir) { goto end; } @@ -169,8 +171,8 @@ char *bt_common_get_home_plugin_path(void) length = strlen(home_dir) + strlen(HOME_PLUGIN_SUBPATH) + 1; if (length >= PATH_MAX) { - BT_LOGW("Home directory path is too long: length=%zu", - length); + BT_LOGW("Home directory path is too long: " + "length=%zu, max-length=%u", length, PATH_MAX); goto end; } @@ -510,6 +512,7 @@ set_end_pos: error: if (output) { g_string_free(output, TRUE); + output = NULL; } end: @@ -670,7 +673,7 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( at += end_pos; - /* :// */ + /* `://` */ if (strncmp(at, "://", 3) != 0) { if (error_buf) { snprintf(error_buf, error_buf_size, @@ -680,6 +683,7 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( goto error; } + /* Skip `://` */ at += 3; /* Hostname */ @@ -729,12 +733,13 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( } if (at[end_pos] == '\0') { + /* Relay daemon hostname and ports provided only */ goto end; } at += end_pos; - /* /host/ */ + /* `/host/` */ if (strncmp(at, "/host/", 6) != 0) { if (error_buf) { snprintf(error_buf, error_buf_size, @@ -758,9 +763,16 @@ struct bt_common_lttng_live_url_parts bt_common_parse_lttng_live_url( } if (at[end_pos] == '\0') { - goto end; + if (error_buf) { + snprintf(error_buf, error_buf_size, + "Missing `/` after target hostname (`%s`)", + parts.target_hostname->str); + } + + goto error; } + /* Skip `/` */ at += end_pos + 1; /* Session name */ @@ -1087,6 +1099,36 @@ end_of_pattern: return p[-1] == '*' && at_end_of_pattern(p, pattern, pattern_len); } +#ifdef __MINGW32__ +BT_HIDDEN +GString *bt_common_normalize_path(const char *path, const char *wd) +{ + char *tmp; + GString *norm_path = NULL; + + BT_ASSERT(path); + + tmp = _fullpath(NULL, path, PATH_MAX); + if (!tmp) { + goto error; + } + + norm_path = g_string_new(tmp); + if (!norm_path) { + goto error; + } + + goto end; +error: + if (norm_path) { + g_string_free(norm_path, TRUE); + norm_path = NULL; + } +end: + free(tmp); + return norm_path; +} +#else static void append_path_parts(const char *path, GPtrArray *parts) { @@ -1120,38 +1162,6 @@ void destroy_gstring(void *gstring) (void) g_string_free(gstring, TRUE); } -#ifdef __MINGW32__ -BT_HIDDEN -GString *bt_common_normalize_path(const char *path, const char *wd) -{ - char *tmp; - GString *norm_path = NULL; - - BT_ASSERT(path); - - tmp = _fullpath(NULL, path, PATH_MAX); - if (!tmp) { - goto error; - } - - norm_path = g_string_new(tmp); - if (!norm_path) { - goto error; - } - - goto end; -error: - if (norm_path) { - g_string_free(norm_path, TRUE); - norm_path = NULL; - } -end: - if (tmp) { - free(tmp); - } - return norm_path; -} -#else BT_HIDDEN GString *bt_common_normalize_path(const char *path, const char *wd) { @@ -1238,7 +1248,7 @@ end: #endif BT_HIDDEN -size_t bt_common_get_page_size(void) +size_t bt_common_get_page_size(int log_level) { int page_size; @@ -1670,3 +1680,226 @@ void bt_common_sep_digits(char *str, unsigned int digits_per_group, char sep) i++; } } + +BT_HIDDEN +GString *bt_common_fold(const char *str, unsigned int total_length, + unsigned int indent) +{ + const unsigned int content_length = total_length - indent; + GString *folded = g_string_new(NULL); + GString *tmp_line = g_string_new(NULL); + gchar **lines = NULL; + gchar **line_words = NULL; + gchar * const *line; + unsigned int i; + + BT_ASSERT(str); + BT_ASSERT(indent < total_length); + BT_ASSERT(tmp_line); + BT_ASSERT(folded); + + if (strlen(str) == 0) { + /* Empty input string: empty output string */ + goto end; + } + + /* Split lines */ + lines = g_strsplit(str, "\n", 0); + BT_ASSERT(lines); + + /* For each source line */ + for (line = lines; *line; line++) { + gchar * const *word; + + /* + * Append empty line without indenting if source line is + * empty. + */ + if (strlen(*line) == 0) { + g_string_append_c(folded, '\n'); + continue; + } + + /* Split words */ + line_words = g_strsplit(*line, " ", 0); + BT_ASSERT(line_words); + + /* + * Indent for first line (we know there's at least one + * word at this point). + */ + for (i = 0; i < indent; i++) { + g_string_append_c(folded, ' '); + } + + /* Append words, folding when necessary */ + g_string_assign(tmp_line, ""); + + for (word = line_words; *word; word++) { + /* + * `tmp_line->len > 0` is in the condition so + * that words that are larger than + * `content_length` are at least written on + * their own line. + * + * `tmp_line->len - 1` because the temporary + * line always contains a trailing space which + * won't be part of the line if we fold. + */ + if (tmp_line->len > 0 && + tmp_line->len - 1 + strlen(*word) >= content_length) { + /* Fold (without trailing space) */ + g_string_append_len(folded, + tmp_line->str, tmp_line->len - 1); + g_string_append_c(folded, '\n'); + + /* Indent new line */ + for (i = 0; i < indent; i++) { + g_string_append_c(folded, ' '); + } + + g_string_assign(tmp_line, ""); + } + + /* Append current word and space to temporary line */ + g_string_append(tmp_line, *word); + g_string_append_c(tmp_line, ' '); + } + + /* Append last line if any, without trailing space */ + if (tmp_line->len > 0) { + g_string_append_len(folded, tmp_line->str, + tmp_line->len - 1); + } + + /* Append source newline */ + g_string_append_c(folded, '\n'); + + /* Free array of this line's words */ + g_strfreev(line_words); + line_words = NULL; + } + + /* Remove trailing newline if any */ + if (folded->str[folded->len - 1] == '\n') { + g_string_truncate(folded, folded->len - 1); + } + +end: + if (lines) { + g_strfreev(lines); + } + + BT_ASSERT(!line_words); + + if (tmp_line) { + g_string_free(tmp_line, TRUE); + } + + return folded; +} + +#ifdef __MINGW32__ +BT_HIDDEN +int bt_common_get_term_size(unsigned int *width, unsigned int *height) +{ + /* Not supported on Windows yet */ + return -1; +} +#else /* __MINGW32__ */ +BT_HIDDEN +int bt_common_get_term_size(unsigned int *width, unsigned int *height) +{ + int ret = 0; + struct winsize winsize; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) < 0) { + ret = -1; + goto end; + } + + if (width) { + *width = (unsigned int) winsize.ws_col; + } + + if (height) { + *height = (unsigned int) winsize.ws_row; + } + +end: + return ret; +} +#endif /* __MINGW32__ */ + +BT_HIDDEN +int bt_common_g_string_append_printf(GString *str, const char *fmt, ...) +{ + va_list ap; + gsize len, allocated_len, available_len; + int print_len; + + /* str->len excludes \0. */ + len = str->len; + /* Explicitly exclude \0. */ + allocated_len = str->allocated_len - 1; + available_len = allocated_len - len; + + str->len = allocated_len; + va_start(ap, fmt); + print_len = vsnprintf(str->str + len, available_len + 1, fmt, ap); + va_end(ap); + if (print_len < 0) { + return print_len; + } + if (G_UNLIKELY(available_len < print_len)) { + /* Resize. */ + g_string_set_size(str, len + print_len); + va_start(ap, fmt); + print_len = vsprintf(str->str + len, fmt, ap); + va_end(ap); + } else { + str->len = len + print_len; + } + return print_len; +} + +BT_HIDDEN +int bt_common_append_file_content_to_g_string(GString *str, FILE *fp) +{ + const size_t chunk_size = 4096; + int ret = 0; + char *buf; + size_t read_len; + gsize orig_len = str->len; + + BT_ASSERT(str); + BT_ASSERT(fp); + buf = g_malloc(chunk_size); + if (!buf) { + ret = -1; + goto end; + } + + while (true) { + if (ferror(fp)) { + ret = -1; + goto end; + } + + if (feof(fp)) { + break; + } + + read_len = fread(buf, 1, chunk_size, fp); + g_string_append_len(str, buf, read_len); + } + +end: + if (ret) { + /* Remove what was appended */ + g_string_truncate(str, orig_len); + } + + g_free(buf); + return ret; +}