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

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

Issue 165723007: Move signal_blocker to platform and use it by default in TEMP_FAILURE_RETRY. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tiny fix. Created 6 years, 9 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/file_linux.cc ('k') | runtime/bin/file_system_watcher_android.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_MACOS) 6 #if defined(TARGET_OS_MACOS)
7 7
8 #include "bin/file.h" 8 #include "bin/file.h"
9 9
10 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
11 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
12 #include <copyfile.h> // NOLINT 12 #include <copyfile.h> // NOLINT
13 #include <sys/stat.h> // NOLINT 13 #include <sys/stat.h> // NOLINT
14 #include <unistd.h> // NOLINT 14 #include <unistd.h> // NOLINT
15 #include <libgen.h> // NOLINT 15 #include <libgen.h> // NOLINT
16 #include <limits.h> // NOLINT 16 #include <limits.h> // NOLINT
17 17
18 #include "bin/builtin.h" 18 #include "bin/builtin.h"
19 #include "bin/fdutils.h" 19 #include "bin/fdutils.h"
20 #include "bin/log.h" 20 #include "bin/log.h"
21 #include "bin/signal_blocker.h" 21
22 #include "platform/signal_blocker.h"
22 23
23 namespace dart { 24 namespace dart {
24 namespace bin { 25 namespace bin {
25 26
26 class FileHandle { 27 class FileHandle {
27 public: 28 public:
28 explicit FileHandle(int fd) : fd_(fd) { } 29 explicit FileHandle(int fd) : fd_(fd) { }
29 ~FileHandle() { } 30 ~FileHandle() { }
30 int fd() const { return fd_; } 31 int fd() const { return fd_; }
31 void set_fd(int fd) { fd_ = fd; } 32 void set_fd(int fd) { fd_ = fd; }
(...skipping 13 matching lines...) Expand all
45 46
46 void File::Close() { 47 void File::Close() {
47 ASSERT(handle_->fd() >= 0); 48 ASSERT(handle_->fd() >= 0);
48 if (handle_->fd() == STDOUT_FILENO) { 49 if (handle_->fd() == STDOUT_FILENO) {
49 // If stdout, redirect fd to /dev/null. 50 // If stdout, redirect fd to /dev/null.
50 intptr_t null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY)); 51 intptr_t null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
51 ASSERT(null_fd >= 0); 52 ASSERT(null_fd >= 0);
52 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd())); 53 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
53 VOID_TEMP_FAILURE_RETRY(close(null_fd)); 54 VOID_TEMP_FAILURE_RETRY(close(null_fd));
54 } else { 55 } else {
55 intptr_t err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd())); 56 intptr_t err = TEMP_FAILURE_RETRY(close(handle_->fd()));
56 if (err != 0) { 57 if (err != 0) {
57 const int kBufferSize = 1024; 58 const int kBufferSize = 1024;
58 char error_message[kBufferSize]; 59 char error_message[kBufferSize];
59 strerror_r(errno, error_message, kBufferSize); 60 strerror_r(errno, error_message, kBufferSize);
60 Log::PrintErr("%s\n", error_message); 61 Log::PrintErr("%s\n", error_message);
61 } 62 }
62 } 63 }
63 handle_->set_fd(kClosedFd); 64 handle_->set_fd(kClosedFd);
64 } 65 }
65 66
66 67
67 bool File::IsClosed() { 68 bool File::IsClosed() {
68 return handle_->fd() == kClosedFd; 69 return handle_->fd() == kClosedFd;
69 } 70 }
70 71
71 72
72 int64_t File::Read(void* buffer, int64_t num_bytes) { 73 int64_t File::Read(void* buffer, int64_t num_bytes) {
73 ASSERT(handle_->fd() >= 0); 74 ASSERT(handle_->fd() >= 0);
74 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(read(handle_->fd(), buffer, 75 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes));
75 num_bytes));
76 } 76 }
77 77
78 78
79 int64_t File::Write(const void* buffer, int64_t num_bytes) { 79 int64_t File::Write(const void* buffer, int64_t num_bytes) {
80 ASSERT(handle_->fd() >= 0); 80 ASSERT(handle_->fd() >= 0);
81 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(write(handle_->fd(), buffer, 81 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
82 num_bytes));
83 } 82 }
84 83
85 84
86 int64_t File::Position() { 85 int64_t File::Position() {
87 ASSERT(handle_->fd() >= 0); 86 ASSERT(handle_->fd() >= 0);
88 return lseek(handle_->fd(), 0, SEEK_CUR); 87 return lseek(handle_->fd(), 0, SEEK_CUR);
89 } 88 }
90 89
91 90
92 bool File::SetPosition(int64_t position) { 91 bool File::SetPosition(int64_t position) {
93 ASSERT(handle_->fd() >= 0); 92 ASSERT(handle_->fd() >= 0);
94 return lseek(handle_->fd(), position, SEEK_SET) >= 0; 93 return lseek(handle_->fd(), position, SEEK_SET) >= 0;
95 } 94 }
96 95
97 96
98 bool File::Truncate(int64_t length) { 97 bool File::Truncate(int64_t length) {
99 ASSERT(handle_->fd() >= 0); 98 ASSERT(handle_->fd() >= 0);
100 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 99 return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length)) != -1;
101 ftruncate(handle_->fd(), length) != -1);
102 } 100 }
103 101
104 102
105 bool File::Flush() { 103 bool File::Flush() {
106 ASSERT(handle_->fd() >= 0); 104 ASSERT(handle_->fd() >= 0);
107 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fsync(handle_->fd()) != -1); 105 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1;
108 } 106 }
109 107
110 108
111 int64_t File::Length() { 109 int64_t File::Length() {
112 ASSERT(handle_->fd() >= 0); 110 ASSERT(handle_->fd() >= 0);
113 struct stat st; 111 struct stat st;
114 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fstat(handle_->fd(), &st)) == 0) { 112 if (NO_RETRY_EXPECTED(fstat(handle_->fd(), &st)) == 0) {
115 return st.st_size; 113 return st.st_size;
116 } 114 }
117 return -1; 115 return -1;
118 } 116 }
119 117
120 118
121 File* File::Open(const char* name, FileOpenMode mode) { 119 File* File::Open(const char* name, FileOpenMode mode) {
122 // Report errors for non-regular files. 120 // Report errors for non-regular files.
123 struct stat st; 121 struct stat st;
124 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) { 122 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
125 // Only accept regular files and character devices. 123 // Only accept regular files and character devices.
126 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { 124 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
127 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; 125 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
128 return NULL; 126 return NULL;
129 } 127 }
130 } 128 }
131 int flags = O_RDONLY; 129 int flags = O_RDONLY;
132 if ((mode & kWrite) != 0) { 130 if ((mode & kWrite) != 0) {
133 flags = (O_RDWR | O_CREAT); 131 flags = (O_RDWR | O_CREAT);
134 } 132 }
135 if ((mode & kTruncate) != 0) { 133 if ((mode & kTruncate) != 0) {
136 flags = flags | O_TRUNC; 134 flags = flags | O_TRUNC;
137 } 135 }
138 int fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(open(name, flags, 0666)); 136 int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666));
139 if (fd < 0) { 137 if (fd < 0) {
140 return NULL; 138 return NULL;
141 } 139 }
142 FDUtils::SetCloseOnExec(fd); 140 FDUtils::SetCloseOnExec(fd);
143 if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) { 141 if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
144 int64_t position = lseek(fd, 0, SEEK_END); 142 int64_t position = lseek(fd, 0, SEEK_END);
145 if (position < 0) { 143 if (position < 0) {
146 return NULL; 144 return NULL;
147 } 145 }
148 } 146 }
149 return new File(new FileHandle(fd)); 147 return new File(new FileHandle(fd));
150 } 148 }
151 149
152 150
153 File* File::OpenStdio(int fd) { 151 File* File::OpenStdio(int fd) {
154 if (fd < 0 || 2 < fd) return NULL; 152 if (fd < 0 || 2 < fd) return NULL;
155 return new File(new FileHandle(fd)); 153 return new File(new FileHandle(fd));
156 } 154 }
157 155
158 156
159 bool File::Exists(const char* name) { 157 bool File::Exists(const char* name) {
160 struct stat st; 158 struct stat st;
161 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) { 159 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
162 return S_ISREG(st.st_mode); 160 return S_ISREG(st.st_mode);
163 } else { 161 } else {
164 return false; 162 return false;
165 } 163 }
166 } 164 }
167 165
168 166
169 bool File::Create(const char* name) { 167 bool File::Create(const char* name) {
170 int fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(open(name, O_RDONLY | O_CREAT, 168 int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CREAT, 0666));
171 0666));
172 if (fd < 0) { 169 if (fd < 0) {
173 return false; 170 return false;
174 } 171 }
175 return (close(fd) == 0); 172 return (close(fd) == 0);
176 } 173 }
177 174
178 175
179 bool File::CreateLink(const char* name, const char* target) { 176 bool File::CreateLink(const char* name, const char* target) {
180 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(symlink(target, name)); 177 int status = NO_RETRY_EXPECTED(symlink(target, name));
181 return (status == 0); 178 return (status == 0);
182 } 179 }
183 180
184 181
185 bool File::Delete(const char* name) { 182 bool File::Delete(const char* name) {
186 File::Type type = File::GetType(name, true); 183 File::Type type = File::GetType(name, true);
187 if (type == kIsFile) { 184 if (type == kIsFile) {
188 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(unlink(name)) == 0; 185 return NO_RETRY_EXPECTED(unlink(name)) == 0;
189 } else if (type == kIsDirectory) { 186 } else if (type == kIsDirectory) {
190 errno = EISDIR; 187 errno = EISDIR;
191 } else { 188 } else {
192 errno = ENOENT; 189 errno = ENOENT;
193 } 190 }
194 return false; 191 return false;
195 } 192 }
196 193
197 194
198 bool File::DeleteLink(const char* name) { 195 bool File::DeleteLink(const char* name) {
199 File::Type type = File::GetType(name, false); 196 File::Type type = File::GetType(name, false);
200 if (type == kIsLink) { 197 if (type == kIsLink) {
201 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(unlink(name)) == 0; 198 return NO_RETRY_EXPECTED(unlink(name)) == 0;
202 } 199 }
203 errno = EINVAL; 200 errno = EINVAL;
204 return false; 201 return false;
205 } 202 }
206 203
207 204
208 bool File::Rename(const char* old_path, const char* new_path) { 205 bool File::Rename(const char* old_path, const char* new_path) {
209 File::Type type = File::GetType(old_path, true); 206 File::Type type = File::GetType(old_path, true);
210 if (type == kIsFile) { 207 if (type == kIsFile) {
211 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(rename(old_path, new_path)) == 0; 208 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
212 } else if (type == kIsDirectory) { 209 } else if (type == kIsDirectory) {
213 errno = EISDIR; 210 errno = EISDIR;
214 } else { 211 } else {
215 errno = ENOENT; 212 errno = ENOENT;
216 } 213 }
217 return false; 214 return false;
218 } 215 }
219 216
220 217
221 bool File::RenameLink(const char* old_path, const char* new_path) { 218 bool File::RenameLink(const char* old_path, const char* new_path) {
222 File::Type type = File::GetType(old_path, false); 219 File::Type type = File::GetType(old_path, false);
223 if (type == kIsLink) { 220 if (type == kIsLink) {
224 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(rename(old_path, new_path)) == 0; 221 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
225 } else if (type == kIsDirectory) { 222 } else if (type == kIsDirectory) {
226 errno = EISDIR; 223 errno = EISDIR;
227 } else { 224 } else {
228 errno = EINVAL; 225 errno = EINVAL;
229 } 226 }
230 return false; 227 return false;
231 } 228 }
232 229
233 230
234 bool File::Copy(const char* old_path, const char* new_path) { 231 bool File::Copy(const char* old_path, const char* new_path) {
235 File::Type type = File::GetType(old_path, true); 232 File::Type type = File::GetType(old_path, true);
236 if (type == kIsFile) { 233 if (type == kIsFile) {
237 return copyfile(old_path, new_path, NULL, COPYFILE_ALL) == 0; 234 return copyfile(old_path, new_path, NULL, COPYFILE_ALL) == 0;
238 } else if (type == kIsDirectory) { 235 } else if (type == kIsDirectory) {
239 errno = EISDIR; 236 errno = EISDIR;
240 } else { 237 } else {
241 errno = ENOENT; 238 errno = ENOENT;
242 } 239 }
243 return false; 240 return false;
244 } 241 }
245 242
246 243
247 int64_t File::LengthFromPath(const char* name) { 244 int64_t File::LengthFromPath(const char* name) {
248 struct stat st; 245 struct stat st;
249 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) { 246 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
250 return st.st_size; 247 return st.st_size;
251 } 248 }
252 return -1; 249 return -1;
253 } 250 }
254 251
255 252
256 void File::Stat(const char* name, int64_t* data) { 253 void File::Stat(const char* name, int64_t* data) {
257 struct stat st; 254 struct stat st;
258 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) { 255 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
259 if (S_ISREG(st.st_mode)) { 256 if (S_ISREG(st.st_mode)) {
260 data[kType] = kIsFile; 257 data[kType] = kIsFile;
261 } else if (S_ISDIR(st.st_mode)) { 258 } else if (S_ISDIR(st.st_mode)) {
262 data[kType] = kIsDirectory; 259 data[kType] = kIsDirectory;
263 } else if (S_ISLNK(st.st_mode)) { 260 } else if (S_ISLNK(st.st_mode)) {
264 data[kType] = kIsLink; 261 data[kType] = kIsLink;
265 } else { 262 } else {
266 data[kType] = kDoesNotExist; 263 data[kType] = kDoesNotExist;
267 } 264 }
268 data[kCreatedTime] = st.st_ctime; 265 data[kCreatedTime] = st.st_ctime;
269 data[kModifiedTime] = st.st_mtime; 266 data[kModifiedTime] = st.st_mtime;
270 data[kAccessedTime] = st.st_atime; 267 data[kAccessedTime] = st.st_atime;
271 data[kMode] = st.st_mode; 268 data[kMode] = st.st_mode;
272 data[kSize] = st.st_size; 269 data[kSize] = st.st_size;
273 } else { 270 } else {
274 data[kType] = kDoesNotExist; 271 data[kType] = kDoesNotExist;
275 } 272 }
276 } 273 }
277 274
278 275
279 time_t File::LastModified(const char* name) { 276 time_t File::LastModified(const char* name) {
280 struct stat st; 277 struct stat st;
281 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(name, &st)) == 0) { 278 if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
282 return st.st_mtime; 279 return st.st_mtime;
283 } 280 }
284 return -1; 281 return -1;
285 } 282 }
286 283
287 284
288 char* File::LinkTarget(const char* pathname) { 285 char* File::LinkTarget(const char* pathname) {
289 struct stat link_stats; 286 struct stat link_stats;
290 if (lstat(pathname, &link_stats) != 0) return NULL; 287 if (lstat(pathname, &link_stats) != 0) return NULL;
291 if (!S_ISLNK(link_stats.st_mode)) { 288 if (!S_ISLNK(link_stats.st_mode)) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 if (S_ISSOCK(buf.st_mode)) return kSocket; 349 if (S_ISSOCK(buf.st_mode)) return kSocket;
353 if (S_ISREG(buf.st_mode)) return kFile; 350 if (S_ISREG(buf.st_mode)) return kFile;
354 return kOther; 351 return kOther;
355 } 352 }
356 353
357 354
358 File::Type File::GetType(const char* pathname, bool follow_links) { 355 File::Type File::GetType(const char* pathname, bool follow_links) {
359 struct stat entry_info; 356 struct stat entry_info;
360 int stat_success; 357 int stat_success;
361 if (follow_links) { 358 if (follow_links) {
362 stat_success = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat(pathname, 359 stat_success = NO_RETRY_EXPECTED(stat(pathname, &entry_info));
363 &entry_info));
364 } else { 360 } else {
365 stat_success = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(lstat(pathname, 361 stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
366 &entry_info));
367 } 362 }
368 if (stat_success == -1) return File::kDoesNotExist; 363 if (stat_success == -1) return File::kDoesNotExist;
369 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory; 364 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
370 if (S_ISREG(entry_info.st_mode)) return File::kIsFile; 365 if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
371 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink; 366 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
372 return File::kDoesNotExist; 367 return File::kDoesNotExist;
373 } 368 }
374 369
375 370
376 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { 371 File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
377 struct stat file_1_info; 372 struct stat file_1_info;
378 struct stat file_2_info; 373 struct stat file_2_info;
379 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(lstat(file_1, &file_1_info)) == -1 || 374 if (NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1 ||
380 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(lstat(file_2, &file_2_info)) == -1) { 375 NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1) {
381 return File::kError; 376 return File::kError;
382 } 377 }
383 return (file_1_info.st_ino == file_2_info.st_ino && 378 return (file_1_info.st_ino == file_2_info.st_ino &&
384 file_1_info.st_dev == file_2_info.st_dev) ? 379 file_1_info.st_dev == file_2_info.st_dev) ?
385 File::kIdentical : 380 File::kIdentical :
386 File::kDifferent; 381 File::kDifferent;
387 } 382 }
388 383
389 } // namespace bin 384 } // namespace bin
390 } // namespace dart 385 } // namespace dart
391 386
392 #endif // defined(TARGET_OS_MACOS) 387 #endif // defined(TARGET_OS_MACOS)
OLDNEW
« no previous file with comments | « runtime/bin/file_linux.cc ('k') | runtime/bin/file_system_watcher_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698