aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordvdli <dvdli@google.com>2020-12-07 18:34:13 +0800
committerdvdli <dvdli@google.com>2020-12-09 15:14:10 +0800
commitf64fb3998ccb438cbda2b8eafa8e33462f1e652d (patch)
treef55aaf394db081fcc8a2ef057fd3641f181e87f7
parent69b9891f995450be8dd8f24dbd39cf1d417fac61 (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.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/src/pcm.c b/src/pcm.c
index 98ca9eb..17775d5 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -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;
}
}