+ /*
+ * If we were able to solve at least partially the path, we can concatenate
+ * what worked and what didn't work
+ */
+ if (try_path_prev != NULL) {
+ /* If we risk to concatenate two '/', we remove one of them */
+ if (try_path_prev[strlen(try_path_prev) - 1] == '/' && prev[0] == '/') {
+ try_path_prev[strlen(try_path_prev) - 1] = '\0';
+ }
+
+ /*
+ * Duplicate the memory used by prev in case resolved_path and
+ * path are pointers for the same memory space
+ */
+ cut_path = strdup(prev);
+
+ /* Concatenate the strings */
+ snprintf(resolved_path, size, "%s%s", try_path_prev, cut_path);
+
+ /* Free the allocated memory */
+ free(cut_path);
+ free(try_path_prev);
+ /*
+ * Else, we just copy the path in our resolved_path to
+ * return it as is
+ */
+ } else {
+ strncpy(resolved_path, path, size);
+ }
+
+ /* Then we return the 'partially' resolved path */
+ return resolved_path;
+
+error:
+ free(resolved_path);
+ return NULL;
+}
+
+/*
+ * Make a full resolution of the given path even if it doesn't exist.
+ * This function uses the utils_partial_realpath function to resolve
+ * symlinks and relatives paths at the start of the string, and
+ * implements functionnalities to resolve the './' and '../' strings
+ * in the middle of a path. This function is only necessary because
+ * realpath(3) does not accept to resolve unexistent paths.
+ * The returned string was allocated in the function, it is thus of
+ * the responsibility of the caller to free this memory.
+ */
+LTTNG_HIDDEN
+char *utils_expand_path(const char *path)
+{
+ char *next, *previous, *slash, *start_path, *absolute_path = NULL;
+ char *last_token;
+ int is_dot, is_dotdot;
+
+ /* Safety net */
+ if (path == NULL) {
+ goto error;
+ }
+
+ /* Allocate memory for the absolute_path */
+ absolute_path = zmalloc(PATH_MAX);
+ if (absolute_path == NULL) {