* \param pb May be \p NULL.
* \param data Type depends on \a event.
*
- * This function calls the table handlers of all tables and passes \a pb and \a
- * data verbatim. It's up to the handlers to interpret the \a data pointer.
+ * This function calls each table event handler, passing \a pb and \a data
+ * verbatim. It's up to the handlers to interpret the \a data pointer. If a
+ * handler returns negative, the loop is aborted.
+ *
+ * \return The (negative) error code of the first handler that failed, or non-negative
+ * if all handlers succeeded.
*/
-void afs_event(enum afs_events event, struct para_buffer *pb,
+__must_check int afs_event(enum afs_events event, struct para_buffer *pb,
void *data)
{
int i, ret;
if (!t->event_handler)
continue;
ret = t->event_handler(event, pb, data);
- if (ret < 0)
+ if (ret < 0) {
PARA_CRIT_LOG("table %s, event %d: %s\n", t->name,
event, para_strerror(-ret));
+ return ret;
+ }
}
+ return 1;
}
/**
* No need to update the status items as the AFSI_CHANGE event will
* recreate them.
*/
- afs_event(AFSI_CHANGE, NULL, &aced);
+ ret = afs_event(AFSI_CHANGE, NULL, &aced);
+ if (ret < 0)
+ goto out;
ret = save_afd(afd);
out:
free(afd->afhi.chunk_table);
if (pb) { /* hs trumps pb, remove pb */
if (flags & ADD_FLAG_VERBOSE)
para_printf(&msg, "removing %s\n", path);
- afs_event(AUDIO_FILE_REMOVE, &msg, pb);
+ ret = afs_event(AUDIO_FILE_REMOVE, &msg, pb);
+ if (ret < 0)
+ goto out;
ret = osl(osl_del_row(audio_file_table, pb));
if (ret < 0)
goto out;
&objs[AFTCOL_PATH]));
if (ret < 0)
goto out;
- afs_event(AUDIO_FILE_RENAME, &msg, hs);
+ ret = afs_event(AUDIO_FILE_RENAME, &msg, hs);
+ if (ret < 0)
+ goto out;
if (!(flags & ADD_FLAG_FORCE))
goto out;
}
&objs[AFTCOL_CHUNKS]));
if (ret < 0)
goto out;
- afs_event(AFHI_CHANGE, &msg, row);
+ ret = afs_event(AFHI_CHANGE, &msg, row);
+ if (ret < 0)
+ goto out;
goto out;
}
/* new entry, use default afsi */
objs[AFTCOL_AFSI].size = AFSI_SIZE;
save_afsi(&default_afsi, &objs[AFTCOL_AFSI]);
ret = osl(osl_add_and_get_row(audio_file_table, objs, &aft_row));
- afs_event(AUDIO_FILE_ADD, &msg, aft_row);
+ ret = afs_event(AUDIO_FILE_ADD, &msg, aft_row);
out:
if (ret < 0)
para_printf(&msg, "could not add %s\n", path);
save_afsi(&new_afsi, &obj); /* in-place update */
aced.aft_row = row;
aced.old_afsi = &old_afsi;
- afs_event(AFSI_CHANGE, &tad->pb, &aced);
- return 1;
+ return afs_event(AFSI_CHANGE, &tad->pb, &aced);
}
static int com_touch_callback(int fd, const struct osl_object *query)
if (crd->flags & RM_FLAG_VERBOSE)
para_printf(&crd->pb, "removing %s\n", name);
- afs_event(AUDIO_FILE_REMOVE, &crd->pb, row);
+ ret = afs_event(AUDIO_FILE_REMOVE, &crd->pb, row);
+ if (ret < 0)
+ return ret;
ret = osl(osl_del_row(audio_file_table, row));
if (ret < 0)
para_printf(&crd->pb, "cannot remove %s\n", name);
para_printf(&cad->pb, "copied afsi to %s\n", name);
aced.aft_row = row;
aced.old_afsi = &old_afsi;
- afs_event(AFSI_CHANGE, &cad->pb, &aced);
- return 1;
+ return afs_event(AFSI_CHANGE, &cad->pb, &aced);
}
static int com_cpsi_callback(int fd, const struct osl_object *query)
new_afsi.attributes |= cad->add_mask;
new_afsi.attributes &= ~cad->del_mask;
save_afsi(&new_afsi, &obj); /* in-place update */
- afs_event(AFSI_CHANGE, &cad->pb, &aced);
- return 1;
+ return afs_event(AFSI_CHANGE, &cad->pb, &aced);
}
static int com_setatt_callback(int fd, const struct osl_object *query)
goto out;
aed.name = p;
aed.bitnum = bitnum;
- afs_event(ATTRIBUTE_ADD, &pb, &aed);
+ ret = afs_event(ATTRIBUTE_ADD, &pb, &aed);
+ if (ret < 0)
+ goto out;
greatest_att_bitnum = PARA_MAX(greatest_att_bitnum, (int)bitnum);
}
out:
if (ret < 0)
para_printf(&pb, "cannot rename %s to %s\n", old, new);
else
- afs_event(ATTRIBUTE_RENAME, &pb, NULL);
+ ret = afs_event(ATTRIBUTE_RENAME, &pb, NULL);
flush_and_free_pb(&pb);
return ret;
}
para_printf(pb, "cannot remove %s\n", name);
return ret;
}
- afs_event(ATTRIBUTE_REMOVE, pb, &red);
- return 1;
+ return afs_event(ATTRIBUTE_REMOVE, pb, &red);
}
static int com_rmatt_callback(int fd, const struct osl_object *query)
ret = -E_NO_MATCH;
else {
para_printf(&pb, "removed %d blob(s)\n", pmd.num_matches);
- afs_event(BLOB_RENAME, NULL, table);
+ ret = afs_event(BLOB_RENAME, NULL, table);
}
out:
flush_and_free_pb(&pb);
ret = osl(osl_add_row(table, objs));
if (ret < 0)
goto out;
- afs_event(BLOB_ADD, NULL, table);
+ ret = afs_event(BLOB_ADD, NULL, table);
out:
if (ret < 0)
msg_len = xasprintf(&msg, "cannot add %s\n", name);
para_printf(&pb, "cannot rename blob %s to %s\n", src, dest);
goto out;
}
- afs_event(BLOB_RENAME, NULL, table);
+ ret = afs_event(BLOB_RENAME, NULL, table);
out:
flush_and_free_pb(&pb);
return ret;