// File: /workspace/github_c_makefile_star2_O2/wahern[P]cqueues/src/lib/notify.c
// Function: notify_opendir
struct notify *notify_opendir(const char *dirpath, int flags, int *_error) {
	struct notify *nfy = NULL;
	size_t dirlen = strlen(dirpath);
	size_t padlen = NAME_MAX + 2;
	int error;

	while (dirlen > 1 && dirpath[dirlen - 1] == '/')
		--dirlen;

	if (~padlen < dirlen) {
		error = ENAMETOOLONG;
		goto error;
	}

	if (!(nfy = calloc(1, offsetof(struct notify, dirpath) + dirlen + padlen)))
		goto syerr;

	nfy->fd = -1;
	nfy->flags = flags;

	nfy->dirfd = -1;
	nfy->dirwd = -1;
	nfy->dirlen = dirlen;
	memcpy(nfy->dirpath, dirpath, dirlen);

#if ENABLE_INOTIFY
#if HAVE_INOTIFY_INIT1 && HAVE_IN_NONBLOCK && HAVE_IN_CLOEXEC
	if (-1 == (nfy->fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)))
		goto syerr;
#else
	if (-1 == (nfy->fd = inotify_init()))
		goto syerr;

	if ((error = cloexec(nfy->fd)))
		goto error;

	if ((error = nonblock(nfy->fd)))
		goto error;
#endif

	if (-1 == (nfy->dirwd = inotify_add_watch(nfy->fd, nfy->dirpath, IN_ATTRIB|IN_CREATE|IN_DELETE|IN_DELETE_SELF|IN_MODIFY|IN_MOVE|IN_MOVE_SELF|IN_ONLYDIR)))
		goto syerr;
#elif ENABLE_FEN
	if (-1 == (nfy->fd = port_create())) {
		if (errno == EAGAIN)
			errno = EMFILE;
		goto syerr;
	}

	if ((error = cloexec(nfy->fd)))
		goto error;

	if ((error = nfy_openfd(&nfy->dirfd, .path = nfy->dirpath, .rdonly = 1, .cloexec = 1, .directory = 1)))
		goto error;

	fenfo_init(&nfy->dirfo, nfy->dirpath);

	if (0 != port_associate(nfy->fd, PORT_SOURCE_FILE, (intptr_t)&nfy->dirfo, FILE_MODIFIED|FILE_ATTRIB|FILE_NOFOLLOW, nfy))
		goto syerr;
#else
#if HAVE_KQUEUE1 && HAVE_O_CLOEXEC
	if (-1 == (nfy->fd = kqueue1(O_CLOEXEC)))
		goto syerr;
#else
	if (-1 == (nfy->fd = kqueue()))
		goto syerr;

	if ((error = cloexec(nfy->fd)))
		goto error;
#endif

	if ((error = nfy_openfd(&nfy->dirfd, .path = nfy->dirpath, .rdonly = 1, .cloexec = 1, .directory = 1)))
		goto error;

	struct kevent event;

	NFY_SET(&event, nfy->dirfd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_REVOKE, 0, nfy);

	if (0 != kevent(nfy->fd, &event, 1, NULL, 0, &(struct timespec){ 0, 0 }))
		goto syerr;
#endif

	return nfy;
syerr:
	error = errno;
error:
	*_error = error;

	notify_close(nfy);

	return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movl %esi, %ebp
movq %rdi, %r12
callq 0xf580
movq %rax, %r13
xorl %eax, %eax
testq %r13, %r13
setne %al
cmpq $0x2, %r13
jb 0x2e5be
cmpb $0x2f, -0x1(%r12,%r13)
jne 0x2e5c3
decq %r13
jmp 0x2e5ab
movq %rax, %r13
jmp 0x2e5d7
cmpq $-0x102, %r13           # imm = 0xFEFE
jbe 0x2e5d7
pushq $0x24
popq %rax
xorl %r14d, %r14d
jmp 0x2e6b4
leaq 0x169(%r13), %rsi
pushq $0x1
popq %rdi
callq 0xf8f0
movq %rax, %r14
testq %rax, %rax
je 0x2e6ad
orl $-0x1, (%r14)
movl %ebp, 0x48(%r14)
orq $-0x1, 0x54(%r14)
movq %r13, 0x60(%r14)
movq %r14, %r15
addq $0x68, %r15
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xfad0
callq 0x10930
movl %eax, (%r14)
cmpl $-0x1, %eax
je 0x2e6ad
movl %eax, %ebp
pushq $0x1
popq %rsi
movl %eax, %edi
xorl %eax, %eax
callq 0xf7f0
cmpl $-0x1, %eax
je 0x2e652
orl $0x1, %eax
pushq $0x2
popq %rsi
movl %ebp, %edi
movl %eax, %edx
xorl %eax, %eax
callq 0xf7f0
cmpl $-0x1, %eax
jne 0x2e65d
callq 0xf0a0
movl (%rax), %eax
testl %eax, %eax
jne 0x2e6b4
movl (%r14), %ebp
pushq $0x3
popq %rsi
movl %ebp, %edi
xorl %eax, %eax
callq 0xf7f0
cmpl $-0x1, %eax
je 0x2e689
orl $0x800, %eax            # imm = 0x800
pushq $0x4
popq %rsi
movl %ebp, %edi
movl %eax, %edx
xorl %eax, %eax
callq 0xf7f0
cmpl $-0x1, %eax
jne 0x2e694
callq 0xf0a0
movl (%rax), %eax
testl %eax, %eax
jne 0x2e6b4
movl (%r14), %edi
movq %r15, %rsi
movl $0x1000fc6, %edx        # imm = 0x1000FC6
callq 0xf720
movl %eax, 0x58(%r14)
cmpl $-0x1, %eax
jne 0x2e6c1
callq 0xf0a0
movl (%rax), %eax
movl %eax, (%rbx)
movq %r14, %rdi
callq 0x10750
xorl %r14d, %r14d
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq