Seems like you're right. Whoops, time to go fix some of my code, which is why I really want a non-broken posix_spawn().
Another silly way to do things is to have the parent process send a list of fds to close over a pipe, which at least doesn't require a second call to exec().
I think the problem with close-on-exec is always going to be simple though: you have to make sure every library you use sets the flag.