user: 请将这段汇编代码片段转换成等效的C代码：

```asm
<udev_node_remove>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  mov    %rdi,%r12
  push   %rbp
  push   %rbx
  sub    $0x428,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x418(%rsp)
  xor    %eax,%eax
  call   <udev_device_get_udev@plt>
  mov    %r12,%rdi
  mov    %rax,%r13
  call   <udev_device_get_devlinks_list_entry@plt>
  test   %rax,%rax
  je     L28
  mov    %rax,%rbp
  nopl   0x0(%rax,%rax,1)
L109:
  mov    %rbp,%rdi
  call   <udev_list_entry_get_name@plt>
  xor    %edx,%edx
  mov    %r12,%rdi
  mov    %eax,%esi
  call   <link_update@plt>
  mov    %rbp,%rdi
  call   <udev_list_entry_get_next@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  jne    L109
L28:
  mov    %r12,%rdi
  xor    %r15d,%r15d
  call   <udev_device_get_devnode@plt>
  mov    %rax,%r14
  test   %rax,%rax
  je     L40
  lea    0x8(%rsp),%rsi
  mov    %rax,%rdi
  call   <stat@plt>
  test   %rax,%rax
  jne    L26
  mov    0x8(%rsp),%rbp
  mov    %r12,%rdi
  call   <udev_device_get_devnum@plt>
  cmp    %rax,%rbp
  jne    L49
  mov    %r12,%rdi
  call   <udev_device_get_syspath@plt>
  mov    %r13,%rdi
  mov    %eax,%esi
  call   <udev_device_new_from_syspath@plt>
  mov    %r14,%rdx
  mov    %rax,%rbp
  test   %rax,%rax
  je     L63
  mov    %r13,%rdi
  lea    D61(%rip),%rsi
  call   <udev_log_null@plt>
  mov    %rbp,%rdi
  call   <udev_device_unref@plt>
L40:
  mov    0x418(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L35
  add    $0x428,%rsp
  mov    %r15d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L26:
  mov    %r14,%rdx
  lea    D68(%rip),%rsi
  mov    %r13,%rdi
  call   <udev_log_null@plt>
  jmp    L40
  nopl   0x0(%rax)
L63:
  lea    D19(%rip),%rsi
  mov    %r13,%rdi
  call   <udev_log_null@plt>
  mov    %r14,%rsi
  mov    %r13,%rdi
  call   <util_unlink_secure@plt>
  mov    %eax,%r15d
  test   %eax,%eax
  je     L20
L101:
  mov    %r12,%rdi
  lea    D57(%rip),%rbp
  call   <udev_device_get_devnum@plt>
  mov    %rax,%rdi
  call   <minor@plt>
  mov    %r12,%rdi
  mov    %eax,%ebx
  call   <udev_device_get_devnum@plt>
  mov    %rax,%rdi
  call   <major@plt>
  mov    %r12,%rdi
  lea    0x10(%rsp),%r12
  mov    %eax,%r14d
  call   <udev_device_get_subsystem@plt>
  mov    %rbp,%rsi
  mov    %eax,%edi
  call   <strcmp@plt>
  mov    %r13,%rdi
  test   %rax,%rax
  lea    D14(%rip),%rax
  cmovne %rax,%rbp
  call   <udev_get_dev_path@plt>
  sub    $0x8,%rsp
  mov    %r14d,%r9d
  mov    %r12,%rdi
  push   %rbx
  lea    D23(%rip),%rdx
  mov    %rax,%rcx
  mov    %rbp,%r8
  mov    $0x400,%esi
  call   <snprintf@plt>
  mov    %r12,%rdi
  call   <unlink@plt>
  pop    %rax
  pop    %rdx
  jmp    L40
L20:
  mov    %r14,%rsi
  mov    %r13,%rdi
  call   <util_delete_path@plt>
  jmp    L101
L49:
  mov    %r14,%rdx
  lea    D43(%rip),%rsi
  mov    %r13,%rdi
  mov    $0xffffffff,%r15d
  call   <udev_log_null@plt>
  jmp    L40
L35:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: disassemble_data
arguments: tag: D61
type_infered: string
name: disassemble_data
arguments: tag: D68
type_infered: string
name: disassemble_data
arguments: tag: D19
type_infered: string
name: disassemble_data
arguments: tag: D57
type_infered: string
name: disassemble_data
arguments: tag: D14
type_infered: string
name: disassemble_data
arguments: tag: D23
type_infered: string
name: disassemble_data
arguments: tag: D43
type_infered: string

tool: D61: keeping device node of existing device'%s'


tool: D68: device node '%s' not found


tool: D19: removing device node '%s'


tool: D57: block

tool: D14: char

tool: D23: %s/%s/%u:%u

tool: D43: device node '%s' points to a different device, skip removal


assistant: ```c
int udev_node_remove(struct udev_device *dev) {
  struct udev *udev = udev_device_get_udev(dev);
  struct udev_list_entry *list_entry;
  const char *devnode;
  struct stat stats;
  struct udev_device *dev_check;
  char filename[1024];
  int err = 0;
  for (list_entry = udev_device_get_devlinks_list_entry(dev); list_entry != NULL; list_entry = udev_list_entry_get_next(list_entry))
    link_update(dev, udev_list_entry_get_name(list_entry), 0);
  devnode = udev_device_get_devnode(dev);
  if (devnode == NULL)
    goto out;
  if (stat(devnode, &stats) != 0) {
    udev_log_null(udev, "device node '%s' not found\n", devnode);
    goto out;
  }
  if (stats.st_rdev != udev_device_get_devnum(dev)) {
    udev_log_null(udev, "device node '%s' points to a different device, skip removal\n", devnode);
    err = -1;
    goto out;
  }
  dev_check = udev_device_new_from_syspath(udev, udev_device_get_syspath(dev));
  if (dev_check != NULL) {
    udev_log_null(udev, "keeping device node of existing device'%s'\n", devnode);
    udev_device_unref(dev_check);
    goto out;
  }
  udev_log_null(udev, "removing device node '%s'\n", devnode);
  err = util_unlink_secure(udev, devnode);
  if (err == 0)
    util_delete_path(udev, devnode);
  snprintf(filename, sizeof(filename), "%s/%s/%u:%u", udev_get_dev_path(udev), strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char", major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
  unlink(filename);
out:
  return err;
}
```