From 40804255e7a6acd6fa76c41ee8e4e1cc2cefa49c Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 10 May 2019 12:41:26 -0400 Subject: [PATCH] Export utils_stream_file_path outside of common/utils.c MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/common/string-utils/Makefile.am | 2 +- src/common/string-utils/format.h | 31 +++++++++++ src/common/utils.c | 85 +++++++++++------------------ src/common/utils.h | 3 + 4 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 src/common/string-utils/format.h diff --git a/src/common/string-utils/Makefile.am b/src/common/string-utils/Makefile.am index 1910042d6..90c08316b 100644 --- a/src/common/string-utils/Makefile.am +++ b/src/common/string-utils/Makefile.am @@ -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 index 000000000..99f775c82 --- /dev/null +++ b/src/common/string-utils/format.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 - Jérémie Galarneau + * + * 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 */ diff --git a/src/common/utils.c b/src/common/utils.c index a91ede65c..2f132a060 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #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; } diff --git a/src/common/utils.h b/src/common/utils.h index 5f95d4aab..ef02c2759 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -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); -- 2.34.1