]> sourceware.org Git - glibc.git/blob - io/tst-mkdirat.c
b97bc3ca6d0cdf232cbd67fbb4deff7d5789a1af
[glibc.git] / io / tst-mkdirat.c
1 #include <dirent.h>
2 #include <fcntl.h>
3 #include <stdbool.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/stat.h>
9
10
11 static void prepare (void);
12 #define PREPARE(argc, argv) prepare ()
13
14 static int do_test (void);
15 #define TEST_FUNCTION do_test ()
16
17 #include "../test-skeleton.c"
18
19 static int dir_fd;
20
21 static void
22 prepare (void)
23 {
24 size_t test_dir_len = strlen (test_dir);
25 static const char dir_name[] = "/tst-mkdirat.XXXXXX";
26
27 size_t dirbuflen = test_dir_len + sizeof (dir_name);
28 char *dirbuf = malloc (dirbuflen);
29 if (dirbuf == NULL)
30 {
31 puts ("out of memory");
32 exit (1);
33 }
34
35 snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
36 if (mkdtemp (dirbuf) == NULL)
37 {
38 puts ("cannot create temporary directory");
39 exit (1);
40 }
41
42 add_temp_file (dirbuf);
43
44 dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
45 if (dir_fd == -1)
46 {
47 puts ("cannot open directory");
48 exit (1);
49 }
50 }
51
52
53 static int
54 do_test (void)
55 {
56 /* Find the current umask. */
57 mode_t mask = umask (022);
58 umask (mask);
59
60 /* fdopendir takes over the descriptor, make a copy. */
61 int dupfd = dup (dir_fd);
62 if (dupfd == -1)
63 {
64 puts ("dup failed");
65 return 1;
66 }
67 if (lseek (dupfd, 0, SEEK_SET) != 0)
68 {
69 puts ("1st lseek failed");
70 return 1;
71 }
72
73 /* The directory should be empty safe the . and .. files. */
74 DIR *dir = fdopendir (dupfd);
75 if (dir == NULL)
76 {
77 puts ("fdopendir failed");
78 return 1;
79 }
80 struct dirent64 *d;
81 while ((d = readdir64 (dir)) != NULL)
82 if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
83 {
84 printf ("temp directory contains file \"%s\"\n", d->d_name);
85 return 1;
86 }
87 closedir (dir);
88
89 /* Create a new directory. */
90 int e = mkdirat (dir_fd, "some-dir", 0777);
91 if (e == -1)
92 {
93 if (errno == ENOSYS)
94 {
95 puts ("*at functions not supported");
96 return 0;
97 }
98
99 puts ("directory creation failed");
100 return 1;
101 }
102
103 struct stat64 st1;
104 if (fstatat64 (dir_fd, "some-dir", &st1, 0) != 0)
105 {
106 puts ("fstat64 failed");
107 return 1;
108 }
109 if (!S_ISDIR (st1.st_mode))
110 {
111 puts ("mkdirat did not create a directory");
112 return 1;
113 }
114 if ((st1.st_mode & 01777) != (~mask & 0777))
115 {
116 printf ("mkdirat created directory with wrong mode %o, expected %o\n",
117 (unsigned int) (st1.st_mode & 01777),
118 (unsigned int) (~mask & 0777));
119 return 1;
120 }
121
122 dupfd = dup (dir_fd);
123 if (dupfd == -1)
124 {
125 puts ("dup failed");
126 return 1;
127 }
128 if (lseek (dupfd, 0, SEEK_SET) != 0)
129 {
130 puts ("1st lseek failed");
131 return 1;
132 }
133
134 dir = fdopendir (dupfd);
135 if (dir == NULL)
136 {
137 puts ("2nd fdopendir failed");
138 return 1;
139 }
140 bool has_some_dir = false;
141 while ((d = readdir64 (dir)) != NULL)
142 if (strcmp (d->d_name, "some-dir") == 0)
143 {
144 has_some_dir = true;
145 if (d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
146 {
147 puts ("d_type for some-dir wrong");
148 return 1;
149 }
150 }
151 else if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
152 {
153 printf ("temp directory contains file \"%s\"\n", d->d_name);
154 return 1;
155 }
156 closedir (dir);
157
158 if (!has_some_dir)
159 {
160 puts ("some-dir not in directory list");
161 return 1;
162 }
163
164 if (unlinkat (dir_fd, "some-dir", AT_REMOVEDIR) != 0)
165 {
166 puts ("unlinkat failed");
167 return 1;
168 }
169
170 /* Test again with a different mode. */
171 umask (0);
172 e = mkdirat (dir_fd, "some-dir", 01755);
173 umask (mask);
174 if (e == -1)
175 {
176 puts ("directory creation (different mode) failed");
177 return 1;
178 }
179 if (fstatat64 (dir_fd, "some-dir", &st1, 0) != 0)
180 {
181 puts ("fstat64 (different mode) failed");
182 return 1;
183 }
184 if (!S_ISDIR (st1.st_mode))
185 {
186 puts ("mkdirat (different mode) did not create a directory");
187 return 1;
188 }
189 if ((st1.st_mode & 01777) != 01755)
190 {
191 printf ("mkdirat (different mode) created directory with wrong mode %o\n",
192 (unsigned int) (st1.st_mode & 01777));
193 return 1;
194 }
195 if (unlinkat (dir_fd, "some-dir", AT_REMOVEDIR) != 0)
196 {
197 puts ("unlinkat (different mode) failed");
198 return 1;
199 }
200
201 close (dir_fd);
202
203 return 0;
204 }
This page took 0.052413 seconds and 6 git commands to generate.