#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) {
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;
}
end:
return ret;
}
+
+LTTNG_HIDDEN
+int timespec_to_ms(struct timespec ts, unsigned long *ms)
+{
+ unsigned long res, remain_ms;
+
+ if (ts.tv_sec > ULONG_MAX / MSEC_PER_SEC) {
+ errno = EOVERFLOW;
+ return -1; /* multiplication overflow */
+ }
+ res = ts.tv_sec * MSEC_PER_SEC;
+ remain_ms = ULONG_MAX - res;
+ if (ts.tv_nsec / NSEC_PER_MSEC > remain_ms) {
+ errno = EOVERFLOW;
+ return -1; /* addition overflow */
+ }
+ res += ts.tv_nsec / NSEC_PER_MSEC;
+ *ms = res;
+ return 0;
+}
+
+LTTNG_HIDDEN
+struct timespec timespec_abs_diff(struct timespec t1, struct timespec t2)
+{
+ uint64_t ts1 = (uint64_t) t1.tv_sec * (uint64_t) NSEC_PER_SEC +
+ (uint64_t) t1.tv_nsec;
+ uint64_t ts2 = (uint64_t) t2.tv_sec * (uint64_t) NSEC_PER_SEC +
+ (uint64_t) t2.tv_nsec;
+ uint64_t diff = max(ts1, ts2) - min(ts1, ts2);
+ struct timespec res;
+
+ res.tv_sec = diff / (uint64_t) NSEC_PER_SEC;
+ res.tv_nsec = diff % (uint64_t) NSEC_PER_SEC;
+ return res;
+}