Do not abort in snd_xxx_close() functions

Remove several memory leaks by not aborting prematurely from a
snd_xxx_close() function when some operation fails.
This can happen when a USB device was unplugged.
This commit is contained in:
Clemens Ladisch 2006-02-27 09:54:57 +00:00
parent f9c7321670
commit 45850439b3
11 changed files with 33 additions and 33 deletions

View file

@ -206,12 +206,11 @@ int snd_hwdep_close(snd_hwdep_t *hwdep)
{ {
int err; int err;
assert(hwdep); assert(hwdep);
if ((err = hwdep->ops->close(hwdep)) < 0) err = hwdep->ops->close(hwdep);
return err;
if (hwdep->name) if (hwdep->name)
free(hwdep->name); free(hwdep->name);
free(hwdep); free(hwdep);
return 0; return err;
} }
/** /**

View file

@ -668,13 +668,13 @@ snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm)
*/ */
int snd_pcm_close(snd_pcm_t *pcm) int snd_pcm_close(snd_pcm_t *pcm)
{ {
int err; int res = 0, err;
assert(pcm); assert(pcm);
if (pcm->setup && !pcm->donot_close) { if (pcm->setup && !pcm->donot_close) {
snd_pcm_drop(pcm); snd_pcm_drop(pcm);
err = snd_pcm_hw_free(pcm); err = snd_pcm_hw_free(pcm);
if (err < 0) if (err < 0)
return err; res = err;
} }
if (pcm->mmap_channels) if (pcm->mmap_channels)
snd_pcm_munmap(pcm); snd_pcm_munmap(pcm);
@ -684,8 +684,11 @@ int snd_pcm_close(snd_pcm_t *pcm)
} }
err = pcm->ops->close(pcm->op_arg); err = pcm->ops->close(pcm->op_arg);
if (err < 0) if (err < 0)
return err; res = err;
return snd_pcm_free(pcm); err = snd_pcm_free(pcm);
if (err < 0)
res = err;
return res;
} }
/** /**

View file

@ -55,13 +55,13 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
snd_pcm_hooks_t *h = pcm->private_data; snd_pcm_hooks_t *h = pcm->private_data;
struct list_head *pos, *next; struct list_head *pos, *next;
unsigned int k; unsigned int k;
int err; int res = 0, err;
list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_CLOSE]) { list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_CLOSE]) {
snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list); snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
err = hook->func(hook); err = hook->func(hook);
if (err < 0) if (err < 0)
return err; res = err;
} }
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) { for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
struct list_head *hooks = &h->hooks[k]; struct list_head *hooks = &h->hooks[k];
@ -72,7 +72,10 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
snd_pcm_hook_remove(hook); snd_pcm_hook_remove(hook);
} }
} }
return snd_pcm_generic_close(pcm); err = snd_pcm_generic_close(pcm);
if (err < 0)
res = err;
return res;
} }
static int snd_pcm_hooks_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) static int snd_pcm_hooks_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)

View file

@ -889,16 +889,15 @@ static int snd_pcm_hw_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
static int snd_pcm_hw_close(snd_pcm_t *pcm) static int snd_pcm_hw_close(snd_pcm_t *pcm)
{ {
snd_pcm_hw_t *hw = pcm->private_data; snd_pcm_hw_t *hw = pcm->private_data;
int err; int err = 0;
if (close(hw->fd)) { if (close(hw->fd)) {
err = -errno; err = -errno;
SYSMSG("close failed\n"); SYSMSG("close failed\n");
return err;
} }
snd_pcm_hw_munmap_status(pcm); snd_pcm_hw_munmap_status(pcm);
snd_pcm_hw_munmap_control(pcm); snd_pcm_hw_munmap_control(pcm);
free(hw); free(hw);
return 0; return err;
} }
static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm, static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,

View file

@ -64,10 +64,7 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm)
int err, result = 0; int err, result = 0;
if (plug->ttable) if (plug->ttable)
free(plug->ttable); free(plug->ttable);
if (plug->gen.slave != plug->req_slave) { assert(plug->gen.slave == plug->req_slave);
SNDERR("plug slaves mismatch");
return -EINVAL;
}
if (plug->gen.close_slave) { if (plug->gen.close_slave) {
snd_pcm_unlink_hw_ptr(pcm, plug->req_slave); snd_pcm_unlink_hw_ptr(pcm, plug->req_slave);
snd_pcm_unlink_appl_ptr(pcm, plug->req_slave); snd_pcm_unlink_appl_ptr(pcm, plug->req_slave);

View file

@ -341,14 +341,13 @@ int snd_rawmidi_close(snd_rawmidi_t *rawmidi)
{ {
int err; int err;
assert(rawmidi); assert(rawmidi);
if ((err = rawmidi->ops->close(rawmidi)) < 0) err = rawmidi->ops->close(rawmidi);
return err;
if (rawmidi->name) if (rawmidi->name)
free(rawmidi->name); free(rawmidi->name);
if (rawmidi->dl_handle) if (rawmidi->dl_handle)
snd_dlclose(rawmidi->dl_handle); snd_dlclose(rawmidi->dl_handle);
free(rawmidi); free(rawmidi);
return 0; return err;
} }
/** /**

View file

@ -48,15 +48,17 @@ typedef struct {
static int snd_rawmidi_hw_close(snd_rawmidi_t *rmidi) static int snd_rawmidi_hw_close(snd_rawmidi_t *rmidi)
{ {
snd_rawmidi_hw_t *hw = rmidi->private_data; snd_rawmidi_hw_t *hw = rmidi->private_data;
int err = 0;
hw->open--; hw->open--;
if (hw->open) if (hw->open)
return 0; return 0;
if (close(hw->fd)) { if (close(hw->fd)) {
err = -errno;
SYSERR("close failed\n"); SYSERR("close failed\n");
return -errno;
} }
free(hw); free(hw);
return 0; return err;
} }
static int snd_rawmidi_hw_nonblock(snd_rawmidi_t *rmidi, int nonblock) static int snd_rawmidi_hw_nonblock(snd_rawmidi_t *rmidi, int nonblock)

View file

@ -1029,8 +1029,6 @@ int snd_seq_close(snd_seq_t *seq)
int err; int err;
assert(seq); assert(seq);
err = seq->ops->close(seq); err = seq->ops->close(seq);
if (err < 0)
return err;
if (seq->obuf) if (seq->obuf)
free(seq->obuf); free(seq->obuf);
if (seq->ibuf) if (seq->ibuf)
@ -1040,7 +1038,7 @@ int snd_seq_close(snd_seq_t *seq)
if (seq->name) if (seq->name)
free(seq->name); free(seq->name);
free(seq); free(seq);
return 0; return err;
} }
/** /**

View file

@ -42,12 +42,14 @@ typedef struct {
static int snd_seq_hw_close(snd_seq_t *seq) static int snd_seq_hw_close(snd_seq_t *seq)
{ {
snd_seq_hw_t *hw = seq->private_data; snd_seq_hw_t *hw = seq->private_data;
int err = 0;
if (close(hw->fd)) { if (close(hw->fd)) {
err = -errno;
SYSERR("close failed\n"); SYSERR("close failed\n");
return -errno;
} }
free(hw); free(hw);
return 0; return err;
} }
static int snd_seq_hw_nonblock(snd_seq_t *seq, int nonblock) static int snd_seq_hw_nonblock(snd_seq_t *seq, int nonblock)

View file

@ -242,12 +242,11 @@ int snd_timer_close(snd_timer_t *timer)
snd_async_handler_t *h = list_entry(timer->async_handlers.next, snd_async_handler_t, hlist); snd_async_handler_t *h = list_entry(timer->async_handlers.next, snd_async_handler_t, hlist);
snd_async_del_handler(h); snd_async_del_handler(h);
} }
if ((err = timer->ops->close(timer)) < 0) err = timer->ops->close(timer);
return err;
if (timer->name) if (timer->name)
free(timer->name); free(timer->name);
free(timer); free(timer);
return 0; return err;
} }
/** /**

View file

@ -196,12 +196,11 @@ int snd_timer_query_close(snd_timer_query_t *timer)
{ {
int err; int err;
assert(timer); assert(timer);
if ((err = timer->ops->close(timer)) < 0) err = timer->ops->close(timer);
return err;
if (timer->name) if (timer->name)
free(timer->name); free(timer->name);
free(timer); free(timer);
return 0; return err;
} }
/** /**