* SOFTWARE.
*/
+#define BT_LOG_TAG "COMMON"
+#include "logging.h"
+
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
#include <ctype.h>
#include <glib.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <babeltrace/babeltrace-internal.h>
#include <babeltrace/common-internal.h>
#include <babeltrace/compat/unistd-internal.h>
char *bt_secure_getenv(const char *name)
{
if (bt_common_is_setuid_setgid()) {
- printf_error("Disregarding %s environment variable for setuid/setgid binary",
- name);
+ BT_LOGD("Disregarding environment variable for setuid/setgid binary: "
+ "name=\"%s\"", name);
return NULL;
}
return getenv(name);
{
char *path = NULL;
const char *home_dir;
+ size_t length;
home_dir = bt_get_home_dir();
if (!home_dir) {
goto end;
}
- if (strlen(home_dir) + strlen(HOME_PLUGIN_SUBPATH) + 1 >= PATH_MAX) {
- printf_error("Home directory path is too long: `%s`\n",
- home_dir);
+ length = strlen(home_dir) + strlen(HOME_PLUGIN_SUBPATH) + 1;
+
+ if (length >= PATH_MAX) {
+ BT_LOGW("Home directory path is too long: length=%zu",
+ length);
goto end;
}
while (at < end) {
GString *path;
- const char *next_colon;
+ const char *next_sep;
- next_colon = strchr(at, ':');
- if (next_colon == at) {
+ next_sep = strchr(at, G_SEARCHPATH_SEPARATOR);
+ if (next_sep == at) {
/*
* Empty path: try next character (supported
* to conform to the typical parsing of $PATH).
*/
at++;
continue;
- } else if (!next_colon) {
- /* No more colon: use the remaining */
- next_colon = paths + strlen(paths);
+ } else if (!next_sep) {
+ /* No more separator: use the remaining */
+ next_sep = paths + strlen(paths);
}
path = g_string_new(NULL);
goto error;
}
- g_string_append_len(path, at, next_colon - at);
- at = next_colon + 1;
+ g_string_append_len(path, at, next_sep - at);
+ at = next_sep + 1;
g_ptr_array_add(dirs, path);
}
return ret;
}
+static
+bool isarealtty(int fd)
+{
+ bool istty = false;
+ struct stat tty_stats;
+
+ if (!isatty(fd)) {
+ /* Not a TTY */
+ goto end;
+ }
+
+ if (fstat(fd, &tty_stats) == 0) {
+ if (!S_ISCHR(tty_stats.st_mode)) {
+ /* Not a character device: not a TTY */
+ goto end;
+ }
+ }
+
+ istty = true;
+
+end:
+ return istty;
+}
+
BT_HIDDEN
bool bt_common_colors_supported(void)
{
static bool supports_colors = false;
static bool supports_colors_set = false;
- const char *term;
- const char *force;
+ const char *term_env_var;
+ const char *term_color_env_var;
if (supports_colors_set) {
goto end;
supports_colors_set = true;
- force = getenv("BABELTRACE_FORCE_COLORS");
- if (force && strcmp(force, "1") == 0) {
- supports_colors = true;
- goto end;
+ /*
+ * `BABELTRACE_TERM_COLOR` environment variable always overrides
+ * the automatic color support detection.
+ */
+ term_color_env_var = getenv("BABELTRACE_TERM_COLOR");
+ if (term_color_env_var) {
+ if (g_ascii_strcasecmp(term_color_env_var, "always") == 0) {
+ /* Force colors */
+ supports_colors = true;
+ } else if (g_ascii_strcasecmp(term_color_env_var, "never") == 0) {
+ /* Force no colors */
+ goto end;
+ }
}
- term = getenv("TERM");
- if (!term) {
+ /* We need a compatible, known terminal */
+ term_env_var = getenv("TERM");
+ if (!term_env_var) {
goto end;
}
- if (strncmp(term, "xterm", 5) != 0 &&
- strncmp(term, "rxvt", 4) != 0 &&
- strncmp(term, "konsole", 7) != 0 &&
- strncmp(term, "gnome", 5) != 0 &&
- strncmp(term, "screen", 5) != 0 &&
- strncmp(term, "tmux", 4) != 0 &&
- strncmp(term, "putty", 5) != 0) {
+ if (strncmp(term_env_var, "xterm", 5) != 0 &&
+ strncmp(term_env_var, "rxvt", 4) != 0 &&
+ strncmp(term_env_var, "konsole", 7) != 0 &&
+ strncmp(term_env_var, "gnome", 5) != 0 &&
+ strncmp(term_env_var, "screen", 5) != 0 &&
+ strncmp(term_env_var, "tmux", 4) != 0 &&
+ strncmp(term_env_var, "putty", 5) != 0) {
goto end;
}
- if (!isatty(1)) {
+ /* Both standard output and error streams need to be TTYs */
+ if (!isarealtty(STDOUT_FILENO) || !isarealtty(STDERR_FILENO)) {
goto end;
}
(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;
+
+ 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)
{
return norm_path;
}
+#endif
BT_HIDDEN
size_t bt_common_get_page_size(void)
page_size = bt_sysconf(_SC_PAGESIZE);
if (page_size < 0) {
- printf_error("Cannot get system page size.");
+ BT_LOGF("Cannot get system's page size: ret=%d",
+ page_size);
abort();
}