// File: /workspace/github_cpp_makefile_star2_O3/jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_env_open
int ESECT
mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
{
	int		oflags, rc, len, excl = -1;
	char *lpath, *dpath;

	if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS)))
		return EINVAL;

	len = strlen(path);
	if (flags & MDB_NOSUBDIR) {
		rc = len + sizeof(LOCKSUFF) + len + 1;
	} else {
		rc = len + sizeof(LOCKNAME) + len + sizeof(DATANAME);
	}
	lpath = malloc(rc);
	if (!lpath)
		return ENOMEM;
	if (flags & MDB_NOSUBDIR) {
		dpath = lpath + len + sizeof(LOCKSUFF);
		sprintf(lpath, "%s" LOCKSUFF, path);
		strcpy(dpath, path);
	} else {
		dpath = lpath + len + sizeof(LOCKNAME);
		sprintf(lpath, "%s" LOCKNAME, path);
		sprintf(dpath, "%s" DATANAME, path);
	}

	rc = MDB_SUCCESS;
	flags |= env->me_flags;
	if (flags & MDB_RDONLY) {
		/* silently ignore WRITEMAP when we're only getting read access */
		flags &= ~MDB_WRITEMAP;
	} else {
		if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) &&
			  (env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2)))))
			rc = ENOMEM;
	}
	env->me_flags = flags |= MDB_ENV_ACTIVE;
	if (rc)
		goto leave;

	env->me_path = strdup(path);
	env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDB_dbx));
	env->me_dbflags = calloc(env->me_maxdbs, sizeof(uint16_t));
	env->me_dbiseqs = calloc(env->me_maxdbs, sizeof(unsigned int));
	if (!(env->me_dbxs && env->me_path && env->me_dbflags && env->me_dbiseqs)) {
		rc = ENOMEM;
		goto leave;
	}
	env->me_dbxs[FREE_DBI].md_cmp = mdb_cmp_long; /* aligned MDB_INTEGERKEY */

	/* For RDONLY, get lockfile after we know datafile exists */
	if (!(flags & (MDB_RDONLY|MDB_NOLOCK))) {
		rc = mdb_env_setup_locks(env, lpath, mode, &excl);
		if (rc)
			goto leave;
	}

#ifdef _WIN32
	if (F_ISSET(flags, MDB_RDONLY)) {
		oflags = GENERIC_READ;
		len = OPEN_EXISTING;
	} else {
		oflags = GENERIC_READ|GENERIC_WRITE;
		len = OPEN_ALWAYS;
	}
	mode = FILE_ATTRIBUTE_NORMAL;
	env->me_fd = CreateFileA(dpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL, len, mode, NULL);
#else
	if (F_ISSET(flags, MDB_RDONLY))
		oflags = O_RDONLY;
	else
		oflags = O_RDWR | O_CREAT;

	env->me_fd = open(dpath, oflags, mode);
