From: Andre Noll Date: Tue, 29 Nov 2011 07:36:49 +0000 (+0100) Subject: Merge branch 't/flac' X-Git-Tag: v0.4.9~2 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=f48194d3ff2a3983f21cab1553fbe29529f2e790;hp=8c8a5e12c09147d5fdd8976eaba7154391e2fe07 Merge branch 't/flac' --- diff --git a/Makefile.in b/Makefile.in index 68aa6bc9..23ceda47 100644 --- a/Makefile.in +++ b/Makefile.in @@ -66,7 +66,6 @@ CPPFLAGS += -I$(cmdline_dir) CPPFLAGS += @osl_cppflags@ man_pages := $(patsubst %, man/man1/%.1, @executables@) -man_pages_in := $(patsubst %, web/%.man.in.html, @executables@) ggo_dir := ggo object_dir := objects @@ -120,8 +119,6 @@ tarball: $(tarball) @[ -z "$(Q)" ] || echo 'GEN $@' $(Q) ./command_util.sh man < $< > $@ -server_command_lists_ch = server_command_list.c afs_command_list.c \ - server_command_list.h afs_command_list.h server_command_lists_man = server_command_list.man afs_command_list.man man/man1/para_server.1: para_server $(server_command_lists_man) | $(man_dir) @[ -z "$(Q)" ] || echo 'MAN $<' @@ -255,7 +252,7 @@ para_gui: $(gui_objs) @[ -z "$(Q)" ] || echo 'LD $@' $(Q) $(CC) $(LDFLAGS) -o $@ $(gui_objs) -lcurses -para_audiod: audiod_command_list.c audiod_command_list.h $(audiod_objs) +para_audiod: $(audiod_objs) @[ -z "$(Q)" ] || echo 'LD $@' $(Q) $(CC) $(LDFLAGS) -o $@ $(audiod_objs) @audiod_ldflags@ @@ -267,7 +264,7 @@ para_fade: $(fade_objs) @[ -z "$(Q)" ] || echo 'LD $@' $(Q) $(CC) $(LDFLAGS) -o $@ $(fade_objs) @fade_ldflags@ -para_server: $(server_command_lists_ch) $(server_objs) +para_server: $(server_objs) @[ -z "$(Q)" ] || echo 'LD $@' $(Q) $(CC) $(LDFLAGS) -o $@ $(server_objs) @server_ldflags@ diff --git a/NEWS b/NEWS index a79cc29f..8bb2862e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ 0.4.9 (to be announced) "hybrid causality" ------------------------------------------ +Support for another audio format and many small improvements/fixes +all over the place. + + - Support for flac, the free lossless audio codec. - Fix for an endless loop in the mp3 decoder for certain (corrupt) mp3 files. - autogen.sh now detects a distcc setup and adjusts the @@ -15,6 +19,11 @@ communication between para_server and para_audiod. - The alsa writer eats up less CPU cycles when configured to use the DMIX plugin. + - Simplified and unified receiver code. + - Makefile cleanups. + - Commands which print a list of matching audio files now + emit a meaningful error message if no audio file matched the + given pattern(s). -------------------------------------- 0.4.8 (2011-08-19) "nested assignment" diff --git a/afs.c b/afs.c index 3f378051..78d8571f 100644 --- a/afs.c +++ b/afs.c @@ -363,7 +363,10 @@ static int action_if_pattern_matches(struct osl_row *row, void *data) continue; if (ret) return -E_FNMATCH; - return pmd->action(pmd->table, row, name, pmd->data); + ret = pmd->action(pmd->table, row, name, pmd->data); + if (ret >= 0) + pmd->num_matches++; + return ret; } return 1; } diff --git a/afs.h b/afs.h index f54aa87c..2fdefa70 100644 --- a/afs.h +++ b/afs.h @@ -181,6 +181,8 @@ struct pattern_match_data { struct osl_object patterns; /** Data pointer passed to the action function. */ void *data; + /** Gets increased by one for each match. */ + unsigned num_matches; /** For each matching row, this function will be called. */ int (*action)(struct osl_table *table, struct osl_row *row, const char *name, void *data); }; diff --git a/aft.c b/aft.c index 8c31906a..d2113f1c 100644 --- a/aft.c +++ b/aft.c @@ -1369,8 +1369,11 @@ static void com_ls_callback(int fd, const struct osl_object *query) prepare_ls_row)); if (ret < 0) goto out; - if (!opts->num_matching_paths) + if (opts->num_matching_paths == 0) { + if (opts->num_patterns > 0) + para_printf(&b, "no matches\n"); goto out; + } ret = sort_matching_paths(opts); if (ret < 0) goto out; @@ -2025,8 +2028,6 @@ struct touch_action_data { struct com_touch_options *cto; /** Message buffer. */ struct para_buffer pb; - /** How many audio files matched the given pattern. */ - unsigned num_matches; }; static int touch_audio_file(__a_unused struct osl_table *table, @@ -2073,7 +2074,6 @@ static int touch_audio_file(__a_unused struct osl_table *table, if (tad->cto->amp >= 0) new_afsi.amp = tad->cto->amp; } - tad->num_matches++; save_afsi(&new_afsi, &obj); /* in-place update */ aced.aft_row = row; aced.old_afsi = &old_afsi; @@ -2105,9 +2105,8 @@ static void com_touch_callback(int fd, const struct osl_object *query) ret = for_each_matching_row(&pmd); if (ret < 0) ret2 = para_printf(&tad.pb, "%s\n", para_strerror(-ret)); - else - if (!tad.num_matches) - ret2 = para_printf(&tad.pb, "no matches\n"); + else if (pmd.num_matches == 0) + ret2 = para_printf(&tad.pb, "no matches\n"); if (ret2 >= 0 && tad.pb.offset) pass_buffer_as_shm(tad.pb.buf, tad.pb.offset, &fd); free(tad.pb.buf); @@ -2203,8 +2202,6 @@ struct com_rm_action_data { uint32_t flags; /** Message buffer. */ struct para_buffer pb; - /** Number of audio files removed. */ - unsigned num_removed; }; static int remove_audio_file(__a_unused struct osl_table *table, @@ -2222,8 +2219,6 @@ static int remove_audio_file(__a_unused struct osl_table *table, ret = osl(osl_del_row(audio_file_table, row)); if (ret < 0) para_printf(&crd->pb, "%s: %s\n", name, para_strerror(-ret)); - else - crd->num_removed++; return ret; } @@ -2253,11 +2248,11 @@ static void com_rm_callback(int fd, const struct osl_object *query) para_printf(&crd.pb, "%s\n", para_strerror(-ret)); return; } - if (!crd.num_removed && !(crd.flags & RM_FLAG_FORCE)) + if ((pmd.num_matches == 0) && !(crd.flags & RM_FLAG_FORCE)) ret = para_printf(&crd.pb, "no matches -- nothing removed\n"); - else { - if (crd.flags & RM_FLAG_VERBOSE) - ret = para_printf(&crd.pb, "removed %u files\n", crd.num_removed); + else if (crd.flags & RM_FLAG_VERBOSE) { + ret = para_printf(&crd.pb, "removed %u files\n", + pmd.num_matches); } if (ret >= 0 && crd.pb.offset) pass_buffer_as_shm(crd.pb.buf, crd.pb.offset, &fd); @@ -2326,8 +2321,6 @@ enum cpsi_flags { struct cpsi_action_data { /** command line flags (see \ref cpsi_flags). */ unsigned flags; - /** Number of audio files changed. */ - unsigned num_copied; /** Message buffer. */ struct para_buffer pb; /** Values are copied from here. */ @@ -2359,7 +2352,6 @@ static int copy_selector_info(__a_unused struct osl_table *table, if (cad->flags & CPSI_FLAG_COPY_ATTRIBUTES) target_afsi.attributes = cad->source_afsi.attributes; save_afsi(&target_afsi, &target_afsi_obj); /* in-place update */ - cad->num_copied++; if (cad->flags & CPSI_FLAG_VERBOSE) { ret = para_printf(&cad->pb, "copied afsi to %s\n", name); if (ret < 0) @@ -2402,9 +2394,9 @@ out: if (ret < 0) para_printf(&cad.pb, "%s\n", para_strerror(-ret)); else if (cad.flags & CPSI_FLAG_VERBOSE) { - if (cad.num_copied) + if (pmd.num_matches > 0) para_printf(&cad.pb, "copied requested afsi from %s " - "to %u files\n", source_path, cad.num_copied); + "to %u files\n", source_path, pmd.num_matches); else para_printf(&cad.pb, "nothing copied\n"); } diff --git a/blob.c b/blob.c index 707c6c62..2545aea9 100644 --- a/blob.c +++ b/blob.c @@ -156,6 +156,8 @@ static void com_lsblob_callback(struct osl_table *table, ret = for_each_matching_row(&pmd); if (ret < 0) para_printf(&lbad.pb, "%s\n", para_strerror(-ret)); + else if (pmd.num_matches == 0 && pmd.patterns.size > 0) + para_printf(&lbad.pb, "no matches\n"); if (lbad.pb.offset) pass_buffer_as_shm(lbad.pb.buf, lbad.pb.offset, &fd); free(lbad.pb.buf); @@ -203,9 +205,9 @@ static int cat_blob(struct osl_table *table, struct osl_row *row, ret = osl(osl_open_disk_object(table, row, BLOBCOL_DEF, &obj)); if (ret < 0) - return ret; - if (obj.size) - ret = pass_buffer_as_shm(obj.data, obj.size, data); + return (ret == osl(-E_OSL_EMPTY))? 0 : ret; + assert(obj.size > 0); + ret = pass_buffer_as_shm(obj.data, obj.size, data); ret2 = osl(osl_close_disk_object(&obj)); return (ret < 0)? ret : ret2; } @@ -223,6 +225,10 @@ static void com_catblob_callback(struct osl_table *table, int fd, .action = cat_blob }; for_each_matching_row(&pmd); + if (pmd.num_matches == 0) { + char err_msg[] = "no matches\n"; + pass_buffer_as_shm(err_msg, sizeof(err_msg), &fd); + } } static int com_catblob(callback_function *f, struct stream_cipher_context *scc, int argc, @@ -238,8 +244,6 @@ static int com_catblob(callback_function *f, struct stream_cipher_context *scc, struct rmblob_data { /** Message buffer. */ struct para_buffer pb; - /** Number of removed blobs. */ - unsigned num_removed; }; static int remove_blob(struct osl_table *table, struct osl_row *row, @@ -251,7 +255,6 @@ static int remove_blob(struct osl_table *table, struct osl_row *row, para_printf(&rmbd->pb, "%s: %s\n", name, para_strerror(-ret)); return ret; } - rmbd->num_removed++; return 1; } @@ -260,7 +263,6 @@ static void com_rmblob_callback(struct osl_table *table, int fd, { int ret, ret2 = 0; struct rmblob_data rmbd = { - .num_removed = 0, .pb = { .max_size = shm_get_shmmax(), .private_data = &fd, @@ -282,10 +284,10 @@ static void com_rmblob_callback(struct osl_table *table, int fd, if (ret2 < 0) goto out; } - if (!rmbd.num_removed) + if (pmd.num_matches == 0) ret2 = para_printf(&rmbd.pb, "no matches, nothing removed\n"); else { - ret2 = para_printf(&rmbd.pb, "removed %d blobs\n", rmbd.num_removed); + ret2 = para_printf(&rmbd.pb, "removed %d blobs\n", pmd.num_matches); afs_event(BLOB_RENAME, NULL, table); } out: diff --git a/daemon.c b/daemon.c index 541e44de..0bf2f0ac 100644 --- a/daemon.c +++ b/daemon.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "para.h" #include "daemon.h" diff --git a/dccp_recv.c b/dccp_recv.c index a9eab006..41518539 100644 --- a/dccp_recv.c +++ b/dccp_recv.c @@ -27,33 +27,15 @@ #include "dccp_recv.cmdline.h" -/** - * data specific to the dccp receiver - * - * \sa receiver receiver_node - */ -struct private_dccp_recv_data { - /** the file descriptor for the dccp socket */ - int fd; - struct btr_pool *btrp; -}; - static void dccp_recv_close(struct receiver_node *rn) { - struct private_dccp_recv_data *pdd = rn->private_data; - - if (!pdd) - return; - if (pdd->fd > 0) - close(pdd->fd); - btr_pool_free(pdd->btrp); - free(pdd); - rn->private_data = NULL; + if (rn->fd > 0) + close(rn->fd); + btr_pool_free(rn->btrp); } static int dccp_recv_open(struct receiver_node *rn) { - struct private_dccp_recv_data *pdd; struct dccp_recv_args_info *conf = rn->conf; struct flowopts *fo = NULL; uint8_t *ccids = NULL; @@ -87,9 +69,8 @@ static int dccp_recv_open(struct receiver_node *rn) ret = mark_fd_nonblocking(fd); if (ret < 0) goto err; - rn->private_data = pdd = para_calloc(sizeof(struct private_dccp_recv_data)); - pdd->btrp = btr_pool_new("dccp_recv", 320 * 1024); - pdd->fd = fd; + rn->btrp = btr_pool_new("dccp_recv", 320 * 1024); + rn->fd = fd; return 1; err: close(fd); @@ -136,18 +117,16 @@ static void *dccp_recv_parse_config(int argc, char **argv) static void dccp_recv_pre_select(struct sched *s, struct task *t) { struct receiver_node *rn = container_of(t, struct receiver_node, task); - struct private_dccp_recv_data *pdd = rn->private_data; t->error = 0; if (generic_recv_pre_select(s, t) <= 0) return; - para_fd_set(pdd->fd, &s->rfds, &s->max_fileno); + para_fd_set(rn->fd, &s->rfds, &s->max_fileno); } static void dccp_recv_post_select(struct sched *s, struct task *t) { struct receiver_node *rn = container_of(t, struct receiver_node, task); - struct private_dccp_recv_data *pdd = rn->private_data; struct btr_node *btrn = rn->btrn; struct iovec iov[2]; int ret, iovcnt; @@ -156,18 +135,18 @@ static void dccp_recv_post_select(struct sched *s, struct task *t) ret = btr_node_status(btrn, 0, BTR_NT_ROOT); if (ret <= 0) goto out; - iovcnt = btr_pool_get_buffers(pdd->btrp, iov); + iovcnt = btr_pool_get_buffers(rn->btrp, iov); ret = -E_DCCP_OVERRUN; if (iovcnt == 0) goto out; - ret = readv_nonblock(pdd->fd, iov, iovcnt, &s->rfds, &num_bytes); + ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes); if (num_bytes == 0) goto out; if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */ - btr_add_output_pool(pdd->btrp, num_bytes, btrn); + btr_add_output_pool(rn->btrp, num_bytes, btrn); else { /* both buffers contain data */ - btr_add_output_pool(pdd->btrp, iov[0].iov_len, btrn); - btr_add_output_pool(pdd->btrp, num_bytes - iov[0].iov_len, btrn); + btr_add_output_pool(rn->btrp, iov[0].iov_len, btrn); + btr_add_output_pool(rn->btrp, num_bytes - iov[0].iov_len, btrn); } out: if (ret >= 0) diff --git a/http_recv.c b/http_recv.c index 5717692c..e6031e75 100644 --- a/http_recv.c +++ b/http_recv.c @@ -44,24 +44,6 @@ struct private_http_recv_data { * \sa receiver::open, receiver_node. */ enum http_recv_status status; - /** - * The file descriptor used for receiving the http stream. - * - * The pre_select function of the http receiver adds this file descriptor to - * the set of file descriptors which are checked for reading/writing (depending - * on the current status) by the select loop of the application (para_audiod or - * para_recv). - * - * The post_select function of the http receiver uses \a fd, if ready, to - * establish the http connection, and updates \a status according to the new - * state of the connection. As soon as \a status is \p HTTP_STREAMING, \a fd is - * going to be only checked for reading. If data is available, it is read into - * the output buffer of the receiver node by post_select. - * - * \sa receiver::pre_select receiver::post_select receiver_node, http_recv_status - */ - int fd; - struct btr_pool *btrp; }; static char *make_request_msg(void) @@ -82,43 +64,48 @@ static void http_recv_pre_select(struct sched *s, struct task *t) if (generic_recv_pre_select(s, t) <= 0) return; if (phd->status == HTTP_CONNECTED) - para_fd_set(phd->fd, &s->wfds, &s->max_fileno); + para_fd_set(rn->fd, &s->wfds, &s->max_fileno); else - para_fd_set(phd->fd, &s->rfds, &s->max_fileno); + para_fd_set(rn->fd, &s->rfds, &s->max_fileno); } +/* + * Establish the http connection. If already established, fill the buffer pool + * area with data read from the socket. In any case, update the state of the + * connection if necessary. + */ static void http_recv_post_select(struct sched *s, struct task *t) { struct receiver_node *rn = container_of(t, struct receiver_node, task); struct private_http_recv_data *phd = rn->private_data; struct btr_node *btrn = rn->btrn; - int ret; - char *buf; - size_t sz, n; + int ret, iovcnt; + struct iovec iov[2]; + size_t num_bytes; t->error = 0; ret = btr_node_status(btrn, 0, BTR_NT_ROOT); if (ret < 0) - goto err; + goto out; if (ret == 0) return; if (phd->status == HTTP_CONNECTED) { char *rq; - if (!FD_ISSET(phd->fd, &s->wfds)) + if (!FD_ISSET(rn->fd, &s->wfds)) return; rq = make_request_msg(); PARA_INFO_LOG("sending http request\n"); - ret = send_va_buffer(phd->fd, "%s", rq); + ret = send_va_buffer(rn->fd, "%s", rq); free(rq); if (ret < 0) - goto err; + goto out; phd->status = HTTP_SENT_GET_REQUEST; return; } if (phd->status == HTTP_SENT_GET_REQUEST) { - ret = read_pattern(phd->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG), &s->rfds); + ret = read_pattern(rn->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG), &s->rfds); if (ret < 0) - goto err; + goto out; if (ret == 0) return; PARA_INFO_LOG("received ok msg, streaming\n"); @@ -126,25 +113,29 @@ static void http_recv_post_select(struct sched *s, struct task *t) return; } ret = -E_HTTP_RECV_OVERRUN; - sz = btr_pool_get_buffer(phd->btrp, &buf); - if (sz == 0) - goto err; - ret = read_nonblock(phd->fd, buf, sz, &s->rfds, &n); - if (n > 0) - btr_add_output_pool(phd->btrp, n, btrn); + iovcnt = btr_pool_get_buffers(rn->btrp, iov); + if (iovcnt == 0) + goto out; + ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes); + if (num_bytes == 0) + goto out; + if (num_bytes <= iov[0].iov_len) /* only the first buffer was filled */ + btr_add_output_pool(rn->btrp, num_bytes, btrn); + else { /* both buffers contain data */ + btr_add_output_pool(rn->btrp, iov[0].iov_len, btrn); + btr_add_output_pool(rn->btrp, num_bytes - iov[0].iov_len, btrn); + } +out: if (ret >= 0) return; -err: btr_remove_node(rn->btrn); t->error = ret; } static void http_recv_close(struct receiver_node *rn) { - struct private_http_recv_data *phd = rn->private_data; - - close(phd->fd); - btr_pool_free(phd->btrp); + close(rn->fd); + btr_pool_free(rn->btrp); free(rn->private_data); } @@ -174,9 +165,9 @@ static int http_recv_open(struct receiver_node *rn) return ret; } rn->private_data = phd = para_calloc(sizeof(struct private_http_recv_data)); - phd->fd = fd; + rn->fd = fd; phd->status = HTTP_CONNECTED; - phd->btrp = btr_pool_new("http_recv", 320 * 1024); + rn->btrp = btr_pool_new("http_recv", 320 * 1024); return 1; } diff --git a/recv.h b/recv.h index 7555dfb4..92b63d27 100644 --- a/recv.h +++ b/recv.h @@ -20,6 +20,21 @@ struct receiver_node { struct task task; /** The receiver node is always the root of the buffer tree. */ struct btr_node *btrn; + /** Each receiver node maintains a buffer pool for the received data. */ + struct btr_pool *btrp; + /** + * The file descriptor to receive the stream. + * + * The pre_select function of the receiver adds this file descriptor to + * the set of file descriptors which are watched for readability or + * writability, depending on the state of the connection (if any). + * + * If \a fd is readable, the post_select function of the receiver reads + * data from this fd into the buffer pool area of \a btrp. + * + * \sa \ref receiver. + */ + int fd; }; /** diff --git a/udp_recv.c b/udp_recv.c index 45d24eae..964b60d4 100644 --- a/udp_recv.c +++ b/udp_recv.c @@ -22,25 +22,13 @@ #include "fd.h" #include "buffer_tree.h" -/** - * Data specific to the udp receiver. - * - * \sa \ref receiver, \ref receiver_node. - */ -struct private_udp_recv_data { - /** The socket file descriptor. */ - int fd; - struct btr_pool *btrp; -}; - static void udp_recv_pre_select(struct sched *s, struct task *t) { struct receiver_node *rn = container_of(t, struct receiver_node, task); - struct private_udp_recv_data *purd = rn->private_data; if (generic_recv_pre_select(s, t) <= 0) return; - para_fd_set(purd->fd, &s->rfds, &s->max_fileno); + para_fd_set(rn->fd, &s->rfds, &s->max_fileno); } static int udp_check_eof(size_t sz, struct iovec iov[2]) @@ -64,7 +52,6 @@ static int udp_check_eof(size_t sz, struct iovec iov[2]) static void udp_recv_post_select(__a_unused struct sched *s, struct task *t) { struct receiver_node *rn = container_of(t, struct receiver_node, task); - struct private_udp_recv_data *purd = rn->private_data; struct btr_node *btrn = rn->btrn; size_t num_bytes; struct iovec iov[2]; @@ -74,11 +61,11 @@ static void udp_recv_post_select(__a_unused struct sched *s, struct task *t) ret = btr_node_status(btrn, 0, BTR_NT_ROOT); if (ret <= 0) goto out; - iovcnt = btr_pool_get_buffers(purd->btrp, iov); + iovcnt = btr_pool_get_buffers(rn->btrp, iov); ret = -E_UDP_OVERRUN; if (iovcnt == 0) goto out; - ret = readv_nonblock(purd->fd, iov, iovcnt, &s->rfds, &num_bytes); + ret = readv_nonblock(rn->fd, iov, iovcnt, &s->rfds, &num_bytes); if (num_bytes == 0) goto out; readv_ret = ret; @@ -86,10 +73,10 @@ static void udp_recv_post_select(__a_unused struct sched *s, struct task *t) if (ret < 0) goto out; if (iov[0].iov_len >= num_bytes) - btr_add_output_pool(purd->btrp, num_bytes, btrn); + btr_add_output_pool(rn->btrp, num_bytes, btrn); else { /* both buffers contain data */ - btr_add_output_pool(purd->btrp, iov[0].iov_len, btrn); - btr_add_output_pool(purd->btrp, num_bytes - iov[0].iov_len, + btr_add_output_pool(rn->btrp, iov[0].iov_len, btrn); + btr_add_output_pool(rn->btrp, num_bytes - iov[0].iov_len, btrn); } ret = readv_ret; @@ -98,18 +85,15 @@ out: return; btr_remove_node(btrn); t->error = ret; - close(purd->fd); - purd->fd = -1; + close(rn->fd); + rn->fd = -1; } static void udp_recv_close(struct receiver_node *rn) { - struct private_udp_recv_data *purd = rn->private_data; - - if (purd->fd >= 0) - close(purd->fd); - btr_pool_free(purd->btrp); - free(rn->private_data); + if (rn->fd >= 0) + close(rn->fd); + btr_pool_free(rn->btrp); } static void *udp_recv_parse_config(int argc, char **argv) @@ -188,36 +172,31 @@ err: static int udp_recv_open(struct receiver_node *rn) { - struct private_udp_recv_data *purd; struct udp_recv_args_info *c = rn->conf; char *iface = c->iface_given ? c->iface_arg : NULL; int ret; - rn->private_data = para_calloc(sizeof(struct private_udp_recv_data)); - purd = rn->private_data; - ret = makesock(IPPROTO_UDP, 1, c->host_arg, c->port_arg, NULL); if (ret < 0) goto err; - purd->fd = ret; + rn->fd = ret; - ret = mcast_receiver_setup(purd->fd, iface); + ret = mcast_receiver_setup(rn->fd, iface); if (ret < 0) { - close(purd->fd); + close(rn->fd); goto err; } - ret = mark_fd_nonblocking(purd->fd); + ret = mark_fd_nonblocking(rn->fd); if (ret < 0) { - close(purd->fd); + close(rn->fd); goto err; } PARA_INFO_LOG("receiving from %s:%d, fd=%d\n", c->host_arg, - c->port_arg, purd->fd); - purd->btrp = btr_pool_new("udp_recv", 320 * 1024); - return purd->fd; + c->port_arg, rn->fd); + rn->btrp = btr_pool_new("udp_recv", 320 * 1024); + return rn->fd; err: - free(rn->private_data); return ret; }