1570af302Sopenharmony_ci#include <dirent.h>
2570af302Sopenharmony_ci#include <fcntl.h>
3570af302Sopenharmony_ci#include <sys/stat.h>
4570af302Sopenharmony_ci#include <errno.h>
5570af302Sopenharmony_ci#include <stdlib.h>
6570af302Sopenharmony_ci#include <stdio.h>
7570af302Sopenharmony_ci#include "__dirent.h"
8570af302Sopenharmony_ci
9570af302Sopenharmony_ciextern uint64_t __get_dir_tag(DIR* dir);
10570af302Sopenharmony_ci
11570af302Sopenharmony_ciDIR *fdopendir(int fd)
12570af302Sopenharmony_ci{
13570af302Sopenharmony_ci	DIR *dir;
14570af302Sopenharmony_ci	struct stat st;
15570af302Sopenharmony_ci
16570af302Sopenharmony_ci	if (fstat(fd, &st) < 0) {
17570af302Sopenharmony_ci		return 0;
18570af302Sopenharmony_ci	}
19570af302Sopenharmony_ci	if (fcntl(fd, F_GETFL) & O_PATH) {
20570af302Sopenharmony_ci		errno = EBADF;
21570af302Sopenharmony_ci		return 0;
22570af302Sopenharmony_ci	}
23570af302Sopenharmony_ci	if (!S_ISDIR(st.st_mode)) {
24570af302Sopenharmony_ci		errno = ENOTDIR;
25570af302Sopenharmony_ci		return 0;
26570af302Sopenharmony_ci	}
27570af302Sopenharmony_ci	if (!(dir = calloc(1, sizeof *dir))) {
28570af302Sopenharmony_ci		return 0;
29570af302Sopenharmony_ci	}
30570af302Sopenharmony_ci
31570af302Sopenharmony_ci	fcntl(fd, F_SETFD, FD_CLOEXEC);
32570af302Sopenharmony_ci	dir->fd = fd;
33570af302Sopenharmony_ci	fdsan_exchange_owner_tag(fd, 0, __get_dir_tag(dir));
34570af302Sopenharmony_ci	return dir;
35570af302Sopenharmony_ci}
36