/* use file descriptor instead.
(danach prüfen wir die Sicherheit des Verzeichnisses)
*/
if (fstat(dirfd, &st_dir_now) < 0)
goto err_mkhtemp;
/* mitigate symlink attacks before open
*/
if (st_dir_now.st_dev != st_dir_initial->st_dev ||
st_dir_now.st_ino != st_dir_initial->st_ino) {
errno = ESTALE;
goto err_mkhtemp;
}

*fd = openat2p(dirfd, fname_copy,
O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC |
O_NOCTTY, 0600);

/* for mkhtemp. hardened mktemp */

int
openat2p(int dirfd, const char *path,
int flags, mode_t mode)
{
#ifdef __linux__
struct open_how how = {
.flags = flags,
.mode = mode,
.resolve =
RESOLVE_BENEATH |
RESOLVE_NO_SYMLINKS |
RESOLVE_NO_MAGICLINKS
};
#endif

if (dirfd < 0) {
errno = EBADF;
return -1;
}

if (path == NULL) {
errno = EFAULT;
return -1;
}

#ifdef __linux__
return syscall(SYS_openat2, dirfd, path, &how, sizeof(how));
#else
return openat(dirfd, path, flags, mode);
#endif
}