// File: chlunde[P]qtar/linux_getdents.cc
// Function: dir_read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::vector<us_dirent, std::allocator<us_dirent>>&)
int
dir_read(std::string& path, std::vector<struct us_dirent>& dest)
{
	int fd = open(path.c_str(), O_DIRECTORY | O_RDONLY);
	int written;
	int offset = 0;

#define buf_size 4096
	char buf[buf_size];

	if (fd < 0) {
		err(EXIT_FAILURE, "open %s", path.c_str());
	}

	do {
		written = linux_getdents(fd, buf, buf_size);
		if (written < 0) {
			err(EXIT_FAILURE, "getdents %s", path.c_str());
		}

		offset = 0;

		while (offset < written) {
			struct linux_dirent *s = (struct linux_dirent*)(buf + offset);
			struct us_dirent d;
			char *type = buf + offset + s->d_reclen - 1;

			d.d_ino = s->d_ino;
			d.d_name = std::string(s->d_name);
			d.d_type = *type;
			d.parent = path;

			dest.push_back(d);
#if 0
			std::push_heap(dest.begin(), dest.end());
#endif

			offset += s->d_reclen;
		}
	} while (written > 0);

	close(fd);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1170, %rsp           # imm = 0x1170
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0x3130
movq %rax, %rdi
movl $0x10000, %esi          # imm = 0x10000
movb $0x0, %al
callq 0x3220
movl %eax, -0x14(%rbp)
movl $0x0, -0x1c(%rbp)
cmpl $0x0, -0x14(%rbp)
jge 0xbdca
movq -0x8(%rbp), %rdi
callq 0x3130
movq %rax, %rdx
movl $0x1, %edi
leaq 0x130f(%rip), %rsi      # 0xd0d2
movb $0x0, %al
callq 0x3290
jmp 0xbdcc
movl -0x14(%rbp), %edi
leaq -0x1020(%rbp), %rsi
movl $0x1000, %edx           # imm = 0x1000
callq 0xbfb0
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jge 0xbe08
movq -0x8(%rbp), %rdi
callq 0x3130
movq %rax, %rdx
movl $0x1, %edi
leaq 0x12d9(%rip), %rsi      # 0xd0da
movb $0x0, %al
callq 0x3290
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0xbf76
movslq -0x1c(%rbp), %rax
leaq -0x1020(%rbp,%rax), %rax
movq %rax, -0x1028(%rbp)
leaq -0x1110(%rbp), %rdi
callq 0x53d0
movslq -0x1c(%rbp), %rax
leaq -0x1020(%rbp,%rax), %rcx
movq -0x1028(%rbp), %rax
movzwl 0x10(%rax), %eax
leaq -0x1(%rax,%rcx), %rax
movq %rax, -0x1118(%rbp)
movq -0x1028(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1110(%rbp)
movq -0x1028(%rbp), %rax
addq $0x12, %rax
movq %rax, -0x1160(%rbp)
leaq -0x1139(%rbp), %rdi
movq %rdi, -0x1158(%rbp)
callq 0x3490
movq -0x1160(%rbp), %rsi
movq -0x1158(%rbp), %rdx
leaq -0x1138(%rbp), %rdi
callq 0x38f0
jmp 0xbeaf
leaq -0x1108(%rbp), %rdi
leaq -0x1138(%rbp), %rsi
movq %rsi, -0x1168(%rbp)
callq 0x3370
movq -0x1168(%rbp), %rdi
callq 0x31c0
leaq -0x1139(%rbp), %rdi
callq 0x3310
movq -0x1118(%rbp), %rax
movb (%rax), %al
movb %al, -0x10c8(%rbp)
movq -0x8(%rbp), %rsi
leaq -0x10e8(%rbp), %rdi
callq 0x3030
jmp 0xbf02
movq -0x10(%rbp), %rdi
leaq -0x1110(%rbp), %rsi
callq 0xbfe0
jmp 0xbf14
movq -0x1028(%rbp), %rax
movzwl 0x10(%rax), %eax
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
leaq -0x1110(%rbp), %rdi
callq 0x4700
jmp 0xbe0f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1148(%rbp)
movl %eax, -0x114c(%rbp)
leaq -0x1139(%rbp), %rdi
callq 0x3310
jmp 0xbf68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1148(%rbp)
movl %eax, -0x114c(%rbp)
leaq -0x1110(%rbp), %rdi
callq 0x4700
jmp 0xbf95
jmp 0xbf78
cmpl $0x0, -0x18(%rbp)
jg 0xbdcc
movl -0x14(%rbp), %edi
callq 0x3520
xorl %eax, %eax
addq $0x1170, %rsp           # imm = 0x1170
popq %rbp
retq
movq -0x1148(%rbp), %rdi
callq 0x3480
nopw %cs:(%rax,%rax)