+ ret = lttng_strncpy(data.u.rmdir.path, path,
+ sizeof(data.u.rmdir.path));
+ if (ret) {
+ goto error;
+ }
+ data.u.rmdir.dirfd = dirfd;
+ run_as(dirfd == AT_FDCWD ? RUN_AS_RMDIR : RUN_AS_RMDIRAT, &data,
+ &run_as_ret, uid, gid);
+ errno = run_as_ret._errno;
+ ret = run_as_ret.u.ret;
+error:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int run_as_rmdir_recursive(const char *path, uid_t uid, gid_t gid, int flags)
+{
+ return run_as_rmdirat_recursive(AT_FDCWD, path, uid, gid, flags);
+}
+
+LTTNG_HIDDEN
+int run_as_rmdirat_recursive(int dirfd, const char *path, uid_t uid, gid_t gid, int flags)
+{
+ int ret;
+ struct run_as_data data = {};
+ struct run_as_ret run_as_ret = {};
+
+ DBG3("rmdirat() recursive fd = %d%s, path = %s, uid = %d, gid = %d",
+ dirfd, dirfd == AT_FDCWD ? " (AT_FDCWD)" : "",
+ path, (int) uid, (int) gid);
+ ret = lttng_strncpy(data.u.rmdir.path, path,
+ sizeof(data.u.rmdir.path));
+ if (ret) {
+ goto error;
+ }
+ data.u.rmdir.dirfd = dirfd;
+ data.u.rmdir.flags = flags;
+ run_as(dirfd == AT_FDCWD ? RUN_AS_RMDIR_RECURSIVE : RUN_AS_RMDIRAT_RECURSIVE,
+ &data, &run_as_ret, uid, gid);
+ errno = run_as_ret._errno;
+ ret = run_as_ret.u.ret;
+error:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int run_as_rename(const char *old, const char *new, uid_t uid, gid_t gid)
+{
+ return run_as_renameat(AT_FDCWD, old, AT_FDCWD, new, uid, gid);
+}
+
+LTTNG_HIDDEN
+int run_as_renameat(int old_dirfd, const char *old_name,
+ int new_dirfd, const char *new_name, uid_t uid, gid_t gid)
+{
+ int ret;
+ struct run_as_data data = {};
+ struct run_as_ret run_as_ret = {};
+
+ DBG3("renameat() old_dirfd = %d%s, old_name = %s, new_dirfd = %d%s, new_name = %s, uid = %d, gid = %d",
+ old_dirfd, old_dirfd == AT_FDCWD ? " (AT_FDCWD)" : "",
+ old_name,
+ new_dirfd, new_dirfd == AT_FDCWD ? " (AT_FDCWD)" : "",
+ new_name, (int) uid, (int) gid);
+ ret = lttng_strncpy(data.u.rename.old_path, old_name,
+ sizeof(data.u.rename.old_path));
+ if (ret) {
+ goto error;
+ }
+ ret = lttng_strncpy(data.u.rename.new_path, new_name,
+ sizeof(data.u.rename.new_path));
+ if (ret) {
+ goto error;
+ }
+
+ data.u.rename.dirfds[0] = old_dirfd;
+ data.u.rename.dirfds[1] = new_dirfd;
+ run_as(old_dirfd == AT_FDCWD && new_dirfd == AT_FDCWD ?
+ RUN_AS_RENAME : RUN_AS_RENAMEAT,
+ &data, &run_as_ret, uid, gid);
+ errno = run_as_ret._errno;
+ ret = run_as_ret.u.ret;
+error:
+ return ret;