app_mixmonitor: Abort MixMonitor if ast_writefile fails

An error flag is set if ast_writefile fails, but this flag
is never used later. If the flag is set, clean up the MixMonitor
invocation and abort.

This complements #2149, which causes ast_writefile to fail
if attempting to record to a file already being written to.

Resolves: #2198

UserNote: If MixMonitor fails to open a file for writing
audio, it will now abort, rather than silently failing.
pull/1504/merge
Naveen Albert 2 weeks ago committed by github-actions[bot]
parent f8a09e90ed
commit d2cf322856

@ -521,6 +521,7 @@ struct mixmonitor_ds {
struct ast_filestream *fs_write;
struct ast_audiohook *audiohook;
char *datastore_id;
unsigned int samp_rate;
char *filename;
@ -570,6 +571,7 @@ static void mixmonitor_ds_destroy(void *data)
mixmonitor_ds->destruction_ok = 1;
ast_free(mixmonitor_ds->filename);
ast_free(mixmonitor_ds->beep_id);
ast_free(mixmonitor_ds->datastore_id);
ast_cond_signal(&mixmonitor_ds->destruction_condition);
ast_mutex_unlock(&mixmonitor_ds->lock);
}
@ -848,6 +850,9 @@ static int mixmonitor_autochan_is_bridged(struct ast_autochan *autochan)
return is_bridged;
}
/* Forward declaration */
static void mixmonitor_ds_remove_and_free(struct ast_channel *chan, const char *datastore_id);
static void *mixmonitor_thread(void *obj)
{
struct mixmonitor *mixmonitor = obj;
@ -875,8 +880,6 @@ static void *mixmonitor_thread(void *obj)
ast_callid_threadassoc_add(mixmonitor->callid);
}
ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);
fs = &mixmonitor->mixmonitor_ds->fs;
fs_read = &mixmonitor->mixmonitor_ds->fs_read;
fs_write = &mixmonitor->mixmonitor_ds->fs_write;
@ -888,6 +891,35 @@ static void *mixmonitor_thread(void *obj)
format_slin = ast_format_cache_get_slin_by_rate(mixmonitor->mixmonitor_ds->samp_rate);
if (errflag) {
/* Tear everything down and exit. */
mixmonitor_ds_close_fs(mixmonitor->mixmonitor_ds);
mixmonitor->mixmonitor_ds->audiohook = NULL;
ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
ast_autochan_channel_lock(mixmonitor->autochan);
ast_audiohook_remove(mixmonitor->autochan->chan, &mixmonitor->audiohook);
mixmonitor_ds_remove_and_free(mixmonitor->autochan->chan, mixmonitor->mixmonitor_ds->datastore_id);
ast_autochan_channel_unlock(mixmonitor->autochan);
ast_autochan_destroy(mixmonitor->autochan);
ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
if (!mixmonitor->mixmonitor_ds->destruction_ok) {
ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock);
}
ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
ast_audiohook_destroy(&mixmonitor->audiohook);
mixmonitor_free(mixmonitor);
ast_module_unref(ast_module_info->self);
return NULL;
}
ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);
ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
if (mixmonitor->skip_seconds > 0.0) {
@ -1042,6 +1074,7 @@ frame_cleanup:
if (!mixmonitor->mixmonitor_ds->destruction_ok) {
ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock);
}
ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
/* Free the translate paths */
@ -1316,7 +1349,7 @@ static int launch_monitor_thread(struct ast_channel *chan, const char *filename,
return -1;
}
ast_free(datastore_id);
mixmonitor->mixmonitor_ds->datastore_id = datastore_id; /* Steal the reference */
/* reference be released at mixmonitor destruction */
mixmonitor->callid = ast_read_threadstorage_callid();

Loading…
Cancel
Save