Export utils_stream_file_path outside of common/utils.c
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 10 May 2019 16:41:26 +0000 (12:41 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 25 Jul 2019 19:45:26 +0000 (15:45 -0400)
utils_stream_file_name is used by the stream file creation and
unlinking utilities. Those utilities perform actions that
will be performed on a trace chunk in a future commit.

Making this util public allows the reuse of most of the code
of the utilities.

The function is renamed from utils_stream_file_name to
utils_stream_file_path since it returns a path and not a
name.

The function's output parameter is moved to the end of the argument
list to honor the convention used in most of the code base. A length
parameter is added rather than relying on an implicit assumption
that the buffer's length is >= PATH_MAX.

The existing callers' buffer size is changed from PATH_MAX to
the preferred LTTNG_PATH_MAX.

The implementation of the function has been reworked to eliminate
a number of unncessary copies and allocations. It is now simpler,
handles path truncations, and does not duplicate the path separator
if it is already contained in `path_name`.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/common/string-utils/Makefile.am
src/common/string-utils/format.h [new file with mode: 0644]
src/common/utils.c
src/common/utils.h

index 1910042d649df3cdbff9f345a64376e21a41977a..90c08316b5dd4bc777cb1cb143518d8486b12be6 100644 (file)
@@ -1,3 +1,3 @@
 noinst_LTLIBRARIES = libstring-utils.la
 
-libstring_utils_la_SOURCES = string-utils.h string-utils.c
+libstring_utils_la_SOURCES = string-utils.h string-utils.c format.h
diff --git a/src/common/string-utils/format.h b/src/common/string-utils/format.h
new file mode 100644 (file)
index 0000000..99f775c
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _STRING_UTILS_FORMAT_H
+#define _STRING_UTILS_FORMAT_H
+
+/*
+ * Maximal length of `val` when formatted in decimal.
+ *
+ * Note that this is an upper bound that can exceed the length
+ * required to hold the largest textual value of `val`. Note that this length
+ * assumes that no grouping/locale-aware formatting is performed (i.e. using
+ * the `'` specifier in POSIX formatting functions).
+ */
+#define MAX_INT_DEC_LEN(val)       ((3 * sizeof(val)) + 2)
+
+#endif /* _STRING_UTILS_FORMAT_H */
index a91ede65c84af5d5c1d01797dc5766ee7e16057b..2f132a0603c8d9891d1280ef1912709b3b3c9013 100644 (file)
@@ -40,6 +40,7 @@
 #include <common/compat/dirent.h>
 #include <common/compat/directory-handle.h>
 #include <common/dynamic-buffer.h>
+#include <common/string-utils/format.h>
 #include <lttng/constant.h>
 
 #include "utils.h"
@@ -725,66 +726,42 @@ end:
 }
 
 /*
- * path is the output parameter. It needs to be PATH_MAX len.
+ * out_stream_path is the output parameter.
  *
  * Return 0 on success or else a negative value.
  */
-static int utils_stream_file_name(char *path,
-               const char *path_name, const char *file_name,
-               uint64_t size, uint64_t count,
-               const char *suffix)
+LTTNG_HIDDEN
+int utils_stream_file_path(const char *path_name, const char *file_name,
+               uint64_t size, uint64_t count, const char *suffix,
+               char *out_stream_path, size_t stream_path_len)
 {
        int ret;
-       char full_path[PATH_MAX];
-       char *path_name_suffix = NULL;
-       char *extra = NULL;
+        char count_str[MAX_INT_DEC_LEN(count) + 1] = {};
+       const char *path_separator;
 
-       ret = snprintf(full_path, sizeof(full_path), "%s/%s",
-                       path_name, file_name);
-       if (ret < 0) {
-               PERROR("snprintf create output file");
-               goto error;
+       if (path_name && path_name[strlen(path_name) - 1] == '/') {
+               path_separator = "";
+       } else {
+               path_separator = "/";
        }
 
-       /* Setup extra string if suffix or/and a count is needed. */
-       if (size > 0 && suffix) {
-               ret = asprintf(&extra, "_%" PRIu64 "%s", count, suffix);
-       } else if (size > 0) {
-               ret = asprintf(&extra, "_%" PRIu64, count);
-       } else if (suffix) {
-               ret = asprintf(&extra, "%s", suffix);
-       }
-       if (ret < 0) {
-               PERROR("Allocating extra string to name");
-               goto error;
+       path_name = path_name ? : "";
+       suffix = suffix ? : "";
+       if (size > 0) {
+               ret = snprintf(count_str, sizeof(count_str), "_%" PRIu64,
+                               count);
+               assert(ret > 0 && ret < sizeof(count_str));
        }
 
-       /*
-        * If we split the trace in multiple files, we have to add the count at
-        * the end of the tracefile name.
-        */
-       if (extra) {
-               ret = asprintf(&path_name_suffix, "%s%s", full_path, extra);
-               if (ret < 0) {
-                       PERROR("Allocating path name with extra string");
-                       goto error_free_suffix;
-               }
-               strncpy(path, path_name_suffix, PATH_MAX - 1);
-               path[PATH_MAX - 1] = '\0';
+        ret = snprintf(out_stream_path, stream_path_len, "%s%s%s%s%s",
+                       path_name, path_separator, file_name, count_str,
+                       suffix);
+       if (ret < 0 || ret >= stream_path_len) {
+               ERR("Truncation occurred while formatting stream path");
+               ret = -1;
        } else {
-               ret = lttng_strncpy(path, full_path, PATH_MAX);
-               if (ret) {
-                       ERR("Failed to copy stream file name");
-                       goto error_free_suffix;
-               }
+               ret = 0;
        }
-       path[PATH_MAX - 1] = '\0';
-       ret = 0;
-
-       free(path_name_suffix);
-error_free_suffix:
-       free(extra);
-error:
        return ret;
 }
 
@@ -798,10 +775,10 @@ int utils_create_stream_file(const char *path_name, char *file_name, uint64_t si
                uint64_t count, int uid, int gid, char *suffix)
 {
        int ret, flags, mode;
-       char path[PATH_MAX];
+       char path[LTTNG_PATH_MAX];
 
-       ret = utils_stream_file_name(path, path_name, file_name,
-                       size, count, suffix);
+       ret = utils_stream_file_path(path_name, file_name,
+                       size, count, suffix, path, sizeof(path));
        if (ret < 0) {
                goto error;
        }
@@ -836,10 +813,10 @@ int utils_unlink_stream_file(const char *path_name, char *file_name, uint64_t si
                uint64_t count, int uid, int gid, char *suffix)
 {
        int ret;
-       char path[PATH_MAX];
+       char path[LTTNG_PATH_MAX];
 
-       ret = utils_stream_file_name(path, path_name, file_name,
-                       size, count, suffix);
+       ret = utils_stream_file_path(path_name, file_name, size, count, suffix,
+                       path, sizeof(path));
        if (ret < 0) {
                goto error;
        }
index 5f95d4aab8db1456291ccdc166331dc93a3a0285..ef02c275914bbd25ecec7cb350c8af05e19b5fff 100644 (file)
@@ -51,6 +51,9 @@ int utils_unlink_stream_file(const char *path_name, char *file_name, uint64_t si
 int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size,
                uint64_t count, int uid, int gid, int out_fd, uint64_t *new_count,
                int *stream_fd);
+int utils_stream_file_path(const char *path_name, const char *file_name,
+               uint64_t size, uint64_t count, const char *suffix,
+               char *out_stream_path, size_t stream_path_len);
 int utils_parse_size_suffix(char const * const str, uint64_t * const size);
 int utils_parse_time_suffix(char const * const str, uint64_t * const time_us);
 int utils_get_count_order_u32(uint32_t x);
This page took 0.029942 seconds and 5 git commands to generate.