Move functions for controlling Caps Lock to CapsLockDelegate from SystemTrayDelegate.
[chromium-blink-merge.git] / base / platform_file_posix.cc
blob112b6a126d0a2ba77064c1eba1f5149ae0e323ee
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/platform_file.h"
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
12 #include "base/eintr_wrapper.h"
13 #include "base/file_path.h"
14 #include "base/logging.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "base/utf_string_conversions.h"
18 #if defined(OS_ANDROID)
19 #include "base/os_compat_android.h"
20 #endif
22 namespace base {
24 #if defined(OS_BSD) || defined(OS_MACOSX)
25 typedef struct stat stat_wrapper_t;
26 static int CallFstat(int fd, stat_wrapper_t *sb) {
27 base::ThreadRestrictions::AssertIOAllowed();
28 return fstat(fd, sb);
30 #else
31 typedef struct stat64 stat_wrapper_t;
32 static int CallFstat(int fd, stat_wrapper_t *sb) {
33 base::ThreadRestrictions::AssertIOAllowed();
34 return fstat64(fd, sb);
36 #endif
38 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here?
39 PlatformFile CreatePlatformFile(const FilePath& name, int flags,
40 bool* created, PlatformFileError* error_code) {
41 base::ThreadRestrictions::AssertIOAllowed();
43 int open_flags = 0;
44 if (flags & PLATFORM_FILE_CREATE)
45 open_flags = O_CREAT | O_EXCL;
47 if (created)
48 *created = false;
50 if (flags & PLATFORM_FILE_CREATE_ALWAYS) {
51 DCHECK(!open_flags);
52 open_flags = O_CREAT | O_TRUNC;
55 if (flags & PLATFORM_FILE_OPEN_TRUNCATED) {
56 DCHECK(!open_flags);
57 DCHECK(flags & PLATFORM_FILE_WRITE);
58 open_flags = O_TRUNC;
61 if (!open_flags && !(flags & PLATFORM_FILE_OPEN) &&
62 !(flags & PLATFORM_FILE_OPEN_ALWAYS)) {
63 NOTREACHED();
64 errno = EOPNOTSUPP;
65 if (error_code)
66 *error_code = PLATFORM_FILE_ERROR_FAILED;
67 return kInvalidPlatformFileValue;
70 if (flags & PLATFORM_FILE_WRITE && flags & PLATFORM_FILE_READ) {
71 open_flags |= O_RDWR;
72 } else if (flags & PLATFORM_FILE_WRITE) {
73 open_flags |= O_WRONLY;
74 } else if (!(flags & PLATFORM_FILE_READ) &&
75 !(flags & PLATFORM_FILE_WRITE_ATTRIBUTES) &&
76 !(flags & PLATFORM_FILE_OPEN_ALWAYS)) {
77 NOTREACHED();
80 if (flags & PLATFORM_FILE_TERMINAL_DEVICE)
81 open_flags |= O_NOCTTY | O_NDELAY;
83 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero);
85 int mode = S_IRUSR | S_IWUSR;
86 #if defined(OS_CHROMEOS)
87 mode |= S_IRGRP | S_IROTH;
88 #endif
90 int descriptor =
91 HANDLE_EINTR(open(name.value().c_str(), open_flags, mode));
93 if (flags & PLATFORM_FILE_OPEN_ALWAYS) {
94 if (descriptor < 0) {
95 open_flags |= O_CREAT;
96 if (flags & PLATFORM_FILE_EXCLUSIVE_READ ||
97 flags & PLATFORM_FILE_EXCLUSIVE_WRITE) {
98 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW
100 descriptor = HANDLE_EINTR(
101 open(name.value().c_str(), open_flags, mode));
102 if (created && descriptor >= 0)
103 *created = true;
107 if (created && (descriptor >= 0) &&
108 (flags & (PLATFORM_FILE_CREATE_ALWAYS | PLATFORM_FILE_CREATE)))
109 *created = true;
111 if ((descriptor >= 0) && (flags & PLATFORM_FILE_DELETE_ON_CLOSE)) {
112 unlink(name.value().c_str());
115 if (error_code) {
116 if (descriptor >= 0)
117 *error_code = PLATFORM_FILE_OK;
118 else {
119 switch (errno) {
120 case EACCES:
121 case EISDIR:
122 case EROFS:
123 case EPERM:
124 *error_code = PLATFORM_FILE_ERROR_ACCESS_DENIED;
125 break;
126 case ETXTBSY:
127 *error_code = PLATFORM_FILE_ERROR_IN_USE;
128 break;
129 case EEXIST:
130 *error_code = PLATFORM_FILE_ERROR_EXISTS;
131 break;
132 case ENOENT:
133 *error_code = PLATFORM_FILE_ERROR_NOT_FOUND;
134 break;
135 case EMFILE:
136 *error_code = PLATFORM_FILE_ERROR_TOO_MANY_OPENED;
137 break;
138 case ENOMEM:
139 *error_code = PLATFORM_FILE_ERROR_NO_MEMORY;
140 break;
141 case ENOSPC:
142 *error_code = PLATFORM_FILE_ERROR_NO_SPACE;
143 break;
144 case ENOTDIR:
145 *error_code = PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
146 break;
147 default:
148 *error_code = PLATFORM_FILE_ERROR_FAILED;
153 return descriptor;
156 bool ClosePlatformFile(PlatformFile file) {
157 base::ThreadRestrictions::AssertIOAllowed();
158 return !HANDLE_EINTR(close(file));
161 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) {
162 base::ThreadRestrictions::AssertIOAllowed();
163 if (file < 0 || size < 0)
164 return -1;
166 int bytes_read = 0;
167 int rv;
168 do {
169 rv = HANDLE_EINTR(pread(file, data + bytes_read,
170 size - bytes_read, offset + bytes_read));
171 if (rv <= 0)
172 break;
174 bytes_read += rv;
175 } while (bytes_read < size);
177 return bytes_read ? bytes_read : rv;
180 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) {
181 base::ThreadRestrictions::AssertIOAllowed();
182 if (file < 0 || size < 0)
183 return -1;
185 int bytes_read = 0;
186 int rv;
187 do {
188 rv = HANDLE_EINTR(read(file, data, size));
189 if (rv <= 0)
190 break;
192 bytes_read += rv;
193 } while (bytes_read < size);
195 return bytes_read ? bytes_read : rv;
198 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset,
199 char* data, int size) {
200 base::ThreadRestrictions::AssertIOAllowed();
201 if (file < 0)
202 return -1;
204 return HANDLE_EINTR(pread(file, data, size, offset));
207 int WritePlatformFile(PlatformFile file, int64 offset,
208 const char* data, int size) {
209 base::ThreadRestrictions::AssertIOAllowed();
210 if (file < 0 || size < 0)
211 return -1;
213 int bytes_written = 0;
214 int rv;
215 do {
216 rv = HANDLE_EINTR(pwrite(file, data + bytes_written,
217 size - bytes_written, offset + bytes_written));
218 if (rv <= 0)
219 break;
221 bytes_written += rv;
222 } while (bytes_written < size);
224 return bytes_written ? bytes_written : rv;
227 int WritePlatformFileAtCurrentPos(PlatformFile file,
228 const char* data, int size) {
229 base::ThreadRestrictions::AssertIOAllowed();
230 if (file < 0 || size < 0)
231 return -1;
233 int bytes_written = 0;
234 int rv;
235 do {
236 rv = HANDLE_EINTR(write(file, data, size));
237 if (rv <= 0)
238 break;
240 bytes_written += rv;
241 } while (bytes_written < size);
243 return bytes_written ? bytes_written : rv;
246 bool TruncatePlatformFile(PlatformFile file, int64 length) {
247 base::ThreadRestrictions::AssertIOAllowed();
248 return ((file >= 0) && !HANDLE_EINTR(ftruncate(file, length)));
251 bool FlushPlatformFile(PlatformFile file) {
252 base::ThreadRestrictions::AssertIOAllowed();
253 return !HANDLE_EINTR(fsync(file));
256 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time,
257 const base::Time& last_modified_time) {
258 base::ThreadRestrictions::AssertIOAllowed();
259 if (file < 0)
260 return false;
262 timeval times[2];
263 times[0] = last_access_time.ToTimeVal();
264 times[1] = last_modified_time.ToTimeVal();
265 return !futimes(file, times);
268 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
269 if (!info)
270 return false;
272 stat_wrapper_t file_info;
273 if (CallFstat(file, &file_info))
274 return false;
276 info->is_directory = S_ISDIR(file_info.st_mode);
277 info->is_symbolic_link = S_ISLNK(file_info.st_mode);
278 info->size = file_info.st_size;
279 info->last_modified = base::Time::FromTimeT(file_info.st_mtime);
280 info->last_accessed = base::Time::FromTimeT(file_info.st_atime);
281 info->creation_time = base::Time::FromTimeT(file_info.st_ctime);
282 return true;
285 } // namespace base