#endif
	if (env->me_fd == INVALID_HANDLE_VALUE) {
		rc = ErrCode();
		goto leave;
	}

	if ((flags & (MDB_RDONLY|MDB_NOLOCK)) == MDB_RDONLY) {
		rc = mdb_env_setup_locks(env, lpath, mode, &excl);
		if (rc)
			goto leave;
	}

	if ((rc = mdb_env_open2(env)) == MDB_SUCCESS) {
		if (flags & (MDB_RDONLY|MDB_WRITEMAP)) {
			env->me_mfd = env->me_fd;
		} else {
			/* Synchronous fd for meta writes. Needed even with
			 * MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset.
			 */
#ifdef _WIN32
			len = OPEN_EXISTING;
			env->me_mfd = CreateFileA(dpath, oflags,
				FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len,
				mode | FILE_FLAG_WRITE_THROUGH, NULL);
#else
			oflags &= ~O_CREAT;
			env->me_mfd = open(dpath, oflags | MDB_DSYNC, mode);
#endif
			if (env->me_mfd == INVALID_HANDLE_VALUE) {
				rc = ErrCode();
				goto leave;
			}
		}
		DPRINTF(("opened dbenv %p", (void *) env));
		if (excl > 0) {
			rc = mdb_env_share_locks(env, &excl);
			if (rc)
				goto leave;
		}
		if (!(flags & MDB_RDONLY)) {
			MDB_txn *txn;
			int tsize = sizeof(MDB_txn), size = tsize + env->me_maxdbs *
				(sizeof(MDB_db)+sizeof(MDB_cursor *)+sizeof(unsigned int)+1);
			if ((env->me_pbuf = calloc(1, env->me_psize)) &&
				(txn = calloc(1, size)))
			{
				txn->mt_dbs = (MDB_db *)((char *)txn + tsize);
				txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs);
				txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs);
				txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs);
				txn->mt_env = env;
				txn->mt_dbxs = env->me_dbxs;
				txn->mt_flags = MDB_TXN_FINISHED;
				env->me_txn0 = txn;
			} else {
				rc = ENOMEM;
			}
		}
	}

leave:
	if (rc) {
		mdb_env_close0(env, excl);
	}
	free(lpath);
	return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl $0xffffffff, 0x4(%rsp)  # imm = 0xFFFFFFFF
