]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Do not abort in snd_xxx_close() functions
authorClemens Ladisch <clemens@ladisch.de>
Mon, 27 Feb 2006 09:54:57 +0000 (09:54 +0000)
committerClemens Ladisch <clemens@ladisch.de>
Mon, 27 Feb 2006 09:54:57 +0000 (09:54 +0000)
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.

src/hwdep/hwdep.c
src/pcm/pcm.c
src/pcm/pcm_hooks.c
src/pcm/pcm_hw.c
src/pcm/pcm_plug.c
src/rawmidi/rawmidi.c
src/rawmidi/rawmidi_hw.c
src/seq/seq.c
src/seq/seq_hw.c
src/timer/timer.c
src/timer/timer_query.c

index f0c8f9d015c82b1707af4f7a959b9df855122b03..6a5e7872b3c55c03d1c89e7074d2412ca60876f0 100644 (file)
@@ -206,12 +206,11 @@ int snd_hwdep_close(snd_hwdep_t *hwdep)
 {
        int err;
        assert(hwdep);
-       if ((err = hwdep->ops->close(hwdep)) < 0)
-               return err;
+       err = hwdep->ops->close(hwdep);
        if (hwdep->name)
                free(hwdep->name);
        free(hwdep);
-       return 0;
+       return err;
 }
 
 /**
index 43d87c35b0ad3548f3048e41ccf0ee3b1c4854ea..0af6f2aacc4f389333deb6f134eb5b81bd4587bf 100644 (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 err;
+       int res = 0, err;
        assert(pcm);
        if (pcm->setup && !pcm->donot_close) {
                snd_pcm_drop(pcm);
                err = snd_pcm_hw_free(pcm);
                if (err < 0)
-                       return err;
+                       res = err;
        }
        if (pcm->mmap_channels)
                snd_pcm_munmap(pcm);
@@ -684,8 +684,11 @@ int snd_pcm_close(snd_pcm_t *pcm)
        }
        err = pcm->ops->close(pcm->op_arg);
        if (err < 0)
-               return err;
-       return snd_pcm_free(pcm);
+               res = err;
+       err = snd_pcm_free(pcm);
+       if (err < 0)
+               res = err;
+       return res;
 }      
 
 /**
index f5136862bd292c49c160782cb11de4746a0bb46c..86799877cfb6f0d5073f4d1352a6500097ef4c56 100644 (file)
@@ -55,13 +55,13 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
        snd_pcm_hooks_t *h = pcm->private_data;
        struct list_head *pos, *next;
        unsigned int k;
-       int err;
+       int res = 0, err;
 
        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);
                err = hook->func(hook);
                if (err < 0)
-                       return err;
+                       res = err;
        }
        for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++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);
                }
        }
-       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)
index 88dab15af90633499332584e166dba7078eabb06..356576fa1570b9faac92114271af8b372be18e61 100644 (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)
 {
        snd_pcm_hw_t *hw = pcm->private_data;
-       int err;
+       int err = 0;
        if (close(hw->fd)) {
                err = -errno;
                SYSMSG("close failed\n");
-               return err;
        }
        snd_pcm_hw_munmap_status(pcm);
        snd_pcm_hw_munmap_control(pcm);
        free(hw);
-       return 0;
+       return err;
 }
 
 static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
index 2bcc62dc832a8b3c58c24a4b1c7be2b04afd28e7..15204d7586ad1847f17c31a72a358ee1117a90d5 100644 (file)
@@ -64,10 +64,7 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm)
        int err, result = 0;
        if (plug->ttable)
                free(plug->ttable);
-       if (plug->gen.slave != plug->req_slave) {
-               SNDERR("plug slaves mismatch");
-               return -EINVAL;
-       }
+       assert(plug->gen.slave == plug->req_slave);
        if (plug->gen.close_slave) {
                snd_pcm_unlink_hw_ptr(pcm, plug->req_slave);
                snd_pcm_unlink_appl_ptr(pcm, plug->req_slave);
index fe19886e0ea0765e011998e6306a03a32602c3ea..2d509097db62d04f2e5cbb1a962a7a45366bbdc8 100644 (file)
@@ -341,14 +341,13 @@ int snd_rawmidi_close(snd_rawmidi_t *rawmidi)
 {
        int err;
        assert(rawmidi);
-       if ((err = rawmidi->ops->close(rawmidi)) < 0)
-               return err;
+       err = rawmidi->ops->close(rawmidi);
        if (rawmidi->name)
                free(rawmidi->name);
        if (rawmidi->dl_handle)
                snd_dlclose(rawmidi->dl_handle);
        free(rawmidi);
-       return 0;
+       return err;
 }
 
 /**
index 6d2316f783b38b661c86750e4e52098ea1258aa7..b15dadb64ae8c205468dc8537b121c68be3e1c29 100644 (file)
@@ -48,15 +48,17 @@ typedef struct {
 static int snd_rawmidi_hw_close(snd_rawmidi_t *rmidi)
 {
        snd_rawmidi_hw_t *hw = rmidi->private_data;
+       int err = 0;
+
        hw->open--;
        if (hw->open)
                return 0;
        if (close(hw->fd)) {
+               err = -errno;
                SYSERR("close failed\n");
-               return -errno;
        }
        free(hw);
-       return 0;
+       return err;
 }
 
 static int snd_rawmidi_hw_nonblock(snd_rawmidi_t *rmidi, int nonblock)
index df7b64e6a73819fac66b91f79359cccdde7a8c9a..07954a35b3fafcc314d4adf7f83b2e66f74eec37 100644 (file)
@@ -1029,8 +1029,6 @@ int snd_seq_close(snd_seq_t *seq)
        int err;
        assert(seq);
        err = seq->ops->close(seq);
-       if (err < 0)
-               return err;
        if (seq->obuf)
                free(seq->obuf);
        if (seq->ibuf)
@@ -1040,7 +1038,7 @@ int snd_seq_close(snd_seq_t *seq)
        if (seq->name)
                free(seq->name);
        free(seq);
-       return 0;
+       return err;
 }
 
 /**
index a2a01455c2e1a4764804b1e78f15e47359a93dc6..c92f3648e75fdfc846767b0a552b15580c519498 100644 (file)
@@ -42,12 +42,14 @@ typedef struct {
 static int snd_seq_hw_close(snd_seq_t *seq)
 {
        snd_seq_hw_t *hw = seq->private_data;
+       int err = 0;
+
        if (close(hw->fd)) {
+               err = -errno;
                SYSERR("close failed\n");
-               return -errno;
        }
        free(hw);
-       return 0;
+       return err;
 }
 
 static int snd_seq_hw_nonblock(snd_seq_t *seq, int nonblock)
index d6ca49bdcc725f76cb7022df47fda6c457687349..8b3da1f25b442a4d8669f70342e708f2b1932b43 100644 (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_del_handler(h);
        }
-       if ((err = timer->ops->close(timer)) < 0)
-               return err;
+       err = timer->ops->close(timer);
        if (timer->name)
                free(timer->name);
        free(timer);
-       return 0;
+       return err;
 }
 
 /**
index 77c9afc2c284e4412f82a50071b8e12c00556446..58c2d5a38381689f85c732b924069277afb4b0fa 100644 (file)
@@ -196,12 +196,11 @@ int snd_timer_query_close(snd_timer_query_t *timer)
 {
        int err;
        assert(timer);
-       if ((err = timer->ops->close(timer)) < 0)
-               return err;
+       err = timer->ops->close(timer);
        if (timer->name)
                free(timer->name);
        free(timer);
-       return 0;
+       return err;
 }
 
 /**