* \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_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)
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;
}