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

Side by Side Diff: services/files/directory_impl.cc

Issue 875643004: Prototype of Files service. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Remove much of DirectoryImpl implementation until I write tests. Created 5 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
OLDNEW
(Empty)
1 // Copyright 2015 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.
4
5 #include "services/files/directory_impl.h"
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <time.h>
13 #include <unistd.h>
14
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/files/scoped_file.h"
18 #include "base/logging.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/posix/eintr_wrapper.h"
21 #include "build/build_config.h"
22 #include "services/files/file_impl.h"
23 #include "services/files/util.h"
24
25 namespace mojo {
26 namespace files {
27
28 namespace {
29
30 Error ValidateOpenFlags(uint32_t open_flags, bool is_directory) {
31 // Treat unknown flags as "unimplemented".
32 if ((open_flags &
33 ~(kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate | kOpenFlagExclusive |
34 kOpenFlagAppend | kOpenFlagTruncate)))
35 return ERROR_UNIMPLEMENTED;
36
37 // At least one of |kOpenFlagRead| or |kOpenFlagWrite| must be set.
38 if (!(open_flags & (kOpenFlagRead | kOpenFlagWrite)))
39 return ERROR_INVALID_ARGUMENT;
40
41 // |kOpenFlagCreate| requires |kOpenFlagWrite|.
42 if ((open_flags & kOpenFlagCreate) && !(open_flags & kOpenFlagWrite))
43 return ERROR_INVALID_ARGUMENT;
44
45 // |kOpenFlagExclusive| requires |kOpenFlagCreate|.
46 if ((open_flags & kOpenFlagExclusive) && !(open_flags & kOpenFlagCreate))
47 return ERROR_INVALID_ARGUMENT;
48
49 if (is_directory) {
50 // Check that file-only flags aren't set.
51 if ((open_flags & (kOpenFlagAppend | kOpenFlagTruncate)))
52 return ERROR_INVALID_ARGUMENT;
53 return ERROR_OK;
54 }
55
56 // File-only flags:
57
58 // |kOpenFlagAppend| requires |kOpenFlagWrite|.
59 if ((open_flags & kOpenFlagAppend) && !(open_flags & kOpenFlagWrite))
60 return ERROR_INVALID_ARGUMENT;
61
62 // |kOpenFlagTruncate| requires |kOpenFlagWrite|.
63 if ((open_flags & kOpenFlagTruncate) && !(open_flags & kOpenFlagWrite))
64 return ERROR_INVALID_ARGUMENT;
65
66 return ERROR_OK;
67 }
68
69 } // namespace
70
71 DirectoryImpl::DirectoryImpl(InterfaceRequest<Directory> request,
72 base::ScopedFD dir_fd,
73 const base::FilePath& owned_dir_name)
74 : binding_(this, request.Pass()),
75 dir_fd_(dir_fd.Pass()),
76 owned_dir_name_(owned_dir_name) {
77 DCHECK(dir_fd_.is_valid());
78 }
79
80 DirectoryImpl::~DirectoryImpl() {
81 if (!owned_dir_name_.empty()) {
82 DVLOG(1) << "Deleting owned directory: " << owned_dir_name_.value();
83 LOG_IF(ERROR, !base::DeleteFile(owned_dir_name_, true))
84 << "Failed to delete owned directory: " << owned_dir_name_.value();
85 }
86 }
87
88 void DirectoryImpl::Read(
89 const Callback<void(Error, Array<DirectoryEntryPtr>)>& callback) {
90 // TODO(vtl): FIXME sooner
91 NOTIMPLEMENTED();
92 callback.Run(ERROR_UNIMPLEMENTED, Array<DirectoryEntryPtr>());
93 }
94
95 void DirectoryImpl::Stat(
96 const Callback<void(Error, FileInformationPtr)>& callback) {
97 // TODO(vtl): FIXME sooner
98 NOTIMPLEMENTED();
99 callback.Run(ERROR_UNIMPLEMENTED, nullptr);
100 }
101
102 void DirectoryImpl::Touch(TimespecOrNowPtr atime,
103 TimespecOrNowPtr mtime,
104 const Callback<void(Error)>& callback) {
105 // TODO(vtl): FIXME sooner
106 NOTIMPLEMENTED();
107 callback.Run(ERROR_UNIMPLEMENTED);
108 }
109
110 // TODO(vtl): Move the implementation to a thread pool.
111 void DirectoryImpl::OpenFile(const String& path,
112 InterfaceRequest<File> file,
113 uint32_t open_flags,
114 const Callback<void(Error)>& callback) {
115 DCHECK(!path.is_null());
116 DCHECK(dir_fd_.is_valid());
117
118 if (Error error = IsPathValid(path)) {
119 callback.Run(error);
120 return;
121 }
122 // TODO(vtl): Make sure the path doesn't exit this directory (if appropriate).
123 // TODO(vtl): Maybe allow absolute paths?
124
125 if (Error error = ValidateOpenFlags(open_flags, false)) {
126 callback.Run(error);
127 return;
128 }
129
130 int flags = 0;
131 if ((open_flags & kOpenFlagRead))
132 flags |= (open_flags & kOpenFlagWrite) ? O_RDWR : O_RDONLY;
133 else
134 flags |= O_WRONLY;
135 if ((open_flags & kOpenFlagCreate))
136 flags |= O_CREAT;
137 if ((open_flags & kOpenFlagExclusive))
138 flags |= O_EXCL;
139 if ((open_flags & kOpenFlagAppend))
140 flags |= O_APPEND;
141 if ((open_flags & kOpenFlagTruncate))
142 flags |= O_TRUNC;
143
144 base::ScopedFD file_fd(
145 HANDLE_EINTR(openat(dir_fd_.get(), path.get().c_str(), flags, 0600)));
146 if (!file_fd.is_valid()) {
147 callback.Run(ErrnoToError(errno));
148 return;
149 }
150
151 if (file.is_pending())
152 new FileImpl(file.Pass(), file_fd.Pass());
153 callback.Run(ERROR_OK);
154 }
155
156 void DirectoryImpl::OpenDirectory(const String& path,
157 InterfaceRequest<Directory> directory,
158 uint32_t open_flags,
159 const Callback<void(Error)>& callback) {
160 // TODO(vtl): FIXME sooner
161 NOTIMPLEMENTED();
162 callback.Run(ERROR_UNIMPLEMENTED);
163 }
164
165 void DirectoryImpl::Rename(const String& path,
166 const String& new_path,
167 const Callback<void(Error)>& callback) {
168 DCHECK(!path.is_null());
169 DCHECK(!new_path.is_null());
170 DCHECK(dir_fd_.is_valid());
171
172 if (Error error = IsPathValid(path)) {
173 callback.Run(error);
174 return;
175 }
176 if (Error error = IsPathValid(new_path)) {
177 callback.Run(error);
178 return;
179 }
180 // TODO(vtl): see TODOs about |path| in OpenFile()
181
182 if (renameat(dir_fd_.get(), path.get().c_str(), dir_fd_.get(),
183 new_path.get().c_str())) {
184 callback.Run(ErrnoToError(errno));
185 return;
186 }
187
188 callback.Run(ERROR_OK);
189 }
190
191 void DirectoryImpl::Delete(const String& path,
192 uint32_t delete_flags,
193 const Callback<void(Error)>& callback) {
194 // TODO(vtl): FIXME sooner
195 NOTIMPLEMENTED();
196 callback.Run(ERROR_UNIMPLEMENTED);
197 }
198
199 } // namespace files
200 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698