Let afs_event() return int.
authorAndre Noll <maan@tuebingen.mpg.de>
Thu, 9 Apr 2015 12:51:49 +0000 (12:51 +0000)
committerAndre Noll <maan@tuebingen.mpg.de>
Wed, 12 Aug 2015 21:23:48 +0000 (23:23 +0200)
It is usually a critical error if an afs event handler returns an
error. Currently we only print a log message an continue in this
case. The callers of afs_event() which trigger the event have no way
to tell that something went wrong, since this function returns void.

By returning int instead of void the callers can abort in the error
case. Most of the callers are afs callbacks. These can propagate the
error code to the command handler process, which will translate the
error code into a string and send it to the client.  All callbacks
are changed in this way.

afs.c
afs.h
aft.c
attribute.c
blob.c

diff --git a/afs.c b/afs.c
index 0c61574..67b473a 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -1170,10 +1170,14 @@ int com_check(struct command_context *cc)
  * \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;
@@ -1183,10 +1187,13 @@ void afs_event(enum afs_events event, struct para_buffer *pb,
                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;
 }
 
 /**
diff --git a/afs.h b/afs.h
index efd7fba..8fd8313 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -209,7 +209,7 @@ _static_inline_ int afs_max_size_handler(char *buf, size_t size, void *private)
 }
 
 __noreturn void afs_init(uint32_t cookie, int socket_fd);
-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 send_callback_request(callback_function *f, struct osl_object *query,
                callback_result_handler *result_handler,
diff --git a/aft.c b/aft.c
index 0207705..9f6c4e2 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1072,7 +1072,9 @@ again:
         * 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);
@@ -1658,7 +1660,9 @@ static int com_add_callback(int fd, const struct osl_object *query)
                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;
@@ -1676,7 +1680,9 @@ static int com_add_callback(int fd, const struct osl_object *query)
                        &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;
        }
@@ -1719,7 +1725,9 @@ static int com_add_callback(int fd, const struct osl_object *query)
                        &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 */
@@ -1732,7 +1740,7 @@ static int com_add_callback(int fd, const struct osl_object *query)
        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);
@@ -2007,8 +2015,7 @@ static int touch_audio_file(__a_unused struct osl_table *table,
        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)
@@ -2139,7 +2146,9 @@ static int remove_audio_file(__a_unused struct osl_table *table,
 
        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);
@@ -2276,8 +2285,7 @@ static int copy_selector_info(__a_unused struct osl_table *table,
                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)
@@ -2398,8 +2406,7 @@ static int change_atts(__a_unused struct osl_table *table,
        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)
index af1400c..5bb14ed 100644 (file)
@@ -280,7 +280,9 @@ static int com_addatt_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:
@@ -330,7 +332,7 @@ 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;
 }
@@ -361,8 +363,7 @@ static int remove_attribute(struct osl_table *table, struct osl_row *row,
                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)
diff --git a/blob.c b/blob.c
index fbfea00..1360963 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -289,7 +289,7 @@ static int com_rmblob_callback(struct osl_table *table, int fd,
                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);
@@ -371,7 +371,7 @@ static int com_addblob_callback(struct osl_table *table, int fd,
        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);
@@ -489,7 +489,7 @@ static int com_mvblob_callback(struct osl_table *table, int fd,
                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;