+} LTTNG_PACKED;
+
+#define COMMAND_IN_FDS(data_ptr) ({ \
+ int *fds = NULL; \
+ if (command_properties[data_ptr->cmd].in_fds_offset != -1) { \
+ fds = (int *) ((char *) data_ptr + command_properties[data_ptr->cmd].in_fds_offset); \
+ } \
+ fds; \
+})
+
+#define COMMAND_OUT_FDS(cmd, ret_ptr) ({ \
+ int *fds = NULL; \
+ if (command_properties[cmd].out_fds_offset != -1) { \
+ fds = (int *) ((char *) ret_ptr + command_properties[cmd].out_fds_offset); \
+ } \
+ fds; \
+})
+
+#define COMMAND_IN_FD_COUNT(data_ptr) ({ \
+ command_properties[data_ptr->cmd].in_fd_count; \
+})
+
+#define COMMAND_OUT_FD_COUNT(cmd) ({ \
+ command_properties[cmd].out_fd_count; \
+})
+
+#define COMMAND_USE_CWD_FD(data_ptr) command_properties[data_ptr->cmd].use_cwd_fd
+
+struct run_as_command_properties {
+ /* Set to -1 when not applicable. */
+ ptrdiff_t in_fds_offset, out_fds_offset;
+ unsigned int in_fd_count, out_fd_count;
+ bool use_cwd_fd;
+};
+
+static const struct run_as_command_properties command_properties[] = {
+ [RUN_AS_MKDIR] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.mkdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_MKDIRAT] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.mkdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_MKDIR_RECURSIVE] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.mkdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_MKDIRAT_RECURSIVE] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.mkdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_OPEN] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.open.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = offsetof(struct run_as_ret, u.open.fd),
+ .out_fd_count = 1,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_OPENAT] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.open.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = offsetof(struct run_as_ret, u.open.fd),
+ .out_fd_count = 1,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_UNLINK] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.unlink.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_UNLINKAT] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.unlink.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_RMDIR_RECURSIVE] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.rmdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_RMDIRAT_RECURSIVE] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.rmdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_RMDIR] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.rmdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_RMDIRAT] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.rmdir.dirfd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_RENAME] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.rename.dirfds),
+ .in_fd_count = 2,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = true,
+ },
+ [RUN_AS_RENAMEAT] = {
+ .in_fds_offset = offsetof(struct run_as_data, u.rename.dirfds),
+ .in_fd_count = 2,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET] = {
+ .in_fds_offset = offsetof(struct run_as_data,
+ u.extract_elf_symbol_offset.fd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_EXTRACT_SDT_PROBE_OFFSETS] = {
+ .in_fds_offset = offsetof(struct run_as_data,
+ u.extract_sdt_probe_offsets.fd),
+ .in_fd_count = 1,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },
+ [RUN_AS_GENERATE_FILTER_BYTECODE] = {
+ .in_fds_offset = -1,
+ .in_fd_count = 0,
+ .out_fds_offset = -1,
+ .out_fd_count = 0,
+ .use_cwd_fd = false,
+ },