user: Please show me the C implementation that matches the assembly code listed below:

```asm
<mutex_attr_show>:
  endbr64
  push   %rbx
  sub    $0x10,%rsp
  mov    %rdi,%rbx
  mov    %fs:0x28,%rax
  mov    %rax,0x8(%rsp)
  xor    %eax,%eax
  mov    %rdi,%rsi
  lea    D68(%rip),%rdi
  call   <printf@plt>
  lea    0x4(%rsp),%rsi
  mov    %rbx,%rdi
  call   <pthread_mutexattr_gettype@plt>
  test   %eax,%eax
  je     L40
  mov    %eax,%esi
  lea    D20(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L9:
  lea    0x4(%rsp),%rsi
  mov    %rbx,%rdi
  call   <pthread_mutexattr_getprioceiling@plt>
  test   %eax,%eax
  je     L0
  mov    %eax,%esi
  lea    D7(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L65:
  lea    0x4(%rsp),%rsi
  mov    %rbx,%rdi
  call   <pthread_mutexattr_getprotocol@plt>
  test   %eax,%eax
  je     L89
  mov    %eax,%esi
  lea    D74(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L69:
  lea    0x4(%rsp),%rsi
  mov    %rbx,%rdi
  call   <pthread_mutexattr_getpshared@plt>
  test   %eax,%eax
  je     L75
  mov    %eax,%esi
  lea    D28(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L29:
  mov    0x8(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L31
  add    $0x10,%rsp
  pop    %rbx
  ret
L40:
  mov    0x4(%rsp),%edi
  call   <mutex_type_str@plt>
  mov    %rax,%rsi
  lea    D60(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L9
L0:
  mov    0x4(%rsp),%esi
  lea    D5(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L65
L89:
  mov    0x4(%rsp),%edi
  call   <mutex_protocol_str@plt>
  mov    %rax,%rsi
  lea    D11(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L69
L75:
  mov    0x4(%rsp),%edi
  call   <mutex_pshared_str@plt>
  mov    %rax,%rsi
  lea    D29(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L29
L31:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: disassemble_data
arguments: label: D68
type_guessed: string
name: disassemble_data
arguments: label: D20
type_guessed: string
name: disassemble_data
arguments: label: D7
type_guessed: string
name: disassemble_data
arguments: label: D74
type_guessed: string
name: disassemble_data
arguments: label: D28
type_guessed: string
name: disassemble_data
arguments: label: D60
type_guessed: string
name: disassemble_data
arguments: label: D5
type_guessed: string
name: disassemble_data
arguments: label: D11
type_guessed: string
name: disassemble_data
arguments: label: D29
type_guessed: string

tool: D68: mutex attributes @ %10p:


tool: D20: ERROR %d returned from pthread_mutexattr_gettype


tool: D7: ERROR %d returned from pthread_mutexattr_getprioceiling


tool: D74: ERROR %d returned from pthread_mutexattr_getprotocol


tool: D28: ERROR %d returned from pthread_mutexattr_getpshared


tool: D60: type=%s


tool: D5: prio_ceiling=%d


tool: D11: protocol=%s


tool: D29: pshared=%s


assistant: ```c
void mutex_attr_show(const pthread_mutexattr_t *attr) {
  int rc;
  int val;
  printf("mutex attributes @ %10p:\n", attr);
  rc = pthread_mutexattr_gettype(attr, &val);
  if (rc != 0)
    printf("ERROR %d returned from pthread_mutexattr_gettype\n", rc);
  else
    printf("type=%s\n", mutex_type_str(val));
  rc = pthread_mutexattr_getprioceiling(attr, &val);
  if (rc != 0)
    printf("ERROR %d returned from pthread_mutexattr_getprioceiling\n", rc);
  else
    printf("prio_ceiling=%d\n", val);
  rc = pthread_mutexattr_getprotocol(attr, &val);
  if (rc != 0)
    printf("ERROR %d returned from pthread_mutexattr_getprotocol\n", rc);
  else
    printf("protocol=%s\n", mutex_protocol_str(val));
  rc = pthread_mutexattr_getpshared(attr, &val);
  if (rc != 0)
    printf("ERROR %d returned from pthread_mutexattr_getpshared\n", rc);
  else
    printf("pshared=%s\n", mutex_pshared_str(val));
}
```