From b2f4aeb035a06b01c4b9404c19e993b206f606b3 Mon Sep 17 00:00:00 2001 From: cohe6423 Date: Mon, 18 Jun 2012 23:45:03 +0300 Subject: [PATCH 1/9] Needed when string length equal 1. exemple: H --- src/htsmsg_xml.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/htsmsg_xml.c b/src/htsmsg_xml.c index 7c494770..77e27b00 100644 --- a/src/htsmsg_xml.c +++ b/src/htsmsg_xml.c @@ -1,6 +1,6 @@ /* * Functions converting HTSMSGs to/from XML - * Copyright (C) 2008 Andreas Öman + * Copyright (C) 2008 Andreas �man * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -707,7 +707,7 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) *cc->cc_end = 0; free(cc); - } else if(c > 1) { + } else if(c > 0) { body = malloc(c + 1); c = 0; From 759de687130b740527fe0ac24b2aa1f7a1a953c3 Mon Sep 17 00:00:00 2001 From: Martin Mrvka Date: Mon, 18 Jun 2012 23:00:54 +0200 Subject: [PATCH 2/9] dvb: added extra priority per adapter --- src/dvb/dvb.h | 4 ++++ src/dvb/dvb_adapter.c | 19 +++++++++++++++++++ src/service.c | 26 ++++++++++++++++++++++---- src/webui/extjs_dvb.c | 4 ++++ src/webui/static/app/dvb.js | 7 ++++++- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 80ff4556..8fac1013 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -205,6 +205,8 @@ typedef struct th_dvb_adapter { int tda_unc_is_delta; /* 1 if we believe FE_READ_UNCORRECTED_BLOCKS * return dela values */ + uint32_t tda_extrapriority; // extra priority for choosing the best adapter/service + } th_dvb_adapter_t; @@ -247,6 +249,8 @@ htsmsg_t *dvb_adapter_build_msg(th_dvb_adapter_t *tda); htsmsg_t *dvb_fe_opts(th_dvb_adapter_t *tda, const char *which); +void dvb_adapter_set_extrapriority(th_dvb_adapter_t *tda, int extrapriority); + /** * DVB Multiplex */ diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 433107ae..0337aa9d 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -86,6 +86,7 @@ tda_save(th_dvb_adapter_t *tda) htsmsg_add_u32(m, "dump_muxes", tda->tda_dump_muxes); htsmsg_add_u32(m, "nitoid", tda->tda_nitoid); htsmsg_add_u32(m, "diseqc_version", tda->tda_diseqc_version); + htsmsg_add_u32(m, "extrapriority", tda->tda_extrapriority); hts_settings_save(m, "dvbadapters/%s", tda->tda_identifier); htsmsg_destroy(m); } @@ -232,6 +233,23 @@ dvb_adapter_set_diseqc_version(th_dvb_adapter_t *tda, unsigned int v) tda_save(tda); } +/** + * + */ +void +dvb_adapter_set_extrapriority(th_dvb_adapter_t *tda, int extrapriority) +{ + lock_assert(&global_lock); + + if(tda->tda_extrapriority == extrapriority) + return; + + tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" extra priority \"%d\" changed to \"%d\"", + tda->tda_displayname, tda->tda_extrapriority, extrapriority); + + tda->tda_extrapriority = extrapriority; + tda_save(tda); +} /** * @@ -383,6 +401,7 @@ dvb_adapter_init(uint32_t adapter_mask) htsmsg_get_u32(c, "dump_muxes", &tda->tda_dump_muxes); htsmsg_get_u32(c, "nitoid", &tda->tda_nitoid); htsmsg_get_u32(c, "diseqc_version", &tda->tda_diseqc_version); + htsmsg_get_u32(c, "extrapriority", &tda->tda_extrapriority); } htsmsg_destroy(l); } diff --git a/src/service.c b/src/service.c index 515c3979..7b76ebfb 100644 --- a/src/service.c +++ b/src/service.c @@ -231,7 +231,7 @@ service_start(service_t *t, unsigned int weight, int force_start) static int dvb_extra_prio(th_dvb_adapter_t *tda) { - return tda->tda_hostconnection * 10; + return tda->tda_extrapriority + tda->tda_hostconnection * 10; } /** @@ -285,10 +285,19 @@ servicecmp(const void *A, const void *B) service_t *a = *(service_t **)A; service_t *b = *(service_t **)B; - int q = service_get_quality(a) - service_get_quality(b); + /* only check quality if both adapters have the same prio + * + * there needs to be a much more sophisticated algorithm to take priority and quality into account + * additional, it may be problematic, since a higher priority value lowers the ranking + * + */ + if (dvb_extra_prio(a->s_dvb_mux_instance->tdmi_adapter) == dvb_extra_prio(b->s_dvb_mux_instance->tdmi_adapter)) { - if(q != 0) - return q; /* Quality precedes priority */ + int q = service_get_quality(a) - service_get_quality(b); + + if(q != 0) + return q; /* Quality precedes priority */ + } return service_get_prio(a) - service_get_prio(b); } @@ -335,6 +344,9 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo, continue; } vec[cnt++] = t; + tvhlog(LOG_DEBUG, "Service", + "%s: Adding adapter \"%s\" for service \"%s\"", + loginfo, t->s_dvb_mux_instance->tdmi_identifier, service_nicename(t)); } /* Sort services, lower priority should come come earlier in the vector @@ -358,6 +370,9 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo, /* First, try all services without stealing */ for(i = off; i < cnt; i++) { t = vec[i]; + tvhlog(LOG_DEBUG, "Service", "%s: Probing adapter \"%s\" without stealing for service \"%s\"", + loginfo, t->s_dvb_mux_instance->tdmi_identifier, service_nicename(t)); + if(t->s_status == SERVICE_RUNNING) return t; if((r = service_start(t, 0, 0)) == 0) @@ -372,6 +387,9 @@ service_find(channel_t *ch, unsigned int weight, const char *loginfo, for(i = off; i < cnt; i++) { t = vec[i]; + tvhlog(LOG_DEBUG, "Service", "%s: Probing adapter \"%s\" with weight %d for service \"%s\"", + loginfo, t->s_dvb_mux_instance->tdmi_identifier, weight, service_nicename(t)); + if((r = service_start(t, weight, 0)) == 0) return t; *errorp = r; diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 4080868e..b9b918ba 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -156,6 +156,7 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) ((const char *[]){"DiSEqC 1.0 / 2.0", "DiSEqC 1.1 / 2.1"}) [tda->tda_diseqc_version % 2]); + htsmsg_add_u32(r, "extrapriority", tda->tda_extrapriority); out = json_single_record(r, "dvbadapters"); } else if(!strcmp(op, "save")) { @@ -185,6 +186,9 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) dvb_adapter_set_diseqc_version(tda, 1); } + if((s = http_arg_get(&hc->hc_req_args, "extrapriority")) != NULL) + dvb_adapter_set_extrapriority(tda, atoi(s)); + out = htsmsg_create_map(); htsmsg_add_u32(out, "success", 1); } else if(!strcmp(op, "addnetwork")) { diff --git a/src/webui/static/app/dvb.js b/src/webui/static/app/dvb.js index 5b7d0576..9c7b7761 100644 --- a/src/webui/static/app/dvb.js +++ b/src/webui/static/app/dvb.js @@ -1106,7 +1106,7 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { var confreader = new Ext.data.JsonReader({ root: 'dvbadapters' }, ['name', 'automux', 'idlescan', 'diseqcversion', 'qmon', - 'dumpmux', 'nitoid']); + 'dumpmux', 'nitoid','extrapriority']); function saveConfForm () { @@ -1150,6 +1150,11 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { fieldLabel: 'NIT-o Network ID', name: 'nitoid', width: 50 + }, + { + fieldLabel: 'Extra priority', + name: 'extrapriority', + width: 50 } ]; From 01c619482f3ef08baea66157a5e65237c7d7e1df Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sat, 16 Jun 2012 21:04:55 +0100 Subject: [PATCH 3/9] Expose DVB table API within the rest of the app (needed by new grabbers). --- src/dvb/dvb.h | 51 ++++++++++++++++++++++++++++++++++++++++++ src/dvb/dvb_tables.c | 53 ++------------------------------------------ 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 8fac1013..2cb5b943 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -209,6 +209,46 @@ typedef struct th_dvb_adapter { } th_dvb_adapter_t; +/** + * DVB table + */ +typedef struct th_dvb_table { + /** + * Flags, must never be changed after creation. + * We inspect it without holding global_lock + */ + int tdt_flags; + + /** + * Cycle queue + * Tables that did not get a fd or filter in hardware will end up here + * waiting for any other table to be received so it can reuse that fd. + * Only linked if fd == -1 + */ + TAILQ_ENTRY(th_dvb_table) tdt_pending_link; + + /** + * File descriptor for filter + */ + int tdt_fd; + + LIST_ENTRY(th_dvb_table) tdt_link; + + char *tdt_name; + + void *tdt_opaque; + int (*tdt_callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, + uint8_t tableid, void *opaque); + + + int tdt_count; + int tdt_pid; + + struct dmx_sct_filter_params *tdt_fparams; + + int tdt_id; + +} th_dvb_table_t; extern struct th_dvb_adapter_queue dvb_adapters; @@ -335,6 +375,17 @@ void dvb_table_add_default(th_dvb_mux_instance_t *tdmi); void dvb_table_flush_all(th_dvb_mux_instance_t *tdmi); +struct dmx_sct_filter_params *dvb_fparams_alloc(void); +void +tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams, + int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, + uint8_t tableid, void *opaque), void *opaque, + const char *name, int flags, int pid, th_dvb_table_t *tdt); + +#define TDT_CRC 0x1 +#define TDT_QUICKREQ 0x2 +#define TDT_CA 0x4 + /** * Satellite configuration */ diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index f2e83653..03069044 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -42,68 +42,19 @@ #include "notify.h" #include "cwc.h" -#define TDT_CRC 0x1 -#define TDT_QUICKREQ 0x2 -#define TDT_CA 0x4 - static void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid); static int tdt_id_tally; -/** - * - */ -typedef struct th_dvb_table { - /** - * Flags, must never be changed after creation. - * We inspect it without holding global_lock - */ - int tdt_flags; - - /** - * Cycle queue - * Tables that did not get a fd or filter in hardware will end up here - * waiting for any other table to be received so it can reuse that fd. - * Only linked if fd == -1 - */ - TAILQ_ENTRY(th_dvb_table) tdt_pending_link; - - /** - * File descriptor for filter - */ - int tdt_fd; - - LIST_ENTRY(th_dvb_table) tdt_link; - - char *tdt_name; - - void *tdt_opaque; - int (*tdt_callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, - uint8_t tableid, void *opaque); - - - int tdt_count; - int tdt_pid; - - struct dmx_sct_filter_params *tdt_fparams; - - int tdt_id; - -} th_dvb_table_t; - - - - /** * Helper for preparing a section filter parameter struct */ -static struct dmx_sct_filter_params * +struct dmx_sct_filter_params * dvb_fparams_alloc(void) { return calloc(1, sizeof(struct dmx_sct_filter_params)); } - /** * */ @@ -323,7 +274,7 @@ dvb_tdt_destroy(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi, /** * Add a new DVB table */ -static void +void tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams, int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tableid, void *opaque), void *opaque, From e183645081af85ae3a85c9cc43088d7a22b2b901 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Mon, 18 Jun 2012 13:38:01 +0100 Subject: [PATCH 4/9] Allow multiple callbacks per PID (with limitations). --- src/dvb/dvb_tables.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index 03069044..b68ba3d1 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -282,8 +282,13 @@ tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams, { th_dvb_table_t *t; + // Allow multiple entries per PID, but only one per callback/opaque instance + // TODO: this could mean reading the same data multiple times, and not + // sure how well this will work! I know Andreas has some thoughts on + // this LIST_FOREACH(t, &tdmi->tdmi_tables, tdt_link) { - if(pid == t->tdt_pid) { + if(pid == t->tdt_pid && + tdt->tdt_callback == callback && tdt->tdt_opaque == opaque) { free(tdt); free(fparams); return; From 5b9d4311db9b483384b7a7020c1e1c0291eb9b09 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Tue, 19 Jun 2012 11:28:04 +0100 Subject: [PATCH 5/9] Improve escape handling in json parser. --- src/htsmsg_json.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/htsmsg_json.c b/src/htsmsg_json.c index a302247d..ff1aa6f7 100644 --- a/src/htsmsg_json.c +++ b/src/htsmsg_json.c @@ -164,7 +164,11 @@ htsmsg_json_parse_string(const char *s, const char **endp) if(*s == '\\') { esc = 1; - } else if(*s == '"' && s[-1] != '\\') { + /* skip the escape */ + s++; + if (*s == 'u') s += 4; + // Note: we could detect the lack of support here! + } else if(*s == '"') { *endp = s + 1; @@ -184,6 +188,8 @@ htsmsg_json_parse_string(const char *s, const char **endp) a++; if(*a == 'b') *b++ = '\b'; + else if(*a == '\\') + *b++ = '\\'; else if(*a == 'f') *b++ = '\f'; else if(*a == 'n') From c8847503b1aee92e4df0ec8eb72891a1aea980db Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Tue, 19 Jun 2012 11:40:08 +0100 Subject: [PATCH 6/9] Some extensions to the htsmsg API, including fix for single length XML strings and cdata processing (previously in xmltv code). --- src/htsmsg.c | 34 ++++++++++++++++++++++++++++++++++ src/htsmsg.h | 14 ++++++++++++++ src/htsmsg_xml.c | 28 +++++++++++++++++++++++++++- src/htsmsg_xml.h | 2 ++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/htsmsg.c b/src/htsmsg.c index 6de14e4e..dab63ee0 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -196,6 +196,16 @@ htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64) f->hmf_s64 = s64; } +/* + * + */ +void +htsmsg_add_u64(htsmsg_t *msg, const char *name, uint64_t u64) +{ + htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_S64, HMF_NAME_ALLOCED); + f->hmf_s64 = u64; +} + /* * */ @@ -306,6 +316,30 @@ htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p) return 0; } +/** + * + */ +int +htsmsg_get_u64(htsmsg_t *msg, const char *name, uint64_t *u64p) +{ + htsmsg_field_t *f; + + if((f = htsmsg_field_find(msg, name)) == NULL) + return HTSMSG_ERR_FIELD_NOT_FOUND; + + switch(f->hmf_type) { + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + case HMF_STR: + *u64p = strtoull(f->hmf_str, NULL, 0); + break; + case HMF_S64: + *u64p = f->hmf_s64; + break; + } + return 0; +} + /* * diff --git a/src/htsmsg.h b/src/htsmsg.h index 6df3abf6..c601394a 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -107,6 +107,11 @@ void htsmsg_add_u32(htsmsg_t *msg, const char *name, uint32_t u32); */ void htsmsg_add_s32(htsmsg_t *msg, const char *name, int32_t s32); +/** + * Add an integer field where source is unsigned 64 bit. + */ +void htsmsg_add_u64(htsmsg_t *msg, const char *name, uint64_t u64); + /** * Add an integer field where source is signed 64 bit. */ @@ -171,6 +176,15 @@ int htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p); */ int htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p); +/** + * Get an integer as an unsigned 64 bit integer. + * + * @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist + * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or + * out of range for the requested storage. + */ +int htsmsg_get_u64(htsmsg_t *msg, const char *name, uint64_t *u64p); + /** * Get pointer to a binary field. No copying of data is performed. * diff --git a/src/htsmsg_xml.c b/src/htsmsg_xml.c index 77e27b00..e9f69165 100644 --- a/src/htsmsg_xml.c +++ b/src/htsmsg_xml.c @@ -693,7 +693,7 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) } } - if(y == 1 && c > 1) { + if(y == 1 && c > 0) { /* One segment UTF-8 (or 7bit ASCII), use data directly from source */ @@ -865,3 +865,29 @@ htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize) return NULL; } + +/* + * Get cdata string field + */ +const char * +htsmsg_xml_get_cdata_str(htsmsg_t *tags, const char *name) +{ + htsmsg_t *sub; + if((sub = htsmsg_get_map(tags, name)) == NULL) + return NULL; + return htsmsg_get_str(sub, "cdata"); +} + +/* + * Get cdata u32 field + */ +int +htsmsg_xml_get_cdata_u32(htsmsg_t *tags, const char *name, uint32_t *u32) +{ + htsmsg_t *sub; + if((sub = htsmsg_get_map(tags, name)) == NULL) + return HTSMSG_ERR_FIELD_NOT_FOUND; + return htsmsg_get_u32(sub, "cdata", u32); +} + + diff --git a/src/htsmsg_xml.h b/src/htsmsg_xml.h index ff723ac0..16e548c2 100644 --- a/src/htsmsg_xml.h +++ b/src/htsmsg_xml.h @@ -23,5 +23,7 @@ #include "htsbuf.h" htsmsg_t *htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize); +const char *htsmsg_xml_get_cdata_str (htsmsg_t *tags, const char *tag); +int htsmsg_xml_get_cdata_u32 (htsmsg_t *tags, const char *tag, uint32_t *u32); #endif /* HTSMSG_XML_H_ */ From 21a97a176d4c9a45ce55b57a5f78813968cbcff3 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Wed, 6 Jun 2012 20:31:01 +0100 Subject: [PATCH 7/9] Move the reading from file descriptor into generic routine as I intend to reuse this function in the new EPG code. --- Makefile | 1 + src/file.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/file.h | 26 +++++++++++++++++ src/spawn.c | 59 ++------------------------------------- 4 files changed, 110 insertions(+), 56 deletions(-) create mode 100644 src/file.c create mode 100644 src/file.h diff --git a/Makefile b/Makefile index 52694582..b27448a6 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ SRCS = src/main.c \ src/tcp.c \ src/http.c \ src/notify.c \ + src/file.c \ src/epg.c \ src/xmltv.c \ src/spawn.c \ diff --git a/src/file.c b/src/file.c new file mode 100644 index 00000000..77316871 --- /dev/null +++ b/src/file.c @@ -0,0 +1,80 @@ +/* + * Process file functions + * Copyright (C) 2008 Andreas Öman + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define MAX_RDBUF_SIZE 8192 + +#include +#include +#include +#include +#include "queue.h" +#include "file.h" + +typedef struct file_read_buf { + TAILQ_ENTRY(file_read_buf) link; + int size; + char buf[MAX_RDBUF_SIZE]; +} file_read_buf_t; + +TAILQ_HEAD(file_read_buf_queue, file_read_buf); + +size_t file_readall ( int fd, char **outp ) +{ + int r, totalsize = 0; + struct file_read_buf_queue bufs; + file_read_buf_t *b = NULL; + char *outbuf; + + TAILQ_INIT(&bufs); + while(1) { + if(b == NULL) { + b = malloc(sizeof(file_read_buf_t)); + b->size = 0; + TAILQ_INSERT_TAIL(&bufs, b, link); + } + + r = read(fd, b->buf + b->size, MAX_RDBUF_SIZE - b->size); + if(r < 1) + break; + b->size += r; + totalsize += r; + if(b->size == MAX_RDBUF_SIZE) + b = NULL; + } + + close(fd); + + if(totalsize == 0) { + free(b); + *outp = NULL; + return 0; + } + + outbuf = malloc(totalsize + 1); + r = 0; + while((b = TAILQ_FIRST(&bufs)) != NULL) { + memcpy(outbuf + r, b->buf, b->size); + r+= b->size; + TAILQ_REMOVE(&bufs, b, link); + free(b); + } + assert(r == totalsize); + *outp = outbuf; + outbuf[totalsize] = 0; + return totalsize; +} diff --git a/src/file.h b/src/file.h new file mode 100644 index 00000000..9523a908 --- /dev/null +++ b/src/file.h @@ -0,0 +1,26 @@ +/* + * Process file operations + * Copyright (C) 2012 Adam Sutton + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FILE_H +#define FILE_H + +#include + +size_t file_readall ( int fd, char **outbuf ); + +#endif /* FILE_H */ diff --git a/src/spawn.c b/src/spawn.c index 9d59c597..953a2c79 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -28,6 +28,7 @@ #include #include "tvheadend.h" +#include "file.h" #include "spawn.h" extern char **environ; @@ -43,21 +44,6 @@ typedef struct spawn { } spawn_t; -/** - * Structs for reading back output from a spawn via a pipe - */ -TAILQ_HEAD(spawn_output_buf_queue, spawn_output_buf); - -#define MAX_SOB_SIZE 4000 - -typedef struct spawn_output_buf { - TAILQ_ENTRY(spawn_output_buf) sob_link; - int sob_size; - char sob_buf[MAX_SOB_SIZE]; -} spawn_output_buf_t; - - - /** * The reaper is called once a second to finish of any pending spawns */ @@ -135,10 +121,7 @@ int spawn_and_store_stdout(const char *prog, char *const argv[], char **outp) { pid_t p; - int fd[2], r, totalsize = 0, f; - char *outbuf; - struct spawn_output_buf_queue bufs; - spawn_output_buf_t *b = NULL; + int fd[2], f; const char *local_argv[2]; if(argv == NULL) { @@ -194,43 +177,7 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp) close(fd[1]); - TAILQ_INIT(&bufs); - while(1) { - if(b == NULL) { - b = malloc(sizeof(spawn_output_buf_t)); - b->sob_size = 0; - TAILQ_INSERT_TAIL(&bufs, b, sob_link); - } - - r = read(fd[0], b->sob_buf + b->sob_size, MAX_SOB_SIZE - b->sob_size); - if(r < 1) - break; - b->sob_size += r; - totalsize += r; - if(b->sob_size == MAX_SOB_SIZE) - b = NULL; - } - - close(fd[0]); - - if(totalsize == 0) { - free(b); - *outp = NULL; - return 0; - } - - outbuf = malloc(totalsize + 1); - r = 0; - while((b = TAILQ_FIRST(&bufs)) != NULL) { - memcpy(outbuf + r, b->sob_buf, b->sob_size); - r+= b->sob_size; - TAILQ_REMOVE(&bufs, b, sob_link); - free(b); - } - assert(r == totalsize); - *outp = outbuf; - outbuf[totalsize] = 0; - return totalsize; + return file_readall(fd[0], outp); } From e23b73cd110908a07d4dcc339542923de600c2b0 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Mon, 18 Jun 2012 15:48:14 +0100 Subject: [PATCH 8/9] Another ptr bug spotted by andyb2k5. --- src/dvb/dvb_tables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index b68ba3d1..b46d097c 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -288,7 +288,7 @@ tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams, // this LIST_FOREACH(t, &tdmi->tdmi_tables, tdt_link) { if(pid == t->tdt_pid && - tdt->tdt_callback == callback && tdt->tdt_opaque == opaque) { + t->tdt_callback == callback && t->tdt_opaque == opaque) { free(tdt); free(fparams); return; From 4abb686ac5330c7fd4eb19b09d78b75e9d53cff0 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Tue, 19 Jun 2012 12:23:05 +0100 Subject: [PATCH 9/9] Add proper #if test around use of SYS_DVBS, this fixes my earlier mod. --- src/dvb/dvb_preconf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dvb/dvb_preconf.c b/src/dvb/dvb_preconf.c index ef1cf6d9..18aa4f25 100644 --- a/src/dvb/dvb_preconf.c +++ b/src/dvb/dvb_preconf.c @@ -64,7 +64,9 @@ dvb_mux_preconf_add(th_dvb_adapter_t *tda, const struct mux *m, int num, break; case FE_QPSK: +#if DVB_API_VERSION > 5 dmc.dmc_fe_delsys = SYS_DVBS; +#endif dmc.dmc_fe_params.u.qpsk.symbol_rate = m->symrate; dmc.dmc_fe_params.u.qpsk.fec_inner = m->fec;