From 4ea832024867a5ab36bed5c1050573e438dda697 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Fri, 13 Nov 2020 16:26:26 +0900 Subject: [PATCH] ctl: card: report error due to operations against element owned by the other processes Some operations to control element returns EBUSY or EPERM when the element is locked for write by the other processes. This commit handles the error in local error domain. Signed-off-by: Takashi Sakamoto --- src/ctl/alsactl-enum-types.h | 2 ++ src/ctl/card.c | 19 ++++++++++++++++--- tests/alsactl-enums | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ctl/alsactl-enum-types.h b/src/ctl/alsactl-enum-types.h index e39bdac..01a8c90 100644 --- a/src/ctl/alsactl-enum-types.h +++ b/src/ctl/alsactl-enum-types.h @@ -115,6 +115,7 @@ typedef enum /*< flags >*/ * @ALSACTL_CARD_ERROR_DISCONNECTED: The card associated to the instance is in disconnect state. * @ALSACTL_CARD_ERROR_ELEM_NOT_FOUND: The control element not found in the card. * @ALSACTL_CARD_ERROR_ELEM_NOT_SUPPORTED: The operation is not supported by the control element. + * @ALSACTL_CARD_ERROR_ELEM_OWNED: The control element is owned by the other process. * * A set of error code for GError with domain which equals to #alsactl_card_error_quark() */ @@ -123,6 +124,7 @@ typedef enum { ALSACTL_CARD_ERROR_DISCONNECTED, ALSACTL_CARD_ERROR_ELEM_NOT_FOUND, ALSACTL_CARD_ERROR_ELEM_NOT_SUPPORTED, + ALSACTL_CARD_ERROR_ELEM_OWNED, } ALSACtlCardError; #endif diff --git a/src/ctl/card.c b/src/ctl/card.c index e7c051b..a325800 100644 --- a/src/ctl/card.c +++ b/src/ctl/card.c @@ -43,6 +43,7 @@ static const char *const err_msgs[] = { [ALSACTL_CARD_ERROR_DISCONNECTED] = "The card associated to the instance is in disconnect state", [ALSACTL_CARD_ERROR_ELEM_NOT_FOUND] = "The control element not found in the card", [ALSACTL_CARD_ERROR_ELEM_NOT_SUPPORTED] = "The operation is not supported by the control element.", + [ALSACTL_CARD_ERROR_ELEM_OWNED] = "The control element is owned by the other process.", }; #define generate_local_error(exception, code) \ @@ -449,6 +450,8 @@ void alsactl_card_lock_elem(ALSACtlCard *self, const ALSACtlElemId *elem_id, generate_local_error(error, ALSACTL_CARD_ERROR_DISCONNECTED); else if (errno == ENOENT) generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_NOT_FOUND); + else if ((errno == EBUSY && lock) || (errno == EPERM && !lock)) + generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_OWNED); else generate_syscall_error(error, errno, "ioctl(%s)", req_name); } @@ -600,6 +603,8 @@ void alsactl_card_write_elem_tlv(ALSACtlCard *self, generate_local_error(error, ALSACTL_CARD_ERROR_DISCONNECTED); else if (errno == ENOENT) generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_NOT_FOUND); + else if (errno == EPERM) + generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_OWNED); else generate_syscall_error(error, errno, "ioctl(%s)", "TLV_WRITE"); } @@ -707,6 +712,8 @@ void alsactl_card_command_elem_tlv(ALSACtlCard *self, generate_local_error(error, ALSACTL_CARD_ERROR_DISCONNECTED); else if (errno == ENOENT) generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_NOT_FOUND); + else if (errno == EPERM) + generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_OWNED); else generate_syscall_error(error, errno, "ioctl(%s)", "TLV_COMMAND"); } @@ -795,12 +802,16 @@ static void add_or_replace_elems(int fd, const ALSACtlElemId *elem_id, info->owner = (__kernel_pid_t)elem_count; if (ioctl(fd, request, info) < 0) { - if (errno == ENODEV) + if (errno == ENODEV) { generate_local_error(error, ALSACTL_CARD_ERROR_DISCONNECTED); - else if (errno == ENOENT) + } else if (errno == ENOENT) { generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_NOT_FOUND); - else + } else if (errno == EBUSY) { + if (replace) + generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_OWNED); + } else { generate_syscall_error(error, errno, "ioctl(%s)", req_name); + } } g_free((void *)info->value.enumerated.names_ptr); if (*error != NULL) @@ -906,6 +917,8 @@ void alsactl_card_remove_elems(ALSACtlCard *self, const ALSACtlElemId *elem_id, generate_local_error(error, ALSACTL_CARD_ERROR_DISCONNECTED); else if (errno == ENOENT) generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_NOT_FOUND); + else if (errno == EBUSY) + generate_local_error(error, ALSACTL_CARD_ERROR_ELEM_OWNED); else generate_syscall_error(error, errno, "ioctl(%s)", "ELEM_REMOVE"); } diff --git a/tests/alsactl-enums b/tests/alsactl-enums index 80db406..7524b1e 100644 --- a/tests/alsactl-enums +++ b/tests/alsactl-enums @@ -56,6 +56,7 @@ card_error_types = ( 'DISCONNECTED', 'ELEM_NOT_FOUND', 'ELEM_NOT_SUPPORTED', + 'ELEM_OWNED', ) types = { -- 2.47.3