/*
- * Copyright (C) 2007 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2007-2008 Andre Noll <maan@systemlinux.org>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
* \param result Callback result will be stored here.
*
* This function creates a shared memory area, copies the buffer pointed to by
- * query to that area and notifies the afs process that \a f should be
+ * \a query to that area and notifies the afs process that \a f should be
* called ASAP.
*
* \return Negative, on errors, the return value of the callback function
* \sa send_option_arg_callback_request(), send_standard_callback_request().
*/
int send_callback_request(callback_function *f, struct osl_object *query,
- struct osl_object *result)
+ callback_result_handler *result_handler,
+ void *private_result_data)
{
struct callback_query *cq;
- struct callback_result *cr;
- int ret, fd = -1, query_shmid, result_shmid;
+ int num_results = 0, ret, fd = -1, query_shmid, result_shmid;
void *query_shm, *result_shm;
char buf[sizeof(afs_socket_cookie) + sizeof(int)];
size_t query_shm_size = sizeof(*cq);
ret = send_bin_buffer(fd, buf, sizeof(buf));
if (ret < 0)
goto out;
- ret = recv_bin_buffer(fd, buf, sizeof(buf));
- if (ret < 0)
- goto out;
- if (ret != sizeof(int)) {
- ret = -E_AFS_SHORT_READ;
- goto out;
- }
- ret = *(int *) buf;
- if (ret <= 0)
- goto out;
- result_shmid = ret;
- ret = shm_attach(result_shmid, ATTACH_RO, &result_shm);
- if (ret >= 0) {
- assert(result);
- cr = result_shm;
- result->size = cr->result_size;
- result->data = para_malloc(result->size);
- memcpy(result->data, result_shm + sizeof(*cr), result->size);
- ret = shm_detach(result_shm);
+ for (;;) {
+ ret = recv_bin_buffer(fd, buf, sizeof(int));
+ if (ret <= 0)
+ goto out;
+ if (ret != sizeof(int)) {
+ ret = -E_AFS_SHORT_READ;
+ goto out;
+ }
+ ret = *(int *) buf;
+ if (ret <= 0)
+ goto out;
+ result_shmid = ret;
+ ret = shm_attach(result_shmid, ATTACH_RO, &result_shm);
+ if (ret >= 0) {
+ struct callback_result *cr = result_shm;
+ struct osl_object result;
+ num_results++;
+ result.size = cr->result_size;
+ result.data = result_shm + sizeof(*cr);
+ if (result.size) {
+ assert(result_handler);
+ ret = result_handler(&result, private_result_data);
+ if (shm_detach(result_shm) < 0)
+ PARA_ERROR_LOG("can not detach result\n");
+ }
+ } else
+ PARA_ERROR_LOG("attach result failed: %d\n", ret);
+ if (shm_destroy(result_shmid) < 0)
+ PARA_ERROR_LOG("destroy result failed\n");
if (ret < 0)
- PARA_ERROR_LOG("can not detach result\n");
- } else
- PARA_ERROR_LOG("attach result failed: %d\n", ret);
- if (shm_destroy(result_shmid) < 0)
- PARA_ERROR_LOG("destroy result failed\n");
- ret = 1;
+ break;
+ }
out:
if (shm_destroy(query_shmid) < 0)
PARA_ERROR_LOG("%s\n", "shm destroy error");
if (fd >= 0)
close(fd);
+ if (ret >= 0)
+ ret = num_results;
// PARA_DEBUG_LOG("callback_ret: %d\n", ret);
return ret;
}
*/
int send_option_arg_callback_request(struct osl_object *options,
int argc, char * const * const argv, callback_function *f,
- struct osl_object *result)
+ callback_result_handler *result_handler,
+ void *private_result_data)
{
char *p;
int i, ret;
strcpy(p, argv[i]); /* OK */
p += strlen(argv[i]) + 1;
}
- ret = send_callback_request(f, &query, result);
+ ret = send_callback_request(f, &query, result_handler,
+ private_result_data);
free(query.data);
return ret;
}
* send_option_arg_callback_request().
*/
int send_standard_callback_request(int argc, char * const * const argv,
- callback_function *f, struct osl_object *result)
+ callback_function *f, callback_result_handler *result_handler,
+ void *private_result_data)
{
- return send_option_arg_callback_request(NULL, argc, argv, f, result);
+ return send_option_arg_callback_request(NULL, argc, argv, f, result_handler,
+ private_result_data);
}
static int action_if_pattern_matches(struct osl_row *row, void *data)
* send_callback_request() otherwise.
*/
int stdin_command(int fd, struct osl_object *arg_obj, callback_function *f,
- unsigned max_len, struct osl_object *result)
+ unsigned max_len, callback_result_handler *result_handler,
+ void *private_result_data)
{
struct osl_object query, stdin_obj;
int ret;
memcpy(query.data, arg_obj->data, arg_obj->size);
memcpy((char *)query.data + arg_obj->size, stdin_obj.data, stdin_obj.size);
free(stdin_obj.data);
- ret = send_callback_request(f, &query, result);
+ ret = send_callback_request(f, &query, result_handler, private_result_data);
free(query.data);
return ret;
}
PARA_NOTICE_LOG("getting next audio file\n");
ret = score_get_best(&aft_row, &score);
if (ret < 0) {
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_ERROR_LOG("%s\n", para_strerror(-ret));
goto no_admissible_files;
}
ret = open_and_update_audio_file(aft_row, score, &afd);
if (ret < 0) {
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_ERROR_LOG("%s\n", para_strerror(-ret));
ret = score_delete(aft_row);
if (ret < 0) {
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_ERROR_LOG("%s\n", para_strerror(-ret));
goto no_admissible_files;
}
goto again;
ret = change_current_mood(NULL); /* always successful */
mode = PLAY_MODE_MOOD;
} else {
- if (!strncmp(arg, "p:", 2)) {
+ if (!strncmp(arg, "p/", 2)) {
ret = playlist_open(arg + 2);
mode = PLAY_MODE_PLAYLIST;
- } else if (!strncmp(arg, "m:", 2)) {
+ } else if (!strncmp(arg, "m/", 2)) {
ret = change_current_mood(arg + 2);
mode = PLAY_MODE_MOOD;
} else
playlist_close();
ret = activate_mood_or_playlist(arg, &num_admissible);
if (ret < 0) {
- para_printf(&pb, "%s\n", PARA_STRERROR(-ret));
+ para_printf(&pb, "%s\n", para_strerror(-ret));
para_printf(&pb, "switching back to %s\n", current_mop?
current_mop : "dummy");
ret = activate_mood_or_playlist(current_mop, &num_admissible);
para_printf(&pb, "activated %s (%d admissible files)\n", current_mop?
current_mop : "dummy mood", num_admissible);
result->data = pb.buf;
- result->size = pb.size;
+ result->size = pb.offset;
return 1;
}
+int send_result(struct osl_object *result, void *private_result_data)
+{
+ int fd = *(int *)private_result_data;
+ if (!result->size)
+ return 1;
+ return send_bin_buffer(fd, result->data, result->size);
+}
+
int com_select(int fd, int argc, char * const * const argv)
{
- int ret;
- struct osl_object query, result;
+ struct osl_object query;
if (argc != 2)
return -E_AFS_SYNTAX;
query.data = argv[1];
query.size = strlen(argv[1]) + 1;
- ret = send_callback_request(com_select_callback, &query,
- &result);
- if (ret > 0 && result.data && result.size) {
- ret = send_va_buffer(fd, "%s", (char *)result.data);
- free(result.data);
- }
- return ret;
+ return send_callback_request(com_select_callback, &query,
+ &send_result, &fd);
}
static void init_admissible_files(char *arg)
ret = create_local_socket(socket_name, &unix_addr,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IWOTH);
if (ret < 0) {
- PARA_EMERG_LOG("%s: %s\n", PARA_STRERROR(-ret), socket_name);
+ PARA_EMERG_LOG("%s: %s\n", para_strerror(-ret), socket_name);
exit(EXIT_FAILURE);
}
socket_fd = ret;
close(socket_fd);
return ret;
}
- PARA_INFO_LOG("listening on socket %s (fd %d)\n", socket_name, ret);
+ PARA_INFO_LOG("listening on socket %s (fd %d)\n", socket_name,
+ socket_fd);
return socket_fd;
}
if (ret >= 0)
continue;
PARA_ERROR_LOG("%s init: %s\n", afs_tables[i].name,
- PARA_STRERROR(-ret));
+ para_strerror(-ret));
break;
}
if (ret >= 0)
}
t->ret = -E_AFS_SIGNAL;
err:
- PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
+ PARA_NOTICE_LOG("%s\n", para_strerror(-t->ret));
unregister_tasks();
}
if (ret <= 0) {
if (ret < 0)
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_ERROR_LOG("%s\n", para_strerror(-ret));
return;
}
buf[ret] = '\0';
if (!strcmp(buf, "new")) {
ret = open_next_audio_file();
if (ret < 0) {
- PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_EMERG_LOG("%s\n", para_strerror(-ret));
unregister_tasks();
}
return;
int ret = recv_bin_buffer(fd, buf, sizeof(buf));
if (ret < 0) {
- PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
return;
}
if (ret != sizeof(buf)) {
goto out;
t->ret = para_accept(ct->fd, &unix_addr, sizeof(unix_addr));
if (t->ret < 0) {
- PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
+ PARA_NOTICE_LOG("%s\n", para_strerror(-t->ret));
goto out;
}
fd = t->ret;
t->ret = mark_fd_nonblocking(fd);
if (t->ret < 0) {
- PARA_NOTICE_LOG("%s\n", PARA_STRERROR(-t->ret));
+ PARA_NOTICE_LOG("%s\n", para_strerror(-t->ret));
close(fd);
goto out;
}
ret = open_afs_tables();
if (ret < 0) {
- PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_EMERG_LOG("%s\n", para_strerror(-ret));
exit(EXIT_FAILURE);
}
server_socket = socket_fd;
s.default_timeout.tv_usec = 999 * 1000;
ret = schedule(&s);
if (ret < 0)
- PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_EMERG_LOG("%s\n", para_strerror(-ret));
close_afs_tables();
exit(EXIT_FAILURE);
}
return -E_BAD_TABLE_NAME;
}
}
- ret = send_callback_request(create_tables_callback, &query, NULL);
+ ret = send_callback_request(create_tables_callback, &query, NULL, NULL);
if (ret < 0)
return ret;
return send_va_buffer(fd, "successfully created afs table(s)\n");
{
unsigned flags = 0;
int i, ret;
- struct osl_object result;
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
if (!flags)
flags = ~0U;
if (flags & CHECK_AFT) {
- ret = send_callback_request(aft_check_callback, NULL, &result);
+ ret = send_callback_request(aft_check_callback, NULL, send_result, &fd);
if (ret < 0)
return ret;
- if (ret > 0) {
- ret = send_buffer(fd, (char *) result.data);
- free(result.data);
- if (ret < 0)
- return ret;
- }
}
if (flags & CHECK_PLAYLISTS) {
- ret = send_callback_request(playlist_check_callback, NULL, &result);
+ ret = send_callback_request(playlist_check_callback, NULL, send_result, &fd);
if (ret < 0)
return ret;
- if (ret > 0) {
- ret = send_buffer(fd, (char *) result.data);
- free(result.data);
- if (ret < 0)
- return ret;
- }
}
if (flags & CHECK_MOODS) {
- ret = send_callback_request(mood_check_callback, NULL, &result);
+ ret = send_callback_request(mood_check_callback, NULL, send_result, &fd);
if (ret < 0)
return ret;
- if (ret > 0) {
- ret = send_buffer(fd, (char *) result.data);
- free(result.data);
- if (ret < 0)
- return ret;
- }
}
return 1;
}
continue;
ret = t->event_handler(event, pb, data);
if (ret < 0)
- PARA_CRIT_LOG("%s\n", PARA_STRERROR(-ret));
+ PARA_CRIT_LOG("%s\n", para_strerror(-ret));
}
}