Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(997)

Side by Side Diff: runtime/bin/directory_linux.cc

Issue 2480793002: clang-format runtime/bin (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/directory_fuchsia.cc ('k') | runtime/bin/directory_macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_LINUX) 6 #if defined(TARGET_OS_LINUX)
7 7
8 #include "bin/directory.h" 8 #include "bin/directory.h"
9 9
10 #include <dirent.h> // NOLINT 10 #include <dirent.h> // NOLINT
11 #include <errno.h> // NOLINT 11 #include <errno.h> // NOLINT
12 #include <stdlib.h> // NOLINT 12 #include <stdlib.h> // NOLINT
13 #include <string.h> // NOLINT 13 #include <string.h> // NOLINT
14 #include <sys/param.h> // NOLINT 14 #include <sys/param.h> // NOLINT
15 #include <sys/stat.h> // NOLINT 15 #include <sys/stat.h> // NOLINT
16 #include <unistd.h> // NOLINT 16 #include <unistd.h> // NOLINT
17 17
18 #include "bin/dartutils.h" 18 #include "bin/dartutils.h"
19 #include "bin/file.h" 19 #include "bin/file.h"
20 #include "bin/platform.h" 20 #include "bin/platform.h"
21 #include "platform/signal_blocker.h" 21 #include "platform/signal_blocker.h"
22 22
23 namespace dart { 23 namespace dart {
24 namespace bin { 24 namespace bin {
25 25
26 PathBuffer::PathBuffer() : length_(0) { 26 PathBuffer::PathBuffer() : length_(0) {
(...skipping 23 matching lines...) Expand all
50 } 50 }
51 51
52 52
53 const char* PathBuffer::AsScopedString() const { 53 const char* PathBuffer::AsScopedString() const {
54 return DartUtils::ScopedCopyCString(AsString()); 54 return DartUtils::ScopedCopyCString(AsString());
55 } 55 }
56 56
57 57
58 bool PathBuffer::Add(const char* name) { 58 bool PathBuffer::Add(const char* name) {
59 char* data = AsString(); 59 char* data = AsString();
60 int written = snprintf(data + length_, 60 int written = snprintf(data + length_, PATH_MAX - length_, "%s", name);
61 PATH_MAX - length_,
62 "%s",
63 name);
64 data[PATH_MAX] = '\0'; 61 data[PATH_MAX] = '\0';
65 if ((written <= PATH_MAX - length_) && 62 if ((written <= PATH_MAX - length_) && (written >= 0) &&
66 (written >= 0) &&
67 (static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1))) { 63 (static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1))) {
68 length_ += written; 64 length_ += written;
69 return true; 65 return true;
70 } else { 66 } else {
71 errno = ENAMETOOLONG; 67 errno = ENAMETOOLONG;
72 return false; 68 return false;
73 } 69 }
74 } 70 }
75 71
76 72
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 (strcmp(entry->d_name, "..") == 0)) { 126 (strcmp(entry->d_name, "..") == 0)) {
131 return Next(listing); 127 return Next(listing);
132 } 128 }
133 return kListDirectory; 129 return kListDirectory;
134 case DT_REG: 130 case DT_REG:
135 return kListFile; 131 return kListFile;
136 case DT_LNK: 132 case DT_LNK:
137 if (!listing->follow_links()) { 133 if (!listing->follow_links()) {
138 return kListLink; 134 return kListLink;
139 } 135 }
140 // Else fall through to next case. 136 // Else fall through to next case.
141 // Fall through. 137 // Fall through.
142 case DT_UNKNOWN: { 138 case DT_UNKNOWN: {
143 // On some file systems the entry type is not determined by 139 // On some file systems the entry type is not determined by
144 // readdir. For those and for links we use stat to determine 140 // readdir. For those and for links we use stat to determine
145 // the actual entry type. Notice that stat returns the type of 141 // the actual entry type. Notice that stat returns the type of
146 // the file pointed to. 142 // the file pointed to.
147 struct stat64 entry_info; 143 struct stat64 entry_info;
148 int stat_success; 144 int stat_success;
149 stat_success = TEMP_FAILURE_RETRY( 145 stat_success = TEMP_FAILURE_RETRY(
150 lstat64(listing->path_buffer().AsString(), &entry_info)); 146 lstat64(listing->path_buffer().AsString(), &entry_info));
151 if (stat_success == -1) { 147 if (stat_success == -1) {
152 return kListError; 148 return kListError;
153 } 149 }
154 if (listing->follow_links() && S_ISLNK(entry_info.st_mode)) { 150 if (listing->follow_links() && S_ISLNK(entry_info.st_mode)) {
155 // Check to see if we are in a loop created by a symbolic link. 151 // Check to see if we are in a loop created by a symbolic link.
156 LinkList current_link = { entry_info.st_dev, 152 LinkList current_link = {entry_info.st_dev, entry_info.st_ino, link_};
157 entry_info.st_ino,
158 link_ };
159 LinkList* previous = link_; 153 LinkList* previous = link_;
160 while (previous != NULL) { 154 while (previous != NULL) {
161 if ((previous->dev == current_link.dev) && 155 if ((previous->dev == current_link.dev) &&
162 (previous->ino == current_link.ino)) { 156 (previous->ino == current_link.ino)) {
163 // Report the looping link as a link, rather than following it. 157 // Report the looping link as a link, rather than following it.
164 return kListLink; 158 return kListLink;
165 } 159 }
166 previous = previous->next; 160 previous = previous->next;
167 } 161 }
168 stat_success = TEMP_FAILURE_RETRY( 162 stat_success = TEMP_FAILURE_RETRY(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 } 218 }
225 if (parent_ != NULL) { 219 if (parent_ != NULL) {
226 link_ = parent_->link_; 220 link_ = parent_->link_;
227 } 221 }
228 } 222 }
229 223
230 224
231 static bool DeleteRecursively(PathBuffer* path); 225 static bool DeleteRecursively(PathBuffer* path);
232 226
233 227
234 static bool DeleteFile(char* file_name, 228 static bool DeleteFile(char* file_name, PathBuffer* path) {
235 PathBuffer* path) {
236 return path->Add(file_name) && 229 return path->Add(file_name) &&
237 (NO_RETRY_EXPECTED(unlink(path->AsString())) == 0); 230 (NO_RETRY_EXPECTED(unlink(path->AsString())) == 0);
238 } 231 }
239 232
240 233
241 static bool DeleteDir(char* dir_name, 234 static bool DeleteDir(char* dir_name, PathBuffer* path) {
242 PathBuffer* path) {
243 if ((strcmp(dir_name, ".") == 0) || (strcmp(dir_name, "..") == 0)) { 235 if ((strcmp(dir_name, ".") == 0) || (strcmp(dir_name, "..") == 0)) {
244 return true; 236 return true;
245 } 237 }
246 return path->Add(dir_name) && DeleteRecursively(path); 238 return path->Add(dir_name) && DeleteRecursively(path);
247 } 239 }
248 240
249 241
250 static bool DeleteRecursively(PathBuffer* path) { 242 static bool DeleteRecursively(PathBuffer* path) {
251 // Do not recurse into links for deletion. Instead delete the link. 243 // Do not recurse into links for deletion. Instead delete the link.
252 // If it's a file, delete it. 244 // If it's a file, delete it.
(...skipping 13 matching lines...) Expand all
266 DIR* dir_pointer; 258 DIR* dir_pointer;
267 do { 259 do {
268 dir_pointer = opendir(path->AsString()); 260 dir_pointer = opendir(path->AsString());
269 } while ((dir_pointer == NULL) && (errno == EINTR)); 261 } while ((dir_pointer == NULL) && (errno == EINTR));
270 if (dir_pointer == NULL) { 262 if (dir_pointer == NULL) {
271 return false; 263 return false;
272 } 264 }
273 265
274 // Iterate the directory and delete all files and directories. 266 // Iterate the directory and delete all files and directories.
275 int path_length = path->length(); 267 int path_length = path->length();
276 while (true){ 268 while (true) {
277 // In case `readdir()` returns `NULL` we distinguish between end-of-stream a nd error 269 // In case `readdir()` returns `NULL` we distinguish between end-of-stream
278 // by looking if `errno` was updated. 270 // and error by looking if `errno` was updated.
279 errno = 0; 271 errno = 0;
280 // In glibc 2.24+, readdir_r is deprecated. 272 // In glibc 2.24+, readdir_r is deprecated.
281 // According to the man page for readdir: 273 // According to the man page for readdir:
282 // "readdir(3) is not required to be thread-safe. However, in modern 274 // "readdir(3) is not required to be thread-safe. However, in modern
283 // implementations (including the glibc implementation), concurrent calls to 275 // implementations (including the glibc implementation), concurrent calls to
284 // readdir(3) that specify different directory streams are thread-safe. 276 // readdir(3) that specify different directory streams are thread-safe."
285 // Therefore, the use of readdir_r() is generally unnecessary in multithread ed
286 // programs. In cases where multiple threads must read from the same directo ry
287 // stream, using readdir(3) with external synchronization is still preferabl e
288 // to the use of readdir_r(), for the reasons given in the points above."
289 dirent* entry = readdir(dir_pointer); 277 dirent* entry = readdir(dir_pointer);
290 if (entry == NULL) { 278 if (entry == NULL) {
291 // Failed to read next directory entry. 279 // Failed to read next directory entry.
292 if (errno != 0) { 280 if (errno != 0) {
293 break; 281 break;
294 } 282 }
295 // End of directory. 283 // End of directory.
296 return (NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0) && 284 return (NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0) &&
297 (NO_RETRY_EXPECTED(remove(path->AsString())) == 0); 285 (NO_RETRY_EXPECTED(remove(path->AsString())) == 0);
298 } 286 }
299 bool ok = false; 287 bool ok = false;
300 switch (entry->d_type) { 288 switch (entry->d_type) {
301 case DT_DIR: 289 case DT_DIR:
302 ok = DeleteDir(entry->d_name, path); 290 ok = DeleteDir(entry->d_name, path);
303 break; 291 break;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 Directory::ExistsResult Directory::Exists(const char* dir_name) { 338 Directory::ExistsResult Directory::Exists(const char* dir_name) {
351 struct stat64 entry_info; 339 struct stat64 entry_info;
352 int success = TEMP_FAILURE_RETRY(stat64(dir_name, &entry_info)); 340 int success = TEMP_FAILURE_RETRY(stat64(dir_name, &entry_info));
353 if (success == 0) { 341 if (success == 0) {
354 if (S_ISDIR(entry_info.st_mode)) { 342 if (S_ISDIR(entry_info.st_mode)) {
355 return EXISTS; 343 return EXISTS;
356 } else { 344 } else {
357 return DOES_NOT_EXIST; 345 return DOES_NOT_EXIST;
358 } 346 }
359 } else { 347 } else {
360 if ((errno == EACCES) || 348 if ((errno == EACCES) || (errno == EBADF) || (errno == EFAULT) ||
361 (errno == EBADF) || 349 (errno == ENOMEM) || (errno == EOVERFLOW)) {
362 (errno == EFAULT) ||
363 (errno == ENOMEM) ||
364 (errno == EOVERFLOW)) {
365 // Search permissions denied for one of the directories in the 350 // Search permissions denied for one of the directories in the
366 // path or a low level error occured. We do not know if the 351 // path or a low level error occured. We do not know if the
367 // directory exists. 352 // directory exists.
368 return UNKNOWN; 353 return UNKNOWN;
369 } 354 }
370 ASSERT((errno == ELOOP) || 355 ASSERT((errno == ELOOP) || (errno == ENAMETOOLONG) || (errno == ENOENT) ||
371 (errno == ENAMETOOLONG) ||
372 (errno == ENOENT) ||
373 (errno == ENOTDIR)); 356 (errno == ENOTDIR));
374 return DOES_NOT_EXIST; 357 return DOES_NOT_EXIST;
375 } 358 }
376 } 359 }
377 360
378 361
379 char* Directory::CurrentNoScope() { 362 char* Directory::CurrentNoScope() {
380 return getcwd(NULL, 0); 363 return getcwd(NULL, 0);
381 } 364 }
382 365
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 if (exists != EXISTS) { 459 if (exists != EXISTS) {
477 return false; 460 return false;
478 } 461 }
479 return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0); 462 return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0);
480 } 463 }
481 464
482 } // namespace bin 465 } // namespace bin
483 } // namespace dart 466 } // namespace dart
484 467
485 #endif // defined(TARGET_OS_LINUX) 468 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/directory_fuchsia.cc ('k') | runtime/bin/directory_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698