Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/tests/gen/opendir_test.c
39534 views
1
/*-
2
* Copyright (c) 2025 Klara, Inc.
3
*
4
* SPDX-License-Identifier: BSD-2-Clause
5
*/
6
7
#include <sys/stat.h>
8
9
#include <dirent.h>
10
#include <errno.h>
11
#include <fcntl.h>
12
#include <stdio.h>
13
#include <stdlib.h>
14
15
#include <atf-c.h>
16
17
/*
18
* Create a directory with a single subdirectory.
19
*/
20
static void
21
opendir_prepare(const struct atf_tc *tc)
22
{
23
ATF_REQUIRE_EQ(0, mkdir("dir", 0755));
24
ATF_REQUIRE_EQ(0, mkdir("dir/subdir", 0755));
25
}
26
27
/*
28
* Assuming dirp represents the directory created by opendir_prepare(),
29
* verify that readdir() returns what we expected to see there.
30
*/
31
static void
32
opendir_check(const struct atf_tc *tc, DIR *dirp)
33
{
34
struct dirent *ent;
35
36
ATF_REQUIRE((ent = readdir(dirp)) != NULL);
37
ATF_CHECK_EQ(1, ent->d_namlen);
38
ATF_CHECK_STREQ(".", ent->d_name);
39
ATF_CHECK_EQ(DT_DIR, ent->d_type);
40
ATF_REQUIRE((ent = readdir(dirp)) != NULL);
41
ATF_CHECK_EQ(2, ent->d_namlen);
42
ATF_CHECK_STREQ("..", ent->d_name);
43
ATF_CHECK_EQ(DT_DIR, ent->d_type);
44
ATF_REQUIRE((ent = readdir(dirp)) != NULL);
45
ATF_CHECK_EQ(sizeof("subdir") - 1, ent->d_namlen);
46
ATF_CHECK_STREQ("subdir", ent->d_name);
47
ATF_CHECK_EQ(DT_DIR, ent->d_type);
48
ATF_CHECK(readdir(dirp) == NULL);
49
ATF_CHECK(readdir(dirp) == NULL);
50
}
51
52
ATF_TC(opendir_ok);
53
ATF_TC_HEAD(opendir_ok, tc)
54
{
55
atf_tc_set_md_var(tc, "descr", "Open a directory.");
56
}
57
ATF_TC_BODY(opendir_ok, tc)
58
{
59
DIR *dirp;
60
61
opendir_prepare(tc);
62
ATF_REQUIRE((dirp = opendir("dir")) != NULL);
63
opendir_check(tc, dirp);
64
ATF_CHECK_EQ(0, closedir(dirp));
65
}
66
67
ATF_TC(opendir_fifo);
68
ATF_TC_HEAD(opendir_fifo, tc)
69
{
70
atf_tc_set_md_var(tc, "descr", "Do not hang if given a named pipe.");
71
}
72
ATF_TC_BODY(opendir_fifo, tc)
73
{
74
DIR *dirp;
75
int fd;
76
77
ATF_REQUIRE((fd = mkfifo("fifo", 0644)) >= 0);
78
ATF_REQUIRE_EQ(0, close(fd));
79
ATF_REQUIRE((dirp = opendir("fifo")) == NULL);
80
ATF_CHECK_EQ(ENOTDIR, errno);
81
}
82
83
ATF_TC(fdopendir_ok);
84
ATF_TC_HEAD(fdopendir_ok, tc)
85
{
86
atf_tc_set_md_var(tc, "descr",
87
"Open a directory from a directory descriptor.");
88
}
89
ATF_TC_BODY(fdopendir_ok, tc)
90
{
91
DIR *dirp;
92
int dd;
93
94
opendir_prepare(tc);
95
ATF_REQUIRE((dd = open("dir", O_DIRECTORY | O_RDONLY)) >= 0);
96
ATF_REQUIRE((dirp = fdopendir(dd)) != NULL);
97
opendir_check(tc, dirp);
98
ATF_CHECK_EQ(dd, fdclosedir(dirp));
99
ATF_CHECK_EQ(0, close(dd));
100
}
101
102
ATF_TC(fdopendir_ebadf);
103
ATF_TC_HEAD(fdopendir_ebadf, tc)
104
{
105
atf_tc_set_md_var(tc, "descr",
106
"Open a directory from an invalid descriptor.");
107
}
108
ATF_TC_BODY(fdopendir_ebadf, tc)
109
{
110
DIR *dirp;
111
int dd;
112
113
ATF_REQUIRE_EQ(0, mkdir("dir", 0755));
114
ATF_REQUIRE((dd = open("dir", O_DIRECTORY | O_RDONLY)) >= 0);
115
ATF_CHECK_EQ(0, close(dd));
116
ATF_REQUIRE((dirp = fdopendir(dd)) == NULL);
117
ATF_CHECK_EQ(EBADF, errno);
118
}
119
120
ATF_TC(fdopendir_enotdir);
121
ATF_TC_HEAD(fdopendir_enotdir, tc)
122
{
123
atf_tc_set_md_var(tc, "descr",
124
"Open a directory from a non-directory descriptor.");
125
}
126
ATF_TC_BODY(fdopendir_enotdir, tc)
127
{
128
DIR *dirp;
129
int fd;
130
131
ATF_REQUIRE((fd = open("file", O_CREAT | O_RDWR, 0644)) >= 0);
132
ATF_REQUIRE((dirp = fdopendir(fd)) == NULL);
133
ATF_CHECK_EQ(ENOTDIR, errno);
134
ATF_CHECK_EQ(0, close(fd));
135
}
136
137
ATF_TP_ADD_TCS(tp)
138
{
139
ATF_TP_ADD_TC(tp, opendir_ok);
140
ATF_TP_ADD_TC(tp, fdopendir_ok);
141
ATF_TP_ADD_TC(tp, fdopendir_ebadf);
142
ATF_TP_ADD_TC(tp, fdopendir_enotdir);
143
ATF_TP_ADD_TC(tp, opendir_fifo);
144
return (atf_no_error());
145
}
146
147