Duh - the mdb_env_copy() FD should have FD_CLOEXEC, since the point was the user can't get at it. Fixed after an off-list discussion. OTOH MDB_env.me_fd should not: mdb_env_get_fd() exposes it, so CLOEXEC would break existing programs.
Another issue is with fork() without exec(). This breaks LMDB: if (fork() == 0) pthread_exit(NULL); because the child's me_txkey destructor releases the reader slot.
This can happen if a single-threaded LMDB process forks a multi- threaded child, which is one way to deal with threads vs. fork().
pthread_atfork() is the official way to deal with that. I'm a bit wary of it since there is no way to unregister an atfork handler. I wonder what happens if the LMDB module was dynamically loaded and then gets unloaded. A simpler way is in any case to check if (reader->mr_pid == getpid()) in mdb_env_reader_dest().
I suppose there could be an mdb_env_fork_cleanup() function which at least closes the FDs, and takes an arg to say whether to free memory too (safe if parent was single-threaded).