X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=afs.c;fp=afs.c;h=b15f83852e6919c4f0867065d13776c211416087;hp=6493586a6abad51c1f6bd5d3716c7a1dd1beeb23;hb=0b5c29fae8853bac16b91503df70b0e101dccca4;hpb=1f33eda05b3e96b32817a133287bcfc5e99ed6b4 diff --git a/afs.c b/afs.c index 6493586a..b15f8385 100644 --- a/afs.c +++ b/afs.c @@ -728,6 +728,43 @@ err: return ret; } +/** + * Format and send an error message to the command handler. + * + * To pass an error message from the callback of an afs command to the client, + * this function should be called. It formats the message into a buffer which + * is passed as a shared memory area to the command handler from where it + * propagates to the client. + * + * The message will be tagged with the ERROR_LOG sideband designator so that + * the client writes it to its stderr stream rather than to stdout as with + * aca->pbout. In analogy to the default Unix semantics of stderr, the message + * is sent without buffering. + * + * If sending the error message fails, an error is logged on the server side, + * but no other action is taken. + * + * \param aca Used to obtain the fd to send the shmid to. + * \param fmt Usual format string. + */ +__printf_2_3 void afs_error(const struct afs_callback_arg *aca, + const char *fmt,...) +{ + va_list argp; + char *msg; + unsigned n; + int ret; + + va_start(argp, fmt); + n = xvasprintf(&msg, fmt, argp); + va_end(argp); + ret = pass_buffer_as_shm(aca->fd, SBD_ERROR_LOG, msg, n + 1); + if (ret < 0) + PARA_ERROR_LOG("Could not send %s: %s\n", msg, + para_strerror(-ret)); + free(msg); +} + static int call_callback(int fd, int query_shmid) { void *query_shm; @@ -958,12 +995,12 @@ static int com_select_callback(struct afs_callback_arg *aca) /* ignore subsequent errors (but log them) */ if (current_mop && strcmp(current_mop, arg) != 0) { int ret2; - para_printf(&aca->pbout, "switching back to %s\n", current_mop); + afs_error(aca, "switching back to %s\n", current_mop); ret2 = activate_mood_or_playlist(current_mop, &aca->pbout); if (ret2 >= 0) goto free_lpr; - para_printf(&aca->pbout, "could not reactivate %s: %s\n", - current_mop, para_strerror(-ret2)); + afs_error(aca, "could not reactivate %s: %s\n", current_mop, + para_strerror(-ret2)); } activate_mood_or_playlist(NULL, &aca->pbout); free_lpr: @@ -1001,8 +1038,7 @@ static int com_init_callback(struct afs_callback_arg *aca) continue; ret = t->ops->create(database_dir); if (ret < 0) { - para_printf(&aca->pbout, "cannot create table %s\n", - t->name); + afs_error(aca, "cannot create table %s\n", t->name); goto out; } para_printf(&aca->pbout, "successfully created %s table\n", @@ -1010,7 +1046,7 @@ static int com_init_callback(struct afs_callback_arg *aca) } ret = open_afs_tables(); if (ret < 0) - para_printf(&aca->pbout, "cannot open afs tables: %s\n", + afs_error(aca, "cannot open afs tables: %s\n", para_strerror(-ret)); out: return ret;