diff options
author | dvdli <dvdli@google.com> | 2020-12-07 18:34:13 +0800 |
---|---|---|
committer | dvdli <dvdli@google.com> | 2020-12-09 15:14:10 +0800 |
commit | f64fb3998ccb438cbda2b8eafa8e33462f1e652d (patch) | |
tree | f55aaf394db081fcc8a2ef057fd3641f181e87f7 | |
parent | 69b9891f995450be8dd8f24dbd39cf1d417fac61 (diff) |
fix bugs in the pcm_open_* functions
1. Align the document and the code.
2. Copy error messages to bad_pcm object for client to get more info
when opening failed.
-rw-r--r-- | src/pcm.c | 46 |
1 files changed, 25 insertions, 21 deletions
@@ -995,24 +995,25 @@ int pcm_close(struct pcm *pcm) * - @ref PCM_MONOTONIC * @param config The hardware and software parameters to open the PCM with. * @returns A PCM structure. - * If an error occurs allocating memory for the PCM, NULL is returned. - * Otherwise, client code should check that the PCM opened properly by calling @ref pcm_is_ready. - * If @ref pcm_is_ready, check @ref pcm_get_error for more information. + * If an error occurs, the pointer of bad_pcm is returned. + * Otherwise, it returns the pointer of PCM object. + * Client code should check that the PCM opened properly by calling @ref pcm_is_ready. + * If @ref pcm_is_ready returns false, check @ref pcm_get_error for more information. * @ingroup libtinyalsa-pcm */ struct pcm *pcm_open_by_name(const char *name, unsigned int flags, const struct pcm_config *config) { - unsigned int card, device; - if ((name[0] != 'h') - || (name[1] != 'w') - || (name[2] != ':')) { - return NULL; - } else if (sscanf(&name[3], "%u,%u", &card, &device) != 2) { - return NULL; - } - return pcm_open(card, device, flags, config); + unsigned int card, device; + if (name[0] != 'h' || name[1] != 'w' || name[2] != ':') { + oops(&bad_pcm, 0, "name format is not matched"); + return &bad_pcm; + } else if (sscanf(&name[3], "%u,%u", &card, &device) != 2) { + oops(&bad_pcm, 0, "name format is not matched"); + return &bad_pcm; + } + return pcm_open(card, device, flags, config); } /** Opens a PCM. @@ -1029,9 +1030,10 @@ struct pcm *pcm_open_by_name(const char *name, * - @ref PCM_MONOTONIC * @param config The hardware and software parameters to open the PCM with. * @returns A PCM structure. - * If an error occurs allocating memory for the PCM, NULL is returned. - * Otherwise, client code should check that the PCM opened properly by calling @ref pcm_is_ready. - * If @ref pcm_is_ready, check @ref pcm_get_error for more information. + * If an error occurs, the pointer of bad_pcm is returned. + * Otherwise, it returns the pointer of PCM object. + * Client code should check that the PCM opened properly by calling @ref pcm_is_ready. + * If @ref pcm_is_ready returns false, check @ref pcm_get_error for more information. * @ingroup libtinyalsa-pcm */ struct pcm *pcm_open(unsigned int card, unsigned int device, @@ -1042,8 +1044,10 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, int rc; pcm = calloc(1, sizeof(struct pcm)); - if (!pcm) + if (!pcm) { + oops(&bad_pcm, ENOMEM, "can't allocate PCM object"); return &bad_pcm; + } /* Default to hw_ops, attemp plugin open only if hw (/dev/snd/pcm*) open fails */ pcm->ops = &hw_ops; @@ -1055,7 +1059,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, pcm->snd_node = snd_utils_open_pcm(card, device); pcm_type = snd_utils_get_node_type(pcm->snd_node); if (!pcm->snd_node || pcm_type != SND_NODE_TYPE_PLUGIN) { - oops(pcm, -ENODEV, "no device (hw/plugin) for card(%u), device(%u)", + oops(&bad_pcm, ENODEV, "no device (hw/plugin) for card(%u), device(%u)", card, device); goto fail_close_dev_node; } @@ -1064,7 +1068,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, } #endif if (pcm->fd < 0) { - oops(pcm, errno, "cannot open device (%u) for card (%u)", + oops(&bad_pcm, errno, "cannot open device (%u) for card (%u)", device, card); goto fail_close_dev_node; } @@ -1072,7 +1076,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, pcm->flags = flags; if (pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_INFO, &info)) { - oops(pcm, errno, "cannot get info"); + oops(&bad_pcm, errno, "cannot get info"); goto fail_close; } pcm->subdevice = info.subdevice; @@ -1082,7 +1086,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, rc = pcm_hw_mmap_status(pcm); if (rc < 0) { - oops(pcm, errno, "mmap status failed"); + oops(&bad_pcm, errno, "mmap status failed"); goto fail; } @@ -1091,7 +1095,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device, int arg = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC; rc = pcm->ops->ioctl(pcm->data, SNDRV_PCM_IOCTL_TTSTAMP, &arg); if (rc < 0) { - oops(pcm, errno, "cannot set timestamp type"); + oops(&bad_pcm, errno, "cannot set timestamp type"); goto fail; } } |