Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
IPTV: fix memory leaks
  • Loading branch information
perexg committed Oct 14, 2015
1 parent 9f21e59 commit 403a432
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 29 deletions.
21 changes: 15 additions & 6 deletions src/http.c
Expand Up @@ -822,19 +822,28 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)



/*
* Delete one argument
*/
void
http_arg_remove(struct http_arg_list *list, struct http_arg *arg)
{
TAILQ_REMOVE(list, arg, link);
free(arg->key);
free(arg->val);
free(arg);
}


/*
* Delete all arguments associated with a connection
*/
void
http_arg_flush(struct http_arg_list *list)
{
http_arg_t *ra;
while((ra = TAILQ_FIRST(list)) != NULL) {
TAILQ_REMOVE(list, ra, link);
free(ra->key);
free(ra->val);
free(ra);
}
while((ra = TAILQ_FIRST(list)) != NULL)
http_arg_remove(list, ra);
}


Expand Down
1 change: 1 addition & 0 deletions src/http.h
Expand Up @@ -173,6 +173,7 @@ static inline void http_arg_init(struct http_arg_list *list)
TAILQ_INIT(list);
}

void http_arg_remove(struct http_arg_list *list, struct http_arg *arg);
void http_arg_flush(struct http_arg_list *list);

char *http_arg_get(struct http_arg_list *list, const char *name);
Expand Down
1 change: 1 addition & 0 deletions src/input/mpegts.h
Expand Up @@ -307,6 +307,7 @@ struct mpegts_network
/*
* Functions
*/
void (*mn_delete) (mpegts_network_t*, int delconf);
void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
void (*mn_config_save) (mpegts_network_t*);
mpegts_mux_t* (*mn_create_mux)
Expand Down
36 changes: 23 additions & 13 deletions src/input/mpegts/iptv/iptv.c
Expand Up @@ -477,30 +477,37 @@ iptv_input_mux_started ( iptv_mux_t *im )
im->mm_iptv_atsc ? DVB_SYS_ATSC_ALL : DVB_SYS_DVBT);
}

/* **************************************************************************
* IPTV network
* *************************************************************************/

static void
iptv_network_class_delete ( idnode_t *in )
iptv_network_delete ( mpegts_network_t *mn, int delconf )
{
iptv_network_t *mn = (iptv_network_t*)in;
char *s = mn->in_url;
iptv_network_t *in = (iptv_network_t*)mn;
char *s = in->in_url;

if (in->in_class == &iptv_auto_network_class)
iptv_auto_network_done((iptv_network_t *)in);
if (in->mn_id.in_class == &iptv_auto_network_class)
iptv_auto_network_done(in);

/* Remove config */
hts_settings_remove("input/iptv/networks/%s",
idnode_uuid_as_sstr(in));
if (delconf)
hts_settings_remove("input/iptv/networks/%s",
idnode_uuid_as_sstr(&in->mn_id));

/* delete */
free(mn->in_remove_args);
mpegts_network_delete((mpegts_network_t *)mn, 1);
free(in->in_remove_args);
mpegts_network_delete(mn, delconf);

free(s);
}

/* **************************************************************************
* IPTV network
* *************************************************************************/

static void
iptv_network_class_delete ( idnode_t *in )
{
return iptv_network_delete((mpegts_network_t *)in, 1);
}

extern const idclass_t mpegts_network_class;
const idclass_t iptv_network_class = {
.ic_super = &mpegts_network_class,
Expand Down Expand Up @@ -640,6 +647,7 @@ iptv_network_create0
free(in);
return NULL;
}
in->mn_delete = iptv_network_delete;
in->mn_create_service = iptv_network_create_service;
in->mn_mux_class = iptv_network_mux_class;
in->mn_mux_create2 = iptv_network_create_mux2;
Expand Down Expand Up @@ -747,7 +755,9 @@ void iptv_done ( void )
pthread_join(iptv_thread, NULL);
tvhpoll_destroy(iptv_poll);
pthread_mutex_lock(&global_lock);
mpegts_network_unregister_builder(&iptv_auto_network_class);
mpegts_network_unregister_builder(&iptv_network_class);
mpegts_network_class_delete(&iptv_auto_network_class, 0);
mpegts_network_class_delete(&iptv_network_class, 0);
mpegts_input_stop_all((mpegts_input_t*)iptv_input);
mpegts_input_delete((mpegts_input_t *)iptv_input, 0);
Expand Down
34 changes: 25 additions & 9 deletions src/input/mpegts/iptv/iptv_auto.c
Expand Up @@ -63,7 +63,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
if (urlparse(url, &u))
return;
if (u.host == NULL || u.host[0] == '\0')
return;
goto end;

/* remove requested arguments */
if (!http_args_empty(remove_args)) {
Expand All @@ -73,7 +73,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
for (ra2 = TAILQ_FIRST(&args); ra2; ra2 = ra2_next) {
ra2_next = TAILQ_NEXT(ra2, link);
if (strcmp(ra1->key, ra2->key) == 0)
TAILQ_REMOVE(&args, ra2, link);
http_arg_remove(&args, ra2);
}
free(u.query);
u.query = NULL;
Expand All @@ -90,6 +90,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
u.query = htsbuf_to_string(&q);
htsbuf_queue_flush(&q);
}
http_arg_flush(&args);
tvh_strlcatf(url2, sizeof(url2), l, "%s://", u.scheme);
if (u.user && u.user[0] && u.pass && u.pass[0])
tvh_strlcatf(url2, sizeof(url2), l, "%s:%s@", u.user, u.pass);
Expand Down Expand Up @@ -129,7 +130,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
if (change)
idnode_notify_changed(&im->mm_id);
(*total)++;
return;
goto end;
}
}

