// File: /workspace/github_c_makefile_star2_O0/ohkimur[P]the-c-programming-language-2nd-edition-solutions/chapter_8/exercise_8_04/syscalls.c
// Function: file_open
FILE *file_open(char *name, char *mode)
{
  int file_descriptor;
  FILE *file_p;

  if (*mode != 'r' && *mode != 'w' && *mode != 'a')
  {
    return NULL;
  }

  for (file_p = _io_buffer; file_p < _io_buffer + MAX_NR_OF_OPEN_FILES; ++file_p)
  {
    if (file_p->flag._READ == 0 && file_p->flag._WRITE == 0)
    {
      break; // found free slot
    }
  }

  if (file_p >= _io_buffer + MAX_NR_OF_OPEN_FILES)
  {
    return NULL; // no free slots
  }

  if (*mode == 'w')
  {
    file_descriptor = creat(name, PERMISSIONS);
  }
  else if (*mode == 'a')
  {
    if ((file_descriptor = open(name, O_WRONLY, 0)) == -1)
    {
      file_descriptor = creat(name, PERMISSIONS);
    }
    lseek(file_descriptor, 0L, 2);
  }
  else
  {
    file_descriptor = open(name, O_RDONLY, 0);
  }

  if (file_descriptor == -1)
  {
    return NULL; // couldn't access name
  }

  file_p->file_descriptor = file_descriptor;
  file_p->counter = 0;
  file_p->base = NULL;
  file_p->flag._EOF = 0;
  file_p->flag._ERR = 0;
  file_p->flag._READ = (*mode == 'r') ? 1 : 0;
  file_p->flag._WRITE = (*mode == 'r') ? 0 : 1;

  return file_p;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x72, %eax
je 0x1511
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x77, %eax
je 0x1511
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x61, %eax
je 0x1511
movq $0x0, -0x8(%rbp)
jmp 0x16b5
leaq 0x2b58(%rip), %rax      # 0x4070
movq %rax, -0x28(%rbp)
leaq 0x2b4d(%rip), %rax      # 0x4070
addq $0x280, %rax            # imm = 0x280
cmpq %rax, -0x28(%rbp)
jae 0x156b
movq -0x28(%rbp), %rax
movb 0x18(%rax), %al
shlb $0x7, %al
sarb $0x7, %al
movsbl %al, %eax
cmpl $0x0, %eax
jne 0x155b
movq -0x28(%rbp), %rax
movb 0x18(%rax), %al
shlb $0x6, %al
sarb $0x7, %al
movsbl %al, %eax
cmpl $0x0, %eax
jne 0x155b
jmp 0x156b
jmp 0x155d
movq -0x28(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x28(%rbp)
jmp 0x151c
leaq 0x2afe(%rip), %rax      # 0x4070
addq $0x280, %rax            # imm = 0x280
cmpq %rax, -0x28(%rbp)
jb 0x158b
movq $0x0, -0x8(%rbp)
jmp 0x16b5
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x77, %eax
jne 0x15aa
movq -0x10(%rbp), %rdi
movl $0x1b6, %esi            # imm = 0x1B6
callq 0x10a0
movl %eax, -0x1c(%rbp)
jmp 0x1608
movq -0x18(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x61, %eax
jne 0x15f4
movq -0x10(%rbp), %rdi
movl $0x1, %esi
xorl %edx, %edx
movb $0x0, %al
callq 0x1090
movl %eax, -0x1c(%rbp)
cmpl $-0x1, %eax
jne 0x15e1
movq -0x10(%rbp), %rdi
movl $0x1b6, %esi            # imm = 0x1B6
callq 0x10a0
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x1050
jmp 0x1606
movq -0x10(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
movb $0x0, %al
callq 0x1090
movl %eax, -0x1c(%rbp)
jmp 0x1608
cmpl $-0x1, -0x1c(%rbp)
jne 0x161b
movq $0x0, -0x8(%rbp)
jmp 0x16b5
movl -0x1c(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x28(%rbp), %rax
movl $0x0, (%rax)
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x28(%rbp), %rax
movb 0x18(%rax), %cl
andb $-0x9, %cl
orb $0x0, %cl
movb %cl, 0x18(%rax)
movq -0x28(%rbp), %rax
movb 0x18(%rax), %cl
andb $-0x11, %cl
orb $0x0, %cl
movb %cl, 0x18(%rax)
movq -0x18(%rbp), %rax
movsbl (%rax), %edx
xorl %ecx, %ecx
movl $0x1, %eax
cmpl $0x72, %edx
cmovel %eax, %ecx
movq -0x28(%rbp), %rax
movb %cl, %dl
movb 0x18(%rax), %cl
andb $0x1, %dl
andb $-0x2, %cl
orb %dl, %cl
movb %cl, 0x18(%rax)
movq -0x18(%rbp), %rax
movsbl (%rax), %edx
movl $0x1, %ecx
xorl %eax, %eax
cmpl $0x72, %edx
cmovel %eax, %ecx
movq -0x28(%rbp), %rax
movb %cl, %dl
movb 0x18(%rax), %cl
andb $0x1, %dl
shlb %dl
andb $-0x3, %cl
orb %dl, %cl
movb %cl, 0x18(%rax)
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x30, %rsp
popq %rbp
retq
nop