X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fcommon%2Futils.c;h=08139e5e2cb23d691c92c6800cef841e2362bc57;hb=c7031a2c707646804e0088d069578d5eb74fc01e;hp=3f74e1fae3c21487e71e8a6aeec3be1a38558677;hpb=857f0d94259cbe44649a16a8c098658352b97fa9;p=lttng-tools.git diff --git a/src/common/utils.c b/src/common/utils.c index 3f74e1fae..08139e5e2 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -41,6 +41,7 @@ #include "utils.h" #include "defaults.h" +#include "time.h" /* * Return a partial realpath(3) of the path even if the full path does not @@ -197,7 +198,7 @@ error: } 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; @@ -206,7 +207,6 @@ char *expand_double_slashes_dot_and_dotdot(char *path) path_last_char = &path[path_len]; if (path_len == 0) { - path = NULL; goto error; } @@ -292,9 +292,9 @@ char *expand_double_slashes_dot_and_dotdot(char *path) } path[expanded_path_len] = '\0'; - + return 0; error: - return path; + return -1; } /* @@ -313,7 +313,7 @@ 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) { @@ -364,8 +364,8 @@ char *_utils_expand_path(const char *path, bool keep_symlink) 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; } @@ -1646,3 +1646,38 @@ int utils_show_help(int section, const char *page_name, 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; +}