Expand All @@ -146,6 +147,9 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
(*total)++;
(*count)++;
}

end:
urlreset(&u);
}

/*
Expand Down Expand Up @@ -224,6 +228,8 @@ iptv_auto_network_process(iptv_network_t *in, const char *last_url, char *data,
if (!strncmp(data, "#EXTM3U", 7))
r = iptv_auto_network_process_m3u(in, data, last_url, &remove_args, in->in_channel_number);

http_arg_flush(&remove_args);

if (r == 0) {
count = 0;
LIST_FOREACH(mm, &in->mn_muxes, mm_network_link)
Expand All @@ -247,7 +253,7 @@ iptv_auto_network_process(iptv_network_t *in, const char *last_url, char *data,
static int
iptv_auto_network_file(iptv_network_t *in, const char *filename)
{
int fd;
int fd, res;
struct stat st;
char *data, *last_url;
size_t r;
Expand Down Expand Up @@ -283,9 +289,12 @@ iptv_auto_network_file(iptv_network_t *in, const char *filename)
last_url = strrchr(filename, '/');
if (last_url)
last_url++;
return iptv_auto_network_process(in, last_url, data, off);
res = iptv_auto_network_process(in, last_url, data, off);
} else {
res = -1;
}
return -1;
free(data);
return res;
}

/*
Expand Down Expand Up @@ -329,6 +338,9 @@ iptv_auto_network_fetch_complete(http_client_t *hc)

pthread_mutex_lock(&global_lock);

if (in->in_http_client == NULL)
goto out;

if (hc->hc_code == HTTP_STATUS_OK && hc->hc_result == 0 && hc->hc_data_size > 0)
iptv_auto_network_process(in, last_url, hc->hc_data, hc->hc_data_size);
else
Expand All @@ -338,8 +350,10 @@ iptv_auto_network_fetch_complete(http_client_t *hc)
/* note: http_client_close must be called outside http_client callbacks */
gtimer_arm(&in->in_fetch_timer, iptv_auto_network_fetch_done, hc, 0);

out:
pthread_mutex_unlock(&global_lock);

urlreset(&u);
return 0;
}

Expand All @@ -353,6 +367,8 @@ iptv_auto_network_fetch(void *aux)
http_client_t *hc;
url_t u;

memset(&u, 0, sizeof(u));

if (strncmp(in->in_url, "file://", 7) == 0) {
iptv_auto_network_file(in, in->in_url + 7);
goto arm;
Expand All @@ -364,7 +380,6 @@ iptv_auto_network_fetch(void *aux)
in->in_http_client = NULL;
}

memset(&u, 0, sizeof(u));
if (urlparse(in->in_url, &u) < 0) {
tvherror("iptv", "wrong url for network '%s'", in->mn_network_name);
goto arm;
Expand All @@ -388,6 +403,7 @@ iptv_auto_network_fetch(void *aux)
in->in_http_client = hc;

arm:
urlreset(&u);
gtimer_arm(&in->in_auto_timer, iptv_auto_network_fetch, in,
MAX(1, in->in_refetch_period) * 60);
}
Expand All @@ -407,10 +423,10 @@ iptv_auto_network_init( iptv_network_t *in )
void
iptv_auto_network_done( iptv_network_t *in )
{
gtimer_disarm(&in->in_auto_timer);
gtimer_disarm(&in->in_fetch_timer);
if (in->in_http_client) {
http_client_close(in->in_http_client);
in->in_http_client = NULL;
}
gtimer_disarm(&in->in_auto_timer);
gtimer_disarm(&in->in_fetch_timer);
}
1 change: 1 addition & 0 deletions src/input/mpegts/iptv/iptv_http.c
Expand Up @@ -146,6 +146,7 @@ iptv_http_complete
} else {
tvherror("iptv", "m3u url invalid '%s'", url);
}
urlreset(&u);
free(url);
return 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/input/mpegts/mpegts_network.c
Expand Up @@ -357,6 +357,7 @@ mpegts_network_create0
mn->mn_create_service = mpegts_network_create_service;
mn->mn_mux_class = mpegts_network_mux_class;
mn->mn_mux_create2 = mpegts_network_mux_create2;
mn->mn_delete = mpegts_network_delete;

/* Add to global list */
LIST_INSERT_HEAD(&mpegts_network_all, mn, mn_global_link);
Expand Down Expand Up @@ -389,7 +390,7 @@ mpegts_network_class_delete(const idclass_t *idc, int delconf)
for (mn = LIST_FIRST(&mpegts_network_all); mn != NULL; mn = n) {
n = LIST_NEXT(mn, mn_global_link);
if (mn->mn_id.in_class == idc)
mpegts_network_delete(mn, delconf);
mn->mn_delete(mn, delconf);
}
}

Expand Down

0 comments on commit 403a432

Please sign in to comment.