movl $0x16, %r12d
testl $0xfe00bffe, %edx       # imm = 0xFE00BFFE
jne 0xc5a0
movq %rdi, %rbx
cmpl $-0x1, (%rdi)
jne 0xc5a0
movl %ecx, %r14d
movl %edx, %ebp
movq %rsi, %r13
movq %rsi, %rdi
callq 0x2110
movq %rax, %r12
btl $0xe, %ebp
leal 0x14(%rax,%rax), %eax
leal 0x7(%r12,%r12), %ecx
cmovael %eax, %ecx
movslq %ecx, %rdi
callq 0x2270
testq %rax, %rax
je 0xc2cf
movslq %r12d, %r15
addq %rax, %r15
btl $0xe, %ebp
movq %rax, 0x8(%rsp)
jb 0xc2da
addq $0xa, %r15
leaq 0x3195(%rip), %rsi      # 0xf441
movq %rax, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x2370
leaq 0x318d(%rip), %rsi      # 0xf44d
movq %r15, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x2370
jmp 0xc2fd
movl $0xc, %r12d
jmp 0xc5a0
addq $0x6, %r15
leaq 0x3154(%rip), %rsi      # 0xf439
movq %rax, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x2370
movq %r15, %rdi
movq %r13, %rsi
callq 0x2080
orl 0xc(%rbx), %ebp
btl $0x11, %ebp
jb 0xc34a
movl $0x1ffff, %edi          # imm = 0x1FFFF
callq 0xb9fb
movq %rax, 0xc8(%rbx)
testq %rax, %rax
je 0xc472
movl $0x20000, %edi          # imm = 0x20000
movl $0x10, %esi
callq 0x2200
movq %rax, 0xd0(%rbx)
testq %rax, %rax
je 0xc472
movq %r15, 0x10(%rsp)
movl %r14d, (%rsp)
jmp 0xc359
movq %r15, 0x10(%rsp)
movl %r14d, (%rsp)
andl $0xfff7ffff, %ebp       # imm = 0xFFF7FFFF
movl %ebp, %eax
orl $0x20000000, %eax       # imm = 0x20000000
movl %eax, 0xc(%rbx)
movq %r13, %rdi
callq 0x23c0
movq %rax, %r14
movq %rax, 0x30(%rbx)
movl 0x24(%rbx), %r12d
movl $0x30, %esi
movq %r12, %rdi
callq 0x2200
movq %rax, %r13
movq %rax, 0x88(%rbx)
movl $0x2, %esi
movq %r12, %rdi
callq 0x2200
movq %rax, %r15
movq %rax, 0x90(%rbx)
movl $0x4, %esi
movq %r12, %rdi
callq 0x2200
movq %rax, 0x98(%rbx)
testq %r13, %r13
sete %cl
testq %r14, %r14
sete %dl
orb %cl, %dl
movl $0xc, %r14d
jne 0xc58b
testq %r15, %r15
sete %cl
testq %rax, %rax
sete %al
orb %cl, %al
jne 0xc58b
leaq -0x93aa(%rip), %rax     # 0x3043
movq %rax, 0x10(%r13)
movl %ebp, %r15d
andl $0x420000, %r15d        # imm = 0x420000
je 0xc486
xorl %eax, %eax
btl $0x11, %ebp
movl $0x42, %r13d
cmovbl %eax, %r13d
movq 0x10(%rsp), %r12
movq %r12, %rdi
movl %r13d, %esi
movl (%rsp), %edx
xorl %eax, %eax
callq 0x2310
movl %eax, (%rbx)
cmpl $-0x1, %eax
je 0xc57d
cmpl $0x20000, %r15d         # imm = 0x20000
movl (%rsp), %r15d
jne 0xc457
leaq 0x4(%rsp), %rcx
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movl %r15d, %edx
callq 0xc5b7
testl %eax, %eax
jne 0xc4a3
movq %rbx, %rdi
callq 0xc81d
testl %eax, %eax
jne 0xc4a3
testl $0xa0000, %ebp          # imm = 0xA0000
je 0xc4ab
movl (%rbx), %eax
movl %eax, 0x8(%rbx)
jmp 0xc4d2
orl $0x20000000, %ebp       # imm = 0x20000000
movl %ebp, 0xc(%rbx)
movl $0xc, %r14d
jmp 0xc58b
leaq 0x4(%rsp), %rcx
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
movl (%rsp), %edx
callq 0xc5b7
testl %eax, %eax
je 0xc401
movl %eax, %r14d
jmp 0xc58b
andl $0x2, %r13d
orl $0x1000, %r13d          # imm = 0x1000
movq %r12, %rdi
movl %r13d, %esi
movl %r15d, %edx
xorl %eax, %eax
callq 0x2310
movl %eax, 0x8(%rbx)
cmpl $-0x1, %eax
je 0xc57d
cmpl $0x0, 0x4(%rsp)
jle 0xc4ee
leaq 0x4(%rsp), %rsi
movq %rbx, %rdi
callq 0xcb5f
testl %eax, %eax
jne 0xc584
xorl %r12d, %r12d
btl $0x11, %ebp
jb 0xc596
movl 0x10(%rbx), %esi
movl 0x24(%rbx), %r15d
movl $0x1, %edi
callq 0x2200
movq %rax, 0x58(%rbx)
testq %rax, %rax
je 0xc58b
imull $0x3d, %r15d, %eax
addl $0x88, %eax
movslq %eax, %rsi
movl $0x1, %edi
callq 0x2200
testq %rax, %rax
je 0xc58b
leaq 0x88(%rax), %rcx
movq %rcx, 0x58(%rax)
leaq (%r15,%r15,2), %rcx
shlq $0x4, %rcx
addq %rax, %rcx
addq $0x88, %rcx
movq %rcx, 0x68(%rax)
leaq (%rcx,%r15,8), %rcx
movq %rcx, 0x60(%rax)
leaq (%rcx,%r15,4), %rcx
movq %rcx, 0x70(%rax)
movq %rbx, 0x20(%rax)
movq 0x88(%rbx), %rcx
movq %rcx, 0x50(%rax)
movl $0x1, 0x7c(%rax)
movq %rax, 0x68(%rbx)
jmp 0xc596
callq 0x2050
movl (%rax), %eax
movl %eax, %r14d
testl %eax, %eax
je 0xc5b2
movq %rbx, %rdi
callq 0xcbf1
movl %r14d, %r12d
movq 0x8(%rsp), %rdi
callq 0x2030
movl %r12d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r12d, %r12d
jmp 0xc596