Support minute and hour as time suffixes
[lttng-tools.git] / src / common / utils.c
index 78bfbef95ede423f4a6c028fbfb0a3886e3c0ea8..a092d940f422979b724fa5a61a72365c54b83ad7 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,21 +321,26 @@ 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) {
                        goto error;
@@ -343,17 +349,23 @@ char *_utils_expand_path(const char *path, bool keep_symlink)
                 * 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;
        }
 
@@ -1092,12 +1104,19 @@ end:
 
 /**
  * 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.
  *
@@ -1112,7 +1131,7 @@ int utils_parse_time_suffix(char const * const str, uint64_t * const time_us)
 {
        int ret;
        uint64_t base_time;
-       long multiplier = 1;
+       uint64_t multiplier = 1;
        const char *str_end;
        char *num_end;
 
@@ -1149,17 +1168,37 @@ int utils_parse_time_suffix(char const * const str, uint64_t * const time_us)
        /* 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':
This page took 0.027101 seconds and 5 git commands to generate.