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

Side by Side Diff: chrome/browser/mac/relauncher.cc

Issue 197873014: Revert of Implement ScopedFD in terms of ScopedGeneric. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/mac/relauncher.h" 5 #include "chrome/browser/mac/relauncher.h"
6 6
7 #include <ApplicationServices/ApplicationServices.h> 7 #include <ApplicationServices/ApplicationServices.h>
8 #include <AvailabilityMacros.h> 8 #include <AvailabilityMacros.h>
9 #include <crt_externs.h> 9 #include <crt_externs.h>
10 #include <dlfcn.h> 10 #include <dlfcn.h>
11 #include <string.h> 11 #include <string.h>
12 #include <sys/event.h> 12 #include <sys/event.h>
13 #include <sys/time.h> 13 #include <sys/time.h>
14 #include <sys/types.h> 14 #include <sys/types.h>
15 #include <unistd.h> 15 #include <unistd.h>
16 16
17 #include <string> 17 #include <string>
18 #include <vector> 18 #include <vector>
19 19
20 #include "base/basictypes.h" 20 #include "base/basictypes.h"
21 #include "base/file_util.h" 21 #include "base/file_util.h"
22 #include "base/files/scoped_file.h"
23 #include "base/logging.h" 22 #include "base/logging.h"
24 #include "base/mac/mac_logging.h" 23 #include "base/mac/mac_logging.h"
25 #include "base/mac/mac_util.h" 24 #include "base/mac/mac_util.h"
26 #include "base/mac/scoped_cftyperef.h" 25 #include "base/mac/scoped_cftyperef.h"
27 #include "base/path_service.h" 26 #include "base/path_service.h"
28 #include "base/posix/eintr_wrapper.h" 27 #include "base/posix/eintr_wrapper.h"
29 #include "base/process/launch.h" 28 #include "base/process/launch.h"
30 #include "base/strings/stringprintf.h" 29 #include "base/strings/stringprintf.h"
31 #include "base/strings/sys_string_conversions.h" 30 #include "base/strings/sys_string_conversions.h"
32 #include "chrome/browser/mac/install_from_dmg.h" 31 #include "chrome/browser/mac/install_from_dmg.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 PLOG(ERROR) << "pipe"; 125 PLOG(ERROR) << "pipe";
127 return false; 126 return false;
128 } 127 }
129 128
130 // The parent process will only use pipe_read_fd as the read side of the 129 // The parent process will only use pipe_read_fd as the read side of the
131 // pipe. It can close the write side as soon as the relauncher process has 130 // pipe. It can close the write side as soon as the relauncher process has
132 // forked off. The relauncher process will only use pipe_write_fd as the 131 // forked off. The relauncher process will only use pipe_write_fd as the
133 // write side of the pipe. In that process, the read side will be closed by 132 // write side of the pipe. In that process, the read side will be closed by
134 // base::LaunchApp because it won't be present in fd_map, and the write side 133 // base::LaunchApp because it won't be present in fd_map, and the write side
135 // will be remapped to kRelauncherSyncFD by fd_map. 134 // will be remapped to kRelauncherSyncFD by fd_map.
136 base::ScopedFD pipe_read_fd(pipe_fds[0]); 135 file_util::ScopedFD pipe_read_fd(&pipe_fds[0]);
137 base::ScopedFD pipe_write_fd(pipe_fds[1]); 136 file_util::ScopedFD pipe_write_fd(&pipe_fds[1]);
138 137
139 // Make sure kRelauncherSyncFD is a safe value. base::LaunchProcess will 138 // Make sure kRelauncherSyncFD is a safe value. base::LaunchProcess will
140 // preserve these three FDs in forked processes, so kRelauncherSyncFD should 139 // preserve these three FDs in forked processes, so kRelauncherSyncFD should
141 // not conflict with them. 140 // not conflict with them.
142 COMPILE_ASSERT(kRelauncherSyncFD != STDIN_FILENO && 141 COMPILE_ASSERT(kRelauncherSyncFD != STDIN_FILENO &&
143 kRelauncherSyncFD != STDOUT_FILENO && 142 kRelauncherSyncFD != STDOUT_FILENO &&
144 kRelauncherSyncFD != STDERR_FILENO, 143 kRelauncherSyncFD != STDERR_FILENO,
145 kRelauncherSyncFD_must_not_conflict_with_stdio_fds); 144 kRelauncherSyncFD_must_not_conflict_with_stdio_fds);
146 145
147 base::FileHandleMappingVector fd_map; 146 base::FileHandleMappingVector fd_map;
148 fd_map.push_back(std::make_pair(pipe_write_fd.get(), kRelauncherSyncFD)); 147 fd_map.push_back(std::make_pair(*pipe_write_fd, kRelauncherSyncFD));
149 148
150 base::LaunchOptions options; 149 base::LaunchOptions options;
151 options.fds_to_remap = &fd_map; 150 options.fds_to_remap = &fd_map;
152 if (!base::LaunchProcess(relaunch_args, options, NULL)) { 151 if (!base::LaunchProcess(relaunch_args, options, NULL)) {
153 LOG(ERROR) << "base::LaunchProcess failed"; 152 LOG(ERROR) << "base::LaunchProcess failed";
154 return false; 153 return false;
155 } 154 }
156 155
157 // The relauncher process is now starting up, or has started up. The 156 // The relauncher process is now starting up, or has started up. The
158 // original parent process continues. 157 // original parent process continues.
159 158
160 pipe_write_fd.reset(); // close(pipe_fds[1]); 159 pipe_write_fd.reset(); // close(pipe_fds[1]);
161 160
162 // Synchronize with the relauncher process. 161 // Synchronize with the relauncher process.
163 char read_char; 162 char read_char;
164 int read_result = HANDLE_EINTR(read(pipe_read_fd.get(), &read_char, 1)); 163 int read_result = HANDLE_EINTR(read(*pipe_read_fd, &read_char, 1));
165 if (read_result != 1) { 164 if (read_result != 1) {
166 if (read_result < 0) { 165 if (read_result < 0) {
167 PLOG(ERROR) << "read"; 166 PLOG(ERROR) << "read";
168 } else { 167 } else {
169 LOG(ERROR) << "read: unexpected result " << read_result; 168 LOG(ERROR) << "read: unexpected result " << read_result;
170 } 169 }
171 return false; 170 return false;
172 } 171 }
173 172
174 // Since a byte has been successfully read from the relauncher process, it's 173 // Since a byte has been successfully read from the relauncher process, it's
175 // guaranteed to have set up its kqueue monitoring this process for exit. 174 // guaranteed to have set up its kqueue monitoring this process for exit.
176 // It's safe to exit now. 175 // It's safe to exit now.
177 return true; 176 return true;
178 } 177 }
179 178
180 namespace { 179 namespace {
181 180
182 // In the relauncher process, performs the necessary synchronization steps 181 // In the relauncher process, performs the necessary synchronization steps
183 // with the parent by setting up a kqueue to watch for it to exit, writing a 182 // with the parent by setting up a kqueue to watch for it to exit, writing a
184 // byte to the pipe, and then waiting for the exit notification on the kqueue. 183 // byte to the pipe, and then waiting for the exit notification on the kqueue.
185 // If anything fails, this logs a message and returns immediately. In those 184 // If anything fails, this logs a message and returns immediately. In those
186 // situations, it can be assumed that something went wrong with the parent 185 // situations, it can be assumed that something went wrong with the parent
187 // process and the best recovery approach is to attempt relaunch anyway. 186 // process and the best recovery approach is to attempt relaunch anyway.
188 void RelauncherSynchronizeWithParent() { 187 void RelauncherSynchronizeWithParent() {
189 base::ScopedFD relauncher_sync_fd(kRelauncherSyncFD); 188 // file_util::ScopedFD needs something non-const to operate on.
189 int relauncher_sync_fd = kRelauncherSyncFD;
190 file_util::ScopedFD relauncher_sync_fd_closer(&relauncher_sync_fd);
190 191
191 int parent_pid = getppid(); 192 int parent_pid = getppid();
192 193
193 // PID 1 identifies init. launchd, that is. launchd never starts the 194 // PID 1 identifies init. launchd, that is. launchd never starts the
194 // relauncher process directly, having this parent_pid means that the parent 195 // relauncher process directly, having this parent_pid means that the parent
195 // already exited and launchd "inherited" the relauncher as its child. 196 // already exited and launchd "inherited" the relauncher as its child.
196 // There's no reason to synchronize with launchd. 197 // There's no reason to synchronize with launchd.
197 if (parent_pid == 1) { 198 if (parent_pid == 1) {
198 LOG(ERROR) << "unexpected parent_pid"; 199 LOG(ERROR) << "unexpected parent_pid";
199 return; 200 return;
200 } 201 }
201 202
202 // Set up a kqueue to monitor the parent process for exit. 203 // Set up a kqueue to monitor the parent process for exit.
203 base::ScopedFD kq(kqueue()); 204 int kq = kqueue();
204 if (!kq.is_valid()) { 205 if (kq < 0) {
205 PLOG(ERROR) << "kqueue"; 206 PLOG(ERROR) << "kqueue";
206 return; 207 return;
207 } 208 }
209 file_util::ScopedFD kq_closer(&kq);
208 210
209 struct kevent change = { 0 }; 211 struct kevent change = { 0 };
210 EV_SET(&change, parent_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); 212 EV_SET(&change, parent_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
211 if (kevent(kq.get(), &change, 1, NULL, 0, NULL) == -1) { 213 if (kevent(kq, &change, 1, NULL, 0, NULL) == -1) {
212 PLOG(ERROR) << "kevent (add)"; 214 PLOG(ERROR) << "kevent (add)";
213 return; 215 return;
214 } 216 }
215 217
216 // Write a '\0' character to the pipe. 218 // Write a '\0' character to the pipe.
217 if (HANDLE_EINTR(write(relauncher_sync_fd.get(), "", 1)) != 1) { 219 if (HANDLE_EINTR(write(relauncher_sync_fd, "", 1)) != 1) {
218 PLOG(ERROR) << "write"; 220 PLOG(ERROR) << "write";
219 return; 221 return;
220 } 222 }
221 223
222 // Up until now, the parent process was blocked in a read waiting for the 224 // Up until now, the parent process was blocked in a read waiting for the
223 // write above to complete. The parent process is now free to exit. Wait for 225 // write above to complete. The parent process is now free to exit. Wait for
224 // that to happen. 226 // that to happen.
225 struct kevent event; 227 struct kevent event;
226 int events = kevent(kq.get(), NULL, 0, &event, 1, NULL); 228 int events = kevent(kq, NULL, 0, &event, 1, NULL);
227 if (events != 1) { 229 if (events != 1) {
228 if (events < 0) { 230 if (events < 0) {
229 PLOG(ERROR) << "kevent (monitor)"; 231 PLOG(ERROR) << "kevent (monitor)";
230 } else { 232 } else {
231 LOG(ERROR) << "kevent (monitor): unexpected result " << events; 233 LOG(ERROR) << "kevent (monitor): unexpected result " << events;
232 } 234 }
233 return; 235 return;
234 } 236 }
235 237
236 if (event.filter != EVFILT_PROC || 238 if (event.filter != EVFILT_PROC ||
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 if (!dmg_bsd_device_name.empty()) { 372 if (!dmg_bsd_device_name.empty()) {
371 EjectAndTrashDiskImage(dmg_bsd_device_name); 373 EjectAndTrashDiskImage(dmg_bsd_device_name);
372 } 374 }
373 375
374 return 0; 376 return 0;
375 } 377 }
376 378
377 } // namespace internal 379 } // namespace internal
378 380
379 } // namespace mac_relauncher 381 } // namespace mac_relauncher
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698