Add rmdirat and renameat to run-as commands
[lttng-tools.git] / src / common / utils.c
index a91ede65c84af5d5c1d01797dc5766ee7e16057b..732a30bf114fb89551bf322451dca89afbef10cf 100644 (file)
@@ -40,6 +40,7 @@
 #include <common/compat/dirent.h>
 #include <common/compat/directory-handle.h>
 #include <common/dynamic-buffer.h>
 #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"
 #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.
  */
  *
  * 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;
 {
        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 {
        } 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;
 }
 
        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;
                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;
        }
        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;
                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;
        }
        if (ret < 0) {
                goto error;
        }
@@ -1508,79 +1485,16 @@ end:
 LTTNG_HIDDEN
 int utils_recursive_rmdir(const char *path)
 {
 LTTNG_HIDDEN
 int utils_recursive_rmdir(const char *path)
 {
-       DIR *dir;
-       size_t path_len;
-       int dir_fd, ret = 0, closeret, is_empty = 1;
-       struct dirent *entry;
-
-       /* Open directory */
-       dir = opendir(path);
-       if (!dir) {
-               PERROR("Cannot open '%s' path", path);
-               return -1;
-       }
-       dir_fd = lttng_dirfd(dir);
-       if (dir_fd < 0) {
-               PERROR("lttng_dirfd");
-               return -1;
-       }
-
-       path_len = strlen(path);
-       while ((entry = readdir(dir))) {
-               struct stat st;
-               size_t name_len;
-               char filename[PATH_MAX];
-
-               if (!strcmp(entry->d_name, ".")
-                               || !strcmp(entry->d_name, "..")) {
-                       continue;
-               }
-
-               name_len = strlen(entry->d_name);
-               if (path_len + name_len + 2 > sizeof(filename)) {
-                       ERR("Failed to remove file: path name too long (%s/%s)",
-                               path, entry->d_name);
-                       continue;
-               }
-               if (snprintf(filename, sizeof(filename), "%s/%s",
-                               path, entry->d_name) < 0) {
-                       ERR("Failed to format path.");
-                       continue;
-               }
-
-               if (stat(filename, &st)) {
-                       PERROR("stat");
-                       continue;
-               }
+       int ret;
+       struct lttng_directory_handle handle;
 
 
-               if (S_ISDIR(st.st_mode)) {
-                       char subpath[PATH_MAX];
-
-                       strncpy(subpath, path, PATH_MAX);
-                       subpath[PATH_MAX - 1] = '\0';
-                       strncat(subpath, "/",
-                               PATH_MAX - strlen(subpath) - 1);
-                       strncat(subpath, entry->d_name,
-                               PATH_MAX - strlen(subpath) - 1);
-                       if (utils_recursive_rmdir(subpath)) {
-                               is_empty = 0;
-                       }
-               } else if (S_ISREG(st.st_mode)) {
-                       is_empty = 0;
-               } else {
-                       ret = -EINVAL;
-                       goto end;
-               }
+       ret = lttng_directory_handle_init(&handle, NULL);
+       if (ret) {
+               goto end;
        }
        }
+       ret = lttng_directory_handle_remove_subdirectory(&handle, path);
+       lttng_directory_handle_fini(&handle);
 end:
 end:
-       closeret = closedir(dir);
-       if (closeret) {
-               PERROR("closedir");
-       }
-       if (is_empty) {
-               DBG3("Attempting rmdir %s", path);
-               ret = rmdir(path);
-       }
        return ret;
 }
 
        return ret;
 }
 
This page took 0.025662 seconds and 4 git commands to generate.