OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/common/service_process_util_posix.h" | 5 #include "chrome/common/service_process_util_posix.h" |
6 | 6 |
7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
8 #include <launch.h> | 8 #include <launch.h> |
9 | 9 |
10 #include <vector> | 10 #include <vector> |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 return @"ServiceProcessSocket"; | 60 return @"ServiceProcessSocket"; |
61 } | 61 } |
62 | 62 |
63 bool GetParentFSRef(const FSRef& child, FSRef* parent) { | 63 bool GetParentFSRef(const FSRef& child, FSRef* parent) { |
64 return FSGetCatalogInfo(&child, 0, NULL, NULL, NULL, parent) == noErr; | 64 return FSGetCatalogInfo(&child, 0, NULL, NULL, NULL, parent) == noErr; |
65 } | 65 } |
66 | 66 |
67 bool RemoveFromLaunchd() { | 67 bool RemoveFromLaunchd() { |
68 // We're killing a file. | 68 // We're killing a file. |
69 base::ThreadRestrictions::AssertIOAllowed(); | 69 base::ThreadRestrictions::AssertIOAllowed(); |
70 base::mac::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); | 70 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); |
71 return Launchd::GetInstance()->DeletePlist(Launchd::User, | 71 return Launchd::GetInstance()->DeletePlist( |
72 Launchd::Agent, | 72 Launchd::User, Launchd::Agent, name); |
73 name); | |
74 } | 73 } |
75 | 74 |
76 class ExecFilePathWatcherCallback { | 75 class ExecFilePathWatcherCallback { |
77 public: | 76 public: |
78 ExecFilePathWatcherCallback() {} | 77 ExecFilePathWatcherCallback() {} |
79 ~ExecFilePathWatcherCallback() {} | 78 ~ExecFilePathWatcherCallback() {} |
80 | 79 |
81 bool Init(const base::FilePath& path); | 80 bool Init(const base::FilePath& path); |
82 void NotifyPathChanged(const base::FilePath& path, bool error); | 81 void NotifyPathChanged(const base::FilePath& path, bool error); |
83 | 82 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 return reinterpret_cast<CFDictionaryRef>(launchd_plist); | 287 return reinterpret_cast<CFDictionaryRef>(launchd_plist); |
289 } | 288 } |
290 | 289 |
291 // Writes the launchd property list into the user's LaunchAgents directory, | 290 // Writes the launchd property list into the user's LaunchAgents directory, |
292 // creating that directory if needed. This will cause the service process to be | 291 // creating that directory if needed. This will cause the service process to be |
293 // auto launched on the next user login. | 292 // auto launched on the next user login. |
294 bool ServiceProcessState::AddToAutoRun() { | 293 bool ServiceProcessState::AddToAutoRun() { |
295 // We're creating directories and writing a file. | 294 // We're creating directories and writing a file. |
296 base::ThreadRestrictions::AssertIOAllowed(); | 295 base::ThreadRestrictions::AssertIOAllowed(); |
297 DCHECK(autorun_command_line_.get()); | 296 DCHECK(autorun_command_line_.get()); |
298 base::mac::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); | 297 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); |
299 base::mac::ScopedCFTypeRef<CFDictionaryRef> plist( | 298 base::ScopedCFTypeRef<CFDictionaryRef> plist( |
300 CreateServiceProcessLaunchdPlist(autorun_command_line_.get(), true)); | 299 CreateServiceProcessLaunchdPlist(autorun_command_line_.get(), true)); |
301 return Launchd::GetInstance()->WritePlistToFile(Launchd::User, | 300 return Launchd::GetInstance()->WritePlistToFile(Launchd::User, |
302 Launchd::Agent, | 301 Launchd::Agent, |
303 name, | 302 name, |
304 plist); | 303 plist); |
305 } | 304 } |
306 | 305 |
307 bool ServiceProcessState::RemoveFromAutoRun() { | 306 bool ServiceProcessState::RemoveFromAutoRun() { |
308 return RemoveFromLaunchd(); | 307 return RemoveFromLaunchd(); |
309 } | 308 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 bool needs_shutdown = false; | 350 bool needs_shutdown = false; |
352 bool needs_restart = false; | 351 bool needs_restart = false; |
353 bool good_bundle = false; | 352 bool good_bundle = false; |
354 | 353 |
355 FSRef macos_fsref; | 354 FSRef macos_fsref; |
356 if (GetParentFSRef(executable_fsref_, &macos_fsref)) { | 355 if (GetParentFSRef(executable_fsref_, &macos_fsref)) { |
357 FSRef contents_fsref; | 356 FSRef contents_fsref; |
358 if (GetParentFSRef(macos_fsref, &contents_fsref)) { | 357 if (GetParentFSRef(macos_fsref, &contents_fsref)) { |
359 FSRef bundle_fsref; | 358 FSRef bundle_fsref; |
360 if (GetParentFSRef(contents_fsref, &bundle_fsref)) { | 359 if (GetParentFSRef(contents_fsref, &bundle_fsref)) { |
361 base::mac::ScopedCFTypeRef<CFURLRef> bundle_url( | 360 base::ScopedCFTypeRef<CFURLRef> bundle_url( |
362 CFURLCreateFromFSRef(kCFAllocatorDefault, &bundle_fsref)); | 361 CFURLCreateFromFSRef(kCFAllocatorDefault, &bundle_fsref)); |
363 if (bundle_url.get()) { | 362 if (bundle_url.get()) { |
364 base::mac::ScopedCFTypeRef<CFBundleRef> bundle( | 363 base::ScopedCFTypeRef<CFBundleRef> bundle( |
365 CFBundleCreate(kCFAllocatorDefault, bundle_url)); | 364 CFBundleCreate(kCFAllocatorDefault, bundle_url)); |
366 // Check to see if the bundle still has a minimal structure. | 365 // Check to see if the bundle still has a minimal structure. |
367 good_bundle = CFBundleGetIdentifier(bundle) != NULL; | 366 good_bundle = CFBundleGetIdentifier(bundle) != NULL; |
368 } | 367 } |
369 } | 368 } |
370 } | 369 } |
371 } | 370 } |
372 if (!good_bundle) { | 371 if (!good_bundle) { |
373 needs_shutdown = true; | 372 needs_shutdown = true; |
374 } else { | 373 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
387 was_moved = false; | 386 was_moved = false; |
388 } | 387 } |
389 } | 388 } |
390 if (was_moved) { | 389 if (was_moved) { |
391 needs_restart = true; | 390 needs_restart = true; |
392 } | 391 } |
393 } | 392 } |
394 } | 393 } |
395 if (needs_shutdown || needs_restart) { | 394 if (needs_shutdown || needs_restart) { |
396 // First deal with the plist. | 395 // First deal with the plist. |
397 base::mac::ScopedCFTypeRef<CFStringRef> name( | 396 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); |
398 CopyServiceProcessLaunchDName()); | |
399 if (needs_restart) { | 397 if (needs_restart) { |
400 base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> plist( | 398 base::ScopedCFTypeRef<CFMutableDictionaryRef> plist( |
401 Launchd::GetInstance()->CreatePlistFromFile(Launchd::User, | 399 Launchd::GetInstance()->CreatePlistFromFile( |
402 Launchd::Agent, | 400 Launchd::User, Launchd::Agent, name)); |
403 name)); | |
404 if (plist.get()) { | 401 if (plist.get()) { |
405 NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist); | 402 NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist); |
406 std::string new_path = base::mac::PathFromFSRef(executable_fsref_); | 403 std::string new_path = base::mac::PathFromFSRef(executable_fsref_); |
407 NSString* ns_new_path = base::SysUTF8ToNSString(new_path); | 404 NSString* ns_new_path = base::SysUTF8ToNSString(new_path); |
408 [ns_plist setObject:ns_new_path forKey:@ LAUNCH_JOBKEY_PROGRAM]; | 405 [ns_plist setObject:ns_new_path forKey:@ LAUNCH_JOBKEY_PROGRAM]; |
409 scoped_nsobject<NSMutableArray> args( | 406 scoped_nsobject<NSMutableArray> args( |
410 [[ns_plist objectForKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS] | 407 [[ns_plist objectForKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS] |
411 mutableCopy]); | 408 mutableCopy]); |
412 [args replaceObjectAtIndex:0 withObject:ns_new_path]; | 409 [args replaceObjectAtIndex:0 withObject:ns_new_path]; |
413 [ns_plist setObject:args forKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS]; | 410 [ns_plist setObject:args forKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS]; |
(...skipping 24 matching lines...) Expand all Loading... |
438 session_type)) { | 435 session_type)) { |
439 DLOG(ERROR) << "RestartLaunchdJob"; | 436 DLOG(ERROR) << "RestartLaunchdJob"; |
440 needs_shutdown = true; | 437 needs_shutdown = true; |
441 } | 438 } |
442 } | 439 } |
443 if (needs_shutdown) { | 440 if (needs_shutdown) { |
444 CFStringRef label = | 441 CFStringRef label = |
445 base::mac::NSToCFCast(GetServiceProcessLaunchDLabel()); | 442 base::mac::NSToCFCast(GetServiceProcessLaunchDLabel()); |
446 CFErrorRef err = NULL; | 443 CFErrorRef err = NULL; |
447 if (!Launchd::GetInstance()->RemoveJob(label, &err)) { | 444 if (!Launchd::GetInstance()->RemoveJob(label, &err)) { |
448 base::mac::ScopedCFTypeRef<CFErrorRef> scoped_err(err); | 445 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err); |
449 DLOG(ERROR) << "RemoveJob " << err; | 446 DLOG(ERROR) << "RemoveJob " << err; |
450 // Exiting with zero, so launchd doesn't restart the process. | 447 // Exiting with zero, so launchd doesn't restart the process. |
451 exit(0); | 448 exit(0); |
452 } | 449 } |
453 } | 450 } |
454 } | 451 } |
455 } | 452 } |
OLD | NEW |