#include "utils.h"
#include "defaults.h"
+#include "time.h"
/*
* Return a partial realpath(3) of the path even if the full path does not
}
static
-char *expand_double_slashes_dot_and_dotdot(char *path)
+int expand_double_slashes_dot_and_dotdot(char *path)
{
size_t expanded_path_len, path_len;
const char *curr_char, *path_last_char, *next_slash, *prev_slash;
path_last_char = &path[path_len];
if (path_len == 0) {
- path = NULL;
goto error;
}
}
path[expanded_path_len] = '\0';
-
+ return 0;
error:
- return path;
+ return -1;
}
/*
LTTNG_HIDDEN
char *_utils_expand_path(const char *path, bool keep_symlink)
{
+ int ret;
char *absolute_path = NULL;
char *last_token;
- int is_dot, is_dotdot;
+ bool is_dot, is_dotdot;
/* Safety net */
if (path == NULL) {
}
/* Allocate memory for the absolute_path */
- absolute_path = zmalloc(PATH_MAX);
+ absolute_path = zmalloc(LTTNG_PATH_MAX);
if (absolute_path == NULL) {
PERROR("zmalloc expand path");
goto error;
}
if (path[0] == '/') {
- strncpy(absolute_path, path, PATH_MAX);
+ ret = lttng_strncpy(absolute_path, path, LTTNG_PATH_MAX);
+ if (ret) {
+ ERR("Path exceeds maximal size of %i bytes", LTTNG_PATH_MAX);
+ goto error;
+ }
} else {
/*
* This is a relative path. We need to get the present working
* directory and start the path walk from there.
*/
- char current_working_dir[PATH_MAX];
+ char current_working_dir[LTTNG_PATH_MAX];
char *cwd_ret;
+
cwd_ret = getcwd(current_working_dir, sizeof(current_working_dir));
if (!cwd_ret) {
- absolute_path = NULL;
goto error;
}
/*
* Get the number of character in the CWD and allocate an array
* to can hold it and the path provided by the caller.
*/
- snprintf(absolute_path, PATH_MAX, "%s/%s", current_working_dir, path);
+ ret = snprintf(absolute_path, LTTNG_PATH_MAX, "%s/%s",
+ current_working_dir, path);
+ if (ret >= LTTNG_PATH_MAX) {
+ ERR("Concatenating current working directory %s and path %s exceeds maximal size of %i bytes",
+ current_working_dir, path, LTTNG_PATH_MAX);
+ goto error;
+ }
}
if (keep_symlink) {
/* Resolve partially our path */
absolute_path = utils_partial_realpath(absolute_path,
- absolute_path, PATH_MAX);
+ absolute_path, LTTNG_PATH_MAX);
}
- absolute_path = expand_double_slashes_dot_and_dotdot(absolute_path);
- if (!absolute_path) {
+ ret = expand_double_slashes_dot_and_dotdot(absolute_path);
+ if (ret) {
goto error;
}
/**
* Parse a string that represents a time in human readable format. It
- * supports decimal integers suffixed by 's', 'u', 'm', 'us', and 'ms'.
+ * supports decimal integers suffixed by:
+ * "us" for microsecond,
+ * "ms" for millisecond,
+ * "s" for second,
+ * "m" for minute,
+ * "h" for hour
*
* The suffix multiply the integer by:
- * 'u'/'us': 1
- * 'm'/'ms': 1000
- * 's': 1000000
+ * "us" : 1
+ * "ms" : 1000
+ * "s" : 1000000
+ * "m" : 60000000
+ * "h" : 3600000000
*
* Note that unit-less numbers are assumed to be microseconds.
*
{
int ret;
uint64_t base_time;
- long multiplier = 1;
+ uint64_t multiplier = 1;
const char *str_end;
char *num_end;
/* Check if a prefix is present. */
switch (*num_end) {
case 'u':
- multiplier = 1;
- /* Skip another letter in the 'us' case. */
- num_end += (*(num_end + 1) == 's') ? 2 : 1;
+ /*
+ * Microsecond (us)
+ *
+ * Skip the "us" if the string matches the "us" suffix,
+ * otherwise let the check for the end of the string handle
+ * the error reporting.
+ */
+ if (*(num_end + 1) == 's') {
+ num_end += 2;
+ }
break;
case 'm':
- multiplier = 1000;
- /* Skip another letter in the 'ms' case. */
- num_end += (*(num_end + 1) == 's') ? 2 : 1;
+ if (*(num_end + 1) == 's') {
+ /* Millisecond (ms) */
+ multiplier = USEC_PER_MSEC;
+ /* Skip the 's' */
+ num_end++;
+ } else {
+ /* Minute (m) */
+ multiplier = USEC_PER_MINUTE;
+ }
+ num_end++;
break;
case 's':
- multiplier = 1000000;
+ /* Second */
+ multiplier = USEC_PER_SEC;
+ num_end++;
+ break;
+ case 'h':
+ /* Hour */
+ multiplier = USEC_PER_HOURS;
num_end++;
break;
case '\0':