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 0c615747435657b65ec5302192561fd902c84348..67b473a49178ea42e3e50f742b6e95f9709f9379 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.
  *
  * \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;
                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 (!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));
                        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 efd7fbacf61d1bea136e7162c14407c66b457b82..8fd8313a49d682be711101c6931dc0c5238bb5b5 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);
 }
 
 __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,
        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 0207705f858a3beb77c98a6a7e0e6a2c123e68b6..9f6c4e29826eb9b403882d8d4c9d5775988fe942 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.
         */
         * 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);
        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);
                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;
                        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;
                        &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;
        }
                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;
                        &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 */
                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));
        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);
 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;
        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)
 }
 
 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);
 
        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);
        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;
                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)
 }
 
 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 */
        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)
 }
 
 static int com_setatt_callback(int fd, const struct osl_object *query)
index af1400c8a8e218d832d86cf0016a81388ab72f7b..5bb14ed43d813b8dc01498c29541e8410d4262b4 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;
                        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:
                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
        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;
 }
        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;
        }
                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)
 }
 
 static int com_rmatt_callback(int fd, const struct osl_object *query)
diff --git a/blob.c b/blob.c
index fbfea00ce90a2ac4bf49c5b8e7002248d5c329e0..1360963e6b6ef16d235972a150faf6dcb7ae64fe 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);
                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);
        }
 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;
        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);
 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;
        }
                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;
 out:
        flush_and_free_pb(&pb);
        return ret;