+
+LTTNG_HIDDEN
+bool lttng_trigger_is_equal(
+ const struct lttng_trigger *a, const struct lttng_trigger *b)
+{
+ /*
+ * Name is not taken into account since it is cosmetic only.
+ */
+ if (!lttng_condition_is_equal(a->condition, b->condition)) {
+ return false;
+ }
+
+ if (!lttng_action_is_equal(a->action, b->action)) {
+ return false;
+ }
+
+ if (!lttng_credentials_is_equal(lttng_trigger_get_credentials(a),
+ lttng_trigger_get_credentials(b))) {
+ return false;
+ }
+
+ return true;
+}
+
+enum lttng_trigger_status lttng_trigger_set_name(struct lttng_trigger *trigger,
+ const char* name)
+{
+ char *name_copy = NULL;
+ enum lttng_trigger_status status = LTTNG_TRIGGER_STATUS_OK;
+
+ if (!trigger || !name ||
+ strlen(name) == 0) {
+ status = LTTNG_TRIGGER_STATUS_INVALID;
+ goto end;
+ }
+
+ name_copy = strdup(name);
+ if (!name_copy) {
+ status = LTTNG_TRIGGER_STATUS_ERROR;
+ goto end;
+ }
+
+ free(trigger->name);
+
+ trigger->name = name_copy;
+ name_copy = NULL;
+end:
+ return status;
+}
+
+enum lttng_trigger_status lttng_trigger_get_name(
+ const struct lttng_trigger *trigger, const char **name)
+{
+ enum lttng_trigger_status status = LTTNG_TRIGGER_STATUS_OK;
+
+ if (!trigger || !name) {
+ status = LTTNG_TRIGGER_STATUS_INVALID;
+ goto end;
+ }
+
+ if (!trigger->name) {
+ status = LTTNG_TRIGGER_STATUS_UNSET;
+ }
+
+ *name = trigger->name;
+end:
+ return status;
+}
+
+LTTNG_HIDDEN
+int lttng_trigger_assign_name(struct lttng_trigger *dst,
+ const struct lttng_trigger *src)
+{
+ int ret = 0;
+ enum lttng_trigger_status status;
+
+ status = lttng_trigger_set_name(dst, src->name);
+ if (status != LTTNG_TRIGGER_STATUS_OK) {
+ ret = -1;
+ ERR("Failed to set name for trigger");
+ goto end;
+ }
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+int lttng_trigger_generate_name(struct lttng_trigger *trigger,
+ uint64_t unique_id)
+{
+ int ret = 0;
+ char *generated_name = NULL;
+
+ ret = asprintf(&generated_name, "T%" PRIu64 "", unique_id);
+ if (ret < 0) {
+ ERR("Failed to generate trigger name");
+ ret = -1;
+ goto end;
+ }
+
+ ret = 0;
+ free(trigger->name);
+ trigger->name = generated_name;
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+void lttng_trigger_get(struct lttng_trigger *trigger)
+{
+ urcu_ref_get(&trigger->ref);
+}
+
+LTTNG_HIDDEN
+void lttng_trigger_put(struct lttng_trigger *trigger)
+{
+ if (!trigger) {
+ return;
+ }
+
+ urcu_ref_put(&trigger->ref , trigger_destroy_ref);
+}
+
+LTTNG_HIDDEN
+const struct lttng_credentials *lttng_trigger_get_credentials(
+ const struct lttng_trigger *trigger)
+{
+ return &trigger->creds;
+}
+
+LTTNG_HIDDEN
+void lttng_trigger_set_credentials(struct lttng_trigger *trigger,
+ const struct lttng_credentials *creds)
+{
+ assert(creds);
+ trigger->creds = *creds;
+}
+
+enum lttng_trigger_status lttng_trigger_set_owner_uid(
+ struct lttng_trigger *trigger, uid_t uid)
+{
+ enum lttng_trigger_status ret = LTTNG_TRIGGER_STATUS_OK;
+ const struct lttng_credentials creds = {
+ .uid = LTTNG_OPTIONAL_INIT_VALUE(uid),
+ .gid = LTTNG_OPTIONAL_INIT_UNSET,
+ };
+
+ if (!trigger) {
+ ret = LTTNG_TRIGGER_STATUS_INVALID;
+ goto end;
+ }
+
+ /* Client-side validation only to report a clearer error. */
+ if (geteuid() != 0) {
+ ret = LTTNG_TRIGGER_STATUS_PERMISSION_DENIED;
+ goto end;
+ }
+
+ lttng_trigger_set_credentials(trigger, &creds);
+
+end:
+ return ret;
+}
+
+enum lttng_trigger_status lttng_trigger_get_owner_uid(
+ const struct lttng_trigger *trigger, uid_t *uid)
+{
+ enum lttng_trigger_status ret = LTTNG_TRIGGER_STATUS_OK;
+ const struct lttng_credentials *creds = NULL;
+
+ if (!trigger || !uid ) {
+ ret = LTTNG_TRIGGER_STATUS_INVALID;
+ goto end;
+ }
+
+ if (!trigger->creds.uid.is_set ) {
+ ret = LTTNG_TRIGGER_STATUS_UNSET;
+ goto end;
+ }
+
+ creds = lttng_trigger_get_credentials(trigger);
+ *uid = lttng_credentials_get_uid(creds);
+
+end:
+ return ret;
+}