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

Side by Side Diff: runtime/bin/file_linux.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_android.cc ('k') | runtime/bin/file_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/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 <sys/stat.h> // NOLINT 12 #include <sys/stat.h> // NOLINT
13 #include <sys/types.h> // NOLINT 13 #include <sys/types.h> // NOLINT
14 #include <sys/sendfile.h> // NOLINT 14 #include <sys/sendfile.h> // NOLINT
15 #include <unistd.h> // NOLINT 15 #include <unistd.h> // NOLINT
16 #include <libgen.h> // NOLINT 16 #include <libgen.h> // NOLINT
17 17
18 #include "platform/signal_blocker.h"
18 #include "bin/builtin.h" 19 #include "bin/builtin.h"
19 #include "bin/log.h" 20 #include "bin/log.h"
20 #include "bin/signal_blocker.h"
21 21
22 22
23 namespace dart { 23 namespace dart {
24 namespace bin { 24 namespace bin {
25 25
26 class FileHandle { 26 class FileHandle {
27 public: 27 public:
28 explicit FileHandle(int fd) : fd_(fd) { } 28 explicit FileHandle(int fd) : fd_(fd) { }
29 ~FileHandle() { } 29 ~FileHandle() { }
30 int fd() const { return fd_; } 30 int fd() const { return fd_; }
(...skipping 14 matching lines...) Expand all
45 45
46 void File::Close() { 46 void File::Close() {
47 ASSERT(handle_->fd() >= 0); 47 ASSERT(handle_->fd() >= 0);
48 if (handle_->fd() == STDOUT_FILENO) { 48 if (handle_->fd() == STDOUT_FILENO) {
49 // If stdout, redirect fd to /dev/null. 49 // If stdout, redirect fd to /dev/null.
50 int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY)); 50 int null_fd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
51 ASSERT(null_fd >= 0); 51 ASSERT(null_fd >= 0);
52 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd())); 52 VOID_TEMP_FAILURE_RETRY(dup2(null_fd, handle_->fd()));
53 VOID_TEMP_FAILURE_RETRY(close(null_fd)); 53 VOID_TEMP_FAILURE_RETRY(close(null_fd));
54 } else { 54 } else {
55 int err = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(handle_->fd())); 55 int err = TEMP_FAILURE_RETRY(close(handle_->fd()));
56 if (err != 0) { 56 if (err != 0) {
57 const int kBufferSize = 1024; 57 const int kBufferSize = 1024;
58 char error_buf[kBufferSize]; 58 char error_buf[kBufferSize];
59 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize)); 59 Log::PrintErr("%s\n", strerror_r(errno, error_buf, kBufferSize));
60 } 60 }
61 } 61 }
62 handle_->set_fd(kClosedFd); 62 handle_->set_fd(kClosedFd);
63 } 63 }
64 64
65 65
66 bool File::IsClosed() { 66 bool File::IsClosed() {
67 return handle_->fd() == kClosedFd; 67 return handle_->fd() == kClosedFd;
68 } 68 }
69 69
70 70
71 int64_t File::Read(void* buffer, int64_t num_bytes) { 71 int64_t File::Read(void* buffer, int64_t num_bytes) {
72 ASSERT(handle_->fd() >= 0); 72 ASSERT(handle_->fd() >= 0);
73 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(read(handle_->fd(), buffer, 73 return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes));
74 num_bytes));
75 } 74 }
76 75
77 76
78 int64_t File::Write(const void* buffer, int64_t num_bytes) { 77 int64_t File::Write(const void* buffer, int64_t num_bytes) {
79 ASSERT(handle_->fd() >= 0); 78 ASSERT(handle_->fd() >= 0);
80 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(write(handle_->fd(), buffer, 79 return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
81 num_bytes));
82 } 80 }
83 81
84 82
85 int64_t File::Position() { 83 int64_t File::Position() {
86 ASSERT(handle_->fd() >= 0); 84 ASSERT(handle_->fd() >= 0);
87 return lseek64(handle_->fd(), 0, SEEK_CUR); 85 return NO_RETRY_EXPECTED(lseek64(handle_->fd(), 0, SEEK_CUR));
88 } 86 }
89 87
90 88
91 bool File::SetPosition(int64_t position) { 89 bool File::SetPosition(int64_t position) {
92 ASSERT(handle_->fd() >= 0); 90 ASSERT(handle_->fd() >= 0);
93 return lseek64(handle_->fd(), position, SEEK_SET) >= 0; 91 return NO_RETRY_EXPECTED(lseek64(handle_->fd(), position, SEEK_SET)) >= 0;
94 } 92 }
95 93
96 94
97 bool File::Truncate(int64_t length) { 95 bool File::Truncate(int64_t length) {
98 ASSERT(handle_->fd() >= 0); 96 ASSERT(handle_->fd() >= 0);
99 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 97 return TEMP_FAILURE_RETRY(ftruncate64(handle_->fd(), length) != -1);
100 ftruncate64(handle_->fd(), length) != -1);
101 } 98 }
102 99
103 100
104 bool File::Flush() { 101 bool File::Flush() {
105 ASSERT(handle_->fd() >= 0); 102 ASSERT(handle_->fd() >= 0);
106 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fsync(handle_->fd()) != -1); 103 return NO_RETRY_EXPECTED(fsync(handle_->fd())) != -1;
107 } 104 }
108 105
109 106
110 int64_t File::Length() { 107 int64_t File::Length() {
111 ASSERT(handle_->fd() >= 0); 108 ASSERT(handle_->fd() >= 0);
112 struct stat64 st; 109 struct stat64 st;
113 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(fstat64(handle_->fd(), &st)) == 0) { 110 if (NO_RETRY_EXPECTED(fstat64(handle_->fd(), &st)) == 0) {
114 return st.st_size; 111 return st.st_size;
115 } 112 }
116 return -1; 113 return -1;
117 } 114 }
118 115
119 116
120 File* File::Open(const char* name, FileOpenMode mode) { 117 File* File::Open(const char* name, FileOpenMode mode) {
121 // Report errors for non-regular files. 118 // Report errors for non-regular files.
122 struct stat64 st; 119 struct stat64 st;
123 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(name, &st)) == 0) { 120 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) {
124 // Only accept regular files and character devices. 121 // Only accept regular files and character devices.
125 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { 122 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
126 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT; 123 errno = (S_ISDIR(st.st_mode)) ? EISDIR : ENOENT;
127 return NULL; 124 return NULL;
128 } 125 }
129 } 126 }
130 int flags = O_RDONLY; 127 int flags = O_RDONLY;
131 if ((mode & kWrite) != 0) { 128 if ((mode & kWrite) != 0) {
132 flags = (O_RDWR | O_CREAT); 129 flags = (O_RDWR | O_CREAT);
133 } 130 }
134 if ((mode & kTruncate) != 0) { 131 if ((mode & kTruncate) != 0) {
135 flags = flags | O_TRUNC; 132 flags = flags | O_TRUNC;
136 } 133 }
137 flags |= O_CLOEXEC; 134 flags |= O_CLOEXEC;
138 int fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(open64(name, flags, 0666)); 135 int fd = TEMP_FAILURE_RETRY(open64(name, flags, 0666));
139 if (fd < 0) { 136 if (fd < 0) {
140 return NULL; 137 return NULL;
141 } 138 }
142 if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) { 139 if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
143 int64_t position = lseek64(fd, 0, SEEK_END); 140 int64_t position = NO_RETRY_EXPECTED(lseek64(fd, 0, SEEK_END));
144 if (position < 0) { 141 if (position < 0) {
145 return NULL; 142 return NULL;
146 } 143 }
147 } 144 }
148 return new File(new FileHandle(fd)); 145 return new File(new FileHandle(fd));
149 } 146 }
150 147
151 148
152 File* File::OpenStdio(int fd) { 149 File* File::OpenStdio(int fd) {
153 if (fd < 0 || 2 < fd) return NULL; 150 if (fd < 0 || 2 < fd) return NULL;
154 return new File(new FileHandle(fd)); 151 return new File(new FileHandle(fd));
155 } 152 }
156 153
157 154
158 bool File::Exists(const char* name) { 155 bool File::Exists(const char* name) {
159 struct stat64 st; 156 struct stat64 st;
160 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(name, &st)) == 0) { 157 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) {
161 return S_ISREG(st.st_mode); 158 return S_ISREG(st.st_mode);
162 } else { 159 } else {
163 return false; 160 return false;
164 } 161 }
165 } 162 }
166 163
167 164
168 bool File::Create(const char* name) { 165 bool File::Create(const char* name) {
169 int fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 166 int fd = TEMP_FAILURE_RETRY(
170 open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666)); 167 open64(name, O_RDONLY | O_CREAT | O_CLOEXEC, 0666));
171 if (fd < 0) { 168 if (fd < 0) {
172 return false; 169 return false;
173 } 170 }
174 return (close(fd) == 0); 171 return (TEMP_FAILURE_RETRY(close(fd)) == 0);
175 } 172 }
176 173
177 174
178 bool File::CreateLink(const char* name, const char* target) { 175 bool File::CreateLink(const char* name, const char* target) {
179 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(symlink(target, name)); 176 return NO_RETRY_EXPECTED(symlink(target, name)) == 0;
180 return (status == 0);
181 } 177 }
182 178
183 179
184 bool File::Delete(const char* name) { 180 bool File::Delete(const char* name) {
185 File::Type type = File::GetType(name, true); 181 File::Type type = File::GetType(name, true);
186 if (type == kIsFile) { 182 if (type == kIsFile) {
187 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(unlink(name)) == 0; 183 return NO_RETRY_EXPECTED(unlink(name)) == 0;
188 } else if (type == kIsDirectory) { 184 } else if (type == kIsDirectory) {
189 errno = EISDIR; 185 errno = EISDIR;
190 } else { 186 } else {
191 errno = ENOENT; 187 errno = ENOENT;
192 } 188 }
193 return false; 189 return false;
194 } 190 }
195 191
196 192
197 bool File::DeleteLink(const char* name) { 193 bool File::DeleteLink(const char* name) {
198 File::Type type = File::GetType(name, false); 194 File::Type type = File::GetType(name, false);
199 if (type == kIsLink) { 195 if (type == kIsLink) {
200 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(unlink(name)) == 0; 196 return NO_RETRY_EXPECTED(unlink(name)) == 0;
201 } 197 }
202 errno = EINVAL; 198 errno = EINVAL;
203 return false; 199 return false;
204 } 200 }
205 201
206 202
207 bool File::Rename(const char* old_path, const char* new_path) { 203 bool File::Rename(const char* old_path, const char* new_path) {
208 File::Type type = File::GetType(old_path, true); 204 File::Type type = File::GetType(old_path, true);
209 if (type == kIsFile) { 205 if (type == kIsFile) {
210 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(rename(old_path, new_path)) == 0; 206 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
211 } else if (type == kIsDirectory) { 207 } else if (type == kIsDirectory) {
212 errno = EISDIR; 208 errno = EISDIR;
213 } else { 209 } else {
214 errno = ENOENT; 210 errno = ENOENT;
215 } 211 }
216 return false; 212 return false;
217 } 213 }
218 214
219 215
220 bool File::RenameLink(const char* old_path, const char* new_path) { 216 bool File::RenameLink(const char* old_path, const char* new_path) {
221 File::Type type = File::GetType(old_path, false); 217 File::Type type = File::GetType(old_path, false);
222 if (type == kIsLink) { 218 if (type == kIsLink) {
223 return TEMP_FAILURE_RETRY_BLOCK_SIGNALS(rename(old_path, new_path)) == 0; 219 return NO_RETRY_EXPECTED(rename(old_path, new_path)) == 0;
224 } else if (type == kIsDirectory) { 220 } else if (type == kIsDirectory) {
225 errno = EISDIR; 221 errno = EISDIR;
226 } else { 222 } else {
227 errno = EINVAL; 223 errno = EINVAL;
228 } 224 }
229 return false; 225 return false;
230 } 226 }
231 227
232 228
233 bool File::Copy(const char* old_path, const char* new_path) { 229 bool File::Copy(const char* old_path, const char* new_path) {
234 File::Type type = File::GetType(old_path, true); 230 File::Type type = File::GetType(old_path, true);
235 if (type == kIsFile) { 231 if (type == kIsFile) {
236 struct stat64 st; 232 struct stat64 st;
237 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(old_path, &st)) != 0) { 233 if (NO_RETRY_EXPECTED(stat64(old_path, &st)) != 0) {
238 return false; 234 return false;
239 } 235 }
240 int old_fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(open64(old_path, 236 int old_fd = TEMP_FAILURE_RETRY(open64(old_path, O_RDONLY | O_CLOEXEC));
241 O_RDONLY | O_CLOEXEC));
242 if (old_fd < 0) { 237 if (old_fd < 0) {
243 return false; 238 return false;
244 } 239 }
245 int new_fd = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 240 int new_fd = TEMP_FAILURE_RETRY(
246 open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode)); 241 open64(new_path, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, st.st_mode));
247 if (new_fd < 0) { 242 if (new_fd < 0) {
248 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(old_fd)); 243 VOID_TEMP_FAILURE_RETRY(close(old_fd));
249 return false; 244 return false;
250 } 245 }
251 int64_t offset = 0; 246 int64_t offset = 0;
252 intptr_t result = 1; 247 intptr_t result = 1;
253 while (result > 0) { 248 while (result > 0) {
254 // Loop to ensure we copy everything, and not only up to 2GB. 249 // Loop to ensure we copy everything, and not only up to 2GB.
255 result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 250 result = NO_RETRY_EXPECTED(
256 sendfile64(new_fd, old_fd, &offset, kMaxUint32)); 251 sendfile64(new_fd, old_fd, &offset, kMaxUint32));
257 } 252 }
258 // From sendfile man pages: 253 // From sendfile man pages:
259 // Applications may wish to fall back to read(2)/write(2) in the case 254 // Applications may wish to fall back to read(2)/write(2) in the case
260 // where sendfile() fails with EINVAL or ENOSYS. 255 // where sendfile() fails with EINVAL or ENOSYS.
261 if (result < 0 && (errno == EINVAL || errno == ENOSYS)) { 256 if (result < 0 && (errno == EINVAL || errno == ENOSYS)) {
262 const intptr_t kBufferSize = 8 * KB; 257 const intptr_t kBufferSize = 8 * KB;
263 uint8_t buffer[kBufferSize]; 258 uint8_t buffer[kBufferSize];
264 while ((result = TEMP_FAILURE_RETRY_BLOCK_SIGNALS( 259 while ((result = TEMP_FAILURE_RETRY(
265 read(old_fd, buffer, kBufferSize))) > 0) { 260 read(old_fd, buffer, kBufferSize))) > 0) {
266 int wrote = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(write(new_fd, buffer, 261 int wrote = TEMP_FAILURE_RETRY(write(new_fd, buffer, result));
267 result));
268 if (wrote != result) { 262 if (wrote != result) {
269 result = -1; 263 result = -1;
270 break; 264 break;
271 } 265 }
272 } 266 }
273 } 267 }
274 if (result < 0) { 268 if (result < 0) {
275 int e = errno; 269 int e = errno;
276 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(old_fd)); 270 VOID_TEMP_FAILURE_RETRY(close(old_fd));
277 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(new_fd)); 271 VOID_TEMP_FAILURE_RETRY(close(new_fd));
278 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(unlink(new_path)); 272 VOID_NO_RETRY_EXPECTED(unlink(new_path));
279 errno = e; 273 errno = e;
280 return false; 274 return false;
281 } 275 }
282 return true; 276 return true;
283 } else if (type == kIsDirectory) { 277 } else if (type == kIsDirectory) {
284 errno = EISDIR; 278 errno = EISDIR;
285 } else { 279 } else {
286 errno = ENOENT; 280 errno = ENOENT;
287 } 281 }
288 return false; 282 return false;
289 } 283 }
290 284
291 285
292 int64_t File::LengthFromPath(const char* name) { 286 int64_t File::LengthFromPath(const char* name) {
293 struct stat64 st; 287 struct stat64 st;
294 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(name, &st)) == 0) { 288 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) {
295 return st.st_size; 289 return st.st_size;
296 } 290 }
297 return -1; 291 return -1;
298 } 292 }
299 293
300 294
301 void File::Stat(const char* name, int64_t* data) { 295 void File::Stat(const char* name, int64_t* data) {
302 struct stat64 st; 296 struct stat64 st;
303 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(name, &st)) == 0) { 297 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) {
304 if (S_ISREG(st.st_mode)) { 298 if (S_ISREG(st.st_mode)) {
305 data[kType] = kIsFile; 299 data[kType] = kIsFile;
306 } else if (S_ISDIR(st.st_mode)) { 300 } else if (S_ISDIR(st.st_mode)) {
307 data[kType] = kIsDirectory; 301 data[kType] = kIsDirectory;
308 } else if (S_ISLNK(st.st_mode)) { 302 } else if (S_ISLNK(st.st_mode)) {
309 data[kType] = kIsLink; 303 data[kType] = kIsLink;
310 } else { 304 } else {
311 data[kType] = kDoesNotExist; 305 data[kType] = kDoesNotExist;
312 } 306 }
313 data[kCreatedTime] = st.st_ctime; 307 data[kCreatedTime] = st.st_ctime;
314 data[kModifiedTime] = st.st_mtime; 308 data[kModifiedTime] = st.st_mtime;
315 data[kAccessedTime] = st.st_atime; 309 data[kAccessedTime] = st.st_atime;
316 data[kMode] = st.st_mode; 310 data[kMode] = st.st_mode;
317 data[kSize] = st.st_size; 311 data[kSize] = st.st_size;
318 } else { 312 } else {
319 data[kType] = kDoesNotExist; 313 data[kType] = kDoesNotExist;
320 } 314 }
321 } 315 }
322 316
323 317
324 time_t File::LastModified(const char* name) { 318 time_t File::LastModified(const char* name) {
325 struct stat64 st; 319 struct stat64 st;
326 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(name, &st)) == 0) { 320 if (NO_RETRY_EXPECTED(stat64(name, &st)) == 0) {
327 return st.st_mtime; 321 return st.st_mtime;
328 } 322 }
329 return -1; 323 return -1;
330 } 324 }
331 325
332 326
333 char* File::LinkTarget(const char* pathname) { 327 char* File::LinkTarget(const char* pathname) {
334 struct stat64 link_stats; 328 struct stat64 link_stats;
335 if (lstat64(pathname, &link_stats) != 0) return NULL; 329 if (NO_RETRY_EXPECTED(lstat64(pathname, &link_stats)) != 0) return NULL;
336 if (!S_ISLNK(link_stats.st_mode)) { 330 if (!S_ISLNK(link_stats.st_mode)) {
337 errno = ENOENT; 331 errno = ENOENT;
338 return NULL; 332 return NULL;
339 } 333 }
340 size_t target_size = link_stats.st_size; 334 size_t target_size = link_stats.st_size;
341 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1)); 335 char* target_name = reinterpret_cast<char*>(malloc(target_size + 1));
342 size_t read_size = readlink(pathname, target_name, target_size + 1); 336 size_t read_size = NO_RETRY_EXPECTED(
337 readlink(pathname, target_name, target_size + 1));
343 if (read_size != target_size) { 338 if (read_size != target_size) {
344 free(target_name); 339 free(target_name);
345 return NULL; 340 return NULL;
346 } 341 }
347 target_name[target_size] = '\0'; 342 target_name[target_size] = '\0';
348 return target_name; 343 return target_name;
349 } 344 }
350 345
351 346
352 bool File::IsAbsolutePath(const char* pathname) { 347 bool File::IsAbsolutePath(const char* pathname) {
(...skipping 19 matching lines...) Expand all
372 367
373 368
374 const char* File::StringEscapedPathSeparator() { 369 const char* File::StringEscapedPathSeparator() {
375 return "/"; 370 return "/";
376 } 371 }
377 372
378 373
379 File::StdioHandleType File::GetStdioHandleType(int fd) { 374 File::StdioHandleType File::GetStdioHandleType(int fd) {
380 ASSERT(0 <= fd && fd <= 2); 375 ASSERT(0 <= fd && fd <= 2);
381 struct stat64 buf; 376 struct stat64 buf;
382 int result = fstat64(fd, &buf); 377 int result = NO_RETRY_EXPECTED(fstat64(fd, &buf));
383 if (result == -1) { 378 if (result == -1) {
384 const int kBufferSize = 1024; 379 const int kBufferSize = 1024;
385 char error_buf[kBufferSize]; 380 char error_buf[kBufferSize];
386 FATAL2("Failed stat on file descriptor %d: %s", fd, 381 FATAL2("Failed stat on file descriptor %d: %s", fd,
387 strerror_r(errno, error_buf, kBufferSize)); 382 strerror_r(errno, error_buf, kBufferSize));
388 } 383 }
389 if (S_ISCHR(buf.st_mode)) return kTerminal; 384 if (S_ISCHR(buf.st_mode)) return kTerminal;
390 if (S_ISFIFO(buf.st_mode)) return kPipe; 385 if (S_ISFIFO(buf.st_mode)) return kPipe;
391 if (S_ISSOCK(buf.st_mode)) return kSocket; 386 if (S_ISSOCK(buf.st_mode)) return kSocket;
392 if (S_ISREG(buf.st_mode)) return kFile; 387 if (S_ISREG(buf.st_mode)) return kFile;
393 return kOther; 388 return kOther;
394 } 389 }
395 390
396 391
397 File::Type File::GetType(const char* pathname, bool follow_links) { 392 File::Type File::GetType(const char* pathname, bool follow_links) {
398 struct stat64 entry_info; 393 struct stat64 entry_info;
399 int stat_success; 394 int stat_success;
400 if (follow_links) { 395 if (follow_links) {
401 stat_success = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(stat64(pathname, 396 stat_success = NO_RETRY_EXPECTED(stat64(pathname, &entry_info));
402 &entry_info));
403 } else { 397 } else {
404 stat_success = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(lstat64(pathname, 398 stat_success = NO_RETRY_EXPECTED(lstat64(pathname, &entry_info));
405 &entry_info));
406 } 399 }
407 if (stat_success == -1) return File::kDoesNotExist; 400 if (stat_success == -1) return File::kDoesNotExist;
408 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory; 401 if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
409 if (S_ISREG(entry_info.st_mode)) return File::kIsFile; 402 if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
410 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink; 403 if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
411 return File::kDoesNotExist; 404 return File::kDoesNotExist;
412 } 405 }
413 406
414 407
415 File::Identical File::AreIdentical(const char* file_1, const char* file_2) { 408 File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
416 struct stat64 file_1_info; 409 struct stat64 file_1_info;
417 struct stat64 file_2_info; 410 struct stat64 file_2_info;
418 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(lstat64(file_1, &file_1_info)) == -1 || 411 if (NO_RETRY_EXPECTED(lstat64(file_1, &file_1_info)) == -1 ||
419 TEMP_FAILURE_RETRY_BLOCK_SIGNALS(lstat64(file_2, &file_2_info)) == -1) { 412 NO_RETRY_EXPECTED(lstat64(file_2, &file_2_info)) == -1) {
420 return File::kError; 413 return File::kError;
421 } 414 }
422 return (file_1_info.st_ino == file_2_info.st_ino && 415 return (file_1_info.st_ino == file_2_info.st_ino &&
423 file_1_info.st_dev == file_2_info.st_dev) ? 416 file_1_info.st_dev == file_2_info.st_dev) ?
424 File::kIdentical : 417 File::kIdentical :
425 File::kDifferent; 418 File::kDifferent;
426 } 419 }
427 420
428 } // namespace bin 421 } // namespace bin
429 } // namespace dart 422 } // namespace dart
430 423
431 #endif // defined(TARGET_OS_LINUX) 424 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/file_android.cc ('k') | runtime/bin/file_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698