Fix: Connect timeout arithmetic in inet/inet6 (v4)
[lttng-tools.git] / src / common / utils.c
index 84d42f4638e53f37fc139c4b1c6d5d6b1c30b375..08139e5e2cb23d691c92c6800cef841e2362bc57 100644 (file)
@@ -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;
 }
 
 /*
@@ -310,9 +310,10 @@ error:
 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) {
@@ -320,41 +321,51 @@ char *_utils_expand_path(const char *path, bool keep_symlink)
        }
 
        /* 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;
        }
 
@@ -1635,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;
+}
This page took 0.024741 seconds and 4 git commands to generate.