]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
ctl: card: report error due to operations against element owned by the other processes
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Fri, 13 Nov 2020 07:26:26 +0000 (16:26 +0900)
committer坂本 貴史 <o-takashi@sakamocchi.jp>
Fri, 13 Nov 2020 23:30:49 +0000 (08:30 +0900)
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 <o-takashi@sakamocchi.jp>
src/ctl/alsactl-enum-types.h
src/ctl/card.c
tests/alsactl-enums

index e39bdacfefe9d60bce1ee6140782c3fca2758722..01a8c90e029a4b792ae0e52f1805f557027b024c 100644 (file)
@@ -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
index e7c051b24b77e2f05b1bc4bce8f0cf3ca2b50031..a325800f9d9022628a785f852c73937a8ebdf2cd 100644 (file)
@@ -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");
     }
index 80db406ba1ea8c049e1122c4638b846271c44df4..7524b1e038c37d997d12f8dfe6abe483c4b99a1c 100644 (file)
@@ -56,6 +56,7 @@ card_error_types = (
     'DISCONNECTED',
     'ELEM_NOT_FOUND',
     'ELEM_NOT_SUPPORTED',
+    'ELEM_OWNED',
 )
 
 types = {