From: Takashi Sakamoto Date: Mon, 16 Nov 2020 02:45:41 +0000 (+0900) Subject: rawmidi: report error for card disconnection state X-Git-Tag: v0.1.99~16 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=10396810c7c998b15c6c0781e849b4e77f976c29;p=alsa-gobject.git rawmidi: report error for card disconnection state When sound card is under disconnection state, operations fail and return ENODEV error. This commit handles the situation in local error domain. Signed-off-by: Takashi Sakamoto --- diff --git a/src/rawmidi/alsarawmidi-enum-types.h b/src/rawmidi/alsarawmidi-enum-types.h index 95dd9b4..6da9cb2 100644 --- a/src/rawmidi/alsarawmidi-enum-types.h +++ b/src/rawmidi/alsarawmidi-enum-types.h @@ -34,11 +34,13 @@ typedef enum /*< flags >*/ /** * ALSARawmidiStreamPairError: * @ALSARAWMIDI_STREAM_PAIR_ERROR_FAILED: The system call failed. + * @ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED: The card associated to the instance is in disconnect state. * * A set of error code for GError with domain which equals to #alsarawmidi_stream_pair_error_quark() */ typedef enum { ALSARAWMIDI_STREAM_PAIR_ERROR_FAILED, + ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED, } ALSARawmidiStreamPairError; #endif diff --git a/src/rawmidi/stream-pair.c b/src/rawmidi/stream-pair.c index b8b5774..9c4b034 100644 --- a/src/rawmidi/stream-pair.c +++ b/src/rawmidi/stream-pair.c @@ -50,6 +50,13 @@ G_DEFINE_TYPE_WITH_PRIVATE(ALSARawmidiStreamPair, alsarawmidi_stream_pair, G_TYP */ G_DEFINE_QUARK(alsarawmidi-stream-pair-error-quark, alsarawmidi_stream_pair_error) +static const char *const err_msgs[] = { + [ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED] = "The card is in disconnect state", +}; + +#define generate_local_error(error, code) \ + g_set_error_literal(error, ALSARAWMIDI_STREAM_PAIR_ERROR, code, err_msgs[code]) + #define generate_file_error(exception, code, format, arg) \ g_set_error(exception, G_FILE_ERROR, code, format, arg) @@ -232,13 +239,16 @@ void alsarawmidi_stream_pair_open(ALSARawmidiStreamPair *self, guint card_id, priv->fd = open(devnode, open_flag); if (priv->fd < 0) { - GFileError code = g_file_error_from_errno(errno); - - if (code != G_FILE_ERROR_FAILED) - generate_file_error(error, code, "open(%s)", devnode); - else - generate_syscall_error(error, errno, "open(%s)", devnode); - + if (errno == ENODEV) { + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + } else { + GFileError code = g_file_error_from_errno(errno); + + if (code != G_FILE_ERROR_FAILED) + generate_file_error(error, code, "open(%s)", devnode); + else + generate_syscall_error(error, errno, "open(%s)", devnode); + } g_free(devnode); return; } @@ -246,7 +256,10 @@ void alsarawmidi_stream_pair_open(ALSARawmidiStreamPair *self, guint card_id, // Remember the version of protocol currently used. if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_PVERSION, &proto_ver) < 0) { - generate_syscall_error(error, errno, "ioctl(%s)", "PVERSION"); + if (errno == ENODEV) + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + else + generate_syscall_error(error, errno, "ioctl(%s)", "PVERSION"); close(priv->fd); priv->fd = -1; return; @@ -316,7 +329,11 @@ void alsarawmidi_stream_pair_get_substream_info(ALSARawmidiStreamPair *self, info->stream = direction; if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_INFO, info) < 0) { g_object_unref(*substream_info); - generate_syscall_error(error, errno, "ioctl(%s)", "INFO"); + + if (errno == ENODEV) + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + else + generate_syscall_error(error, errno, "ioctl(%s)", "INFO"); } } @@ -350,8 +367,12 @@ void alsarawmidi_stream_pair_set_substream_params(ALSARawmidiStreamPair *self, rawmidi_substream_params_refer_private(substream_params, ¶ms); params->stream = direction; - if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_PARAMS, params) < 0) - generate_syscall_error(error, errno, "ioctl(%s)", "PARAMS"); + if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_PARAMS, params) < 0) { + if (errno == ENODEV) + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + else + generate_syscall_error(error, errno, "ioctl(%s)", "PARAMS"); + } } /** @@ -384,8 +405,12 @@ void alsarawmidi_stream_pair_get_substream_status(ALSARawmidiStreamPair *self, rawmidi_substream_status_refer_private(*substream_status, &status); status->stream = direction; - if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_STATUS, status) < 0) - generate_syscall_error(error, errno, "ioctl(%s)", "STATUS"); + if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_STATUS, status) < 0) { + if (errno == ENODEV) + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + else + generate_syscall_error(error, errno, "ioctl(%s)", "STATUS"); + } } /** @@ -419,12 +444,16 @@ void alsarawmidi_stream_pair_read_from_substream(ALSARawmidiStreamPair *self, len = read(priv->fd, *buf, *buf_size); if (len < 0) { - GFileError code = g_file_error_from_errno(errno); + if (errno == ENODEV) { + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + } else { + GFileError code = g_file_error_from_errno(errno); - if (code != G_FILE_ERROR_FAILED) - generate_file_error(error, code, "read(%s)", priv->devnode); - else - generate_syscall_error(error, errno, "read(%s)", priv->devnode); + if (code != G_FILE_ERROR_FAILED) + generate_file_error(error, code, "read(%s)", priv->devnode); + else + generate_syscall_error(error, errno, "read(%s)", priv->devnode); + } return; } @@ -462,12 +491,16 @@ void alsarawmidi_stream_pair_write_to_substream(ALSARawmidiStreamPair *self, len = write(priv->fd, buf, buf_size); if (len < 0) { - GFileError code = g_file_error_from_errno(errno); + if (errno == ENODEV) { + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + } else { + GFileError code = g_file_error_from_errno(errno); - if (code != G_FILE_ERROR_FAILED) - generate_file_error(error, code, "write(%s)", priv->devnode); - else - generate_syscall_error(error, errno, "write(%s)", priv->devnode); + if (code != G_FILE_ERROR_FAILED) + generate_file_error(error, code, "write(%s)", priv->devnode); + else + generate_syscall_error(error, errno, "write(%s)", priv->devnode); + } return; } @@ -498,8 +531,12 @@ void alsarawmidi_stream_pair_drain_substream(ALSARawmidiStreamPair *self, g_return_if_fail(error == NULL || *error == NULL); - if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_DRAIN, &direction) < 0) - generate_syscall_error(error, errno, "ioctl(%s)", "DRAIN"); + if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_DRAIN, &direction) < 0) { + if (errno == ENODEV) + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + else + generate_syscall_error(error, errno, "ioctl(%s)", "DRAIN"); + } } /** @@ -526,8 +563,12 @@ void alsarawmidi_stream_pair_drop_substream(ALSARawmidiStreamPair *self, g_return_if_fail(error == NULL || *error == NULL); - if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_DROP, &direction) < 0) - generate_syscall_error(error, errno, "ioctl(%s)", "DROP"); + if (ioctl(priv->fd, SNDRV_RAWMIDI_IOCTL_DROP, &direction) < 0) { + if (errno == ENODEV) + generate_local_error(error, ALSARAWMIDI_STREAM_PAIR_ERROR_DISCONNECTED); + else + generate_syscall_error(error, errno, "ioctl(%s)", "DROP"); + } } static gboolean rawmidi_stream_pair_check_src(GSource *gsrc) diff --git a/tests/alsarawmidi-enums b/tests/alsarawmidi-enums index 69d3799..5959b3a 100644 --- a/tests/alsarawmidi-enums +++ b/tests/alsarawmidi-enums @@ -18,6 +18,7 @@ stream_pair_info_flags = ( stream_pair_error_types = ( 'FAILED', + 'DISCONNECTED', ) types = {