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

Unified Diff: chrome/common/launchd_mac.mm

Issue 6660001: Getting service process on Mac to handle having things moved/changed underneath it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix up bad instance reset Created 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/launchd_mac.mm
diff --git a/chrome/common/launchd_mac.mm b/chrome/common/launchd_mac.mm
new file mode 100644
index 0000000000000000000000000000000000000000..0c930bb5c0a8ff9a266f8833a9fc477a1ff96496
--- /dev/null
+++ b/chrome/common/launchd_mac.mm
@@ -0,0 +1,167 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/launchd_mac.h"
+
+#import <Foundation/Foundation.h>
+#include <launch.h>
+
+#include "base/mac/mac_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/mac/scoped_nsautorelease_pool.h"
+#include "base/process_util.h"
+#include "base/stringprintf.h"
+#include "base/sys_string_conversions.h"
+#include "third_party/GTM/Foundation/GTMServiceManagement.h"
+
+namespace {
+
+NSString* SanitizeShellArgument(NSString* arg) {
+ if (!arg) {
+ return nil;
+ }
+ NSString *sanitize = [arg stringByReplacingOccurrencesOfString:@"'"
+ withString:@"'\''"];
+ return [NSString stringWithFormat:@"'%@'", sanitize];
+}
+
+NSURL* GetPlistURL(Launchd::Domain domain,
+ Launchd::Type type,
+ CFStringRef name) {
+ NSArray* library_paths =
+ NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, domain, YES);
+ DCHECK_EQ([library_paths count], 1U);
+ NSString* library_path = [library_paths objectAtIndex:0];
+
+ NSString *launch_dir_name = (type == Launchd::Daemon) ? @"LaunchDaemons"
+ : @"LaunchAgents";
+ NSString* launch_dir =
+ [library_path stringByAppendingPathComponent:launch_dir_name];
+
+ NSError* err;
+ if (![[NSFileManager defaultManager] createDirectoryAtPath:launch_dir
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:&err]) {
+ LOG(ERROR) << "GetPlistURL " << base::mac::NSToCFCast(err);
+ return nil;
+ }
+
+ NSString* plist_file_path =
+ [launch_dir stringByAppendingPathComponent:base::mac::CFToNSCast(name)];
+ plist_file_path = [plist_file_path stringByAppendingPathExtension:@"plist"];
+ return [NSURL fileURLWithPath:plist_file_path isDirectory:NO];
+}
+
+} // namespace
+
+COMPILE_ASSERT(static_cast<int>(Launchd::User) ==
+ static_cast<int>(NSUserDomainMask), foundation_value_changed);
Mark Mentovai 2011/03/22 00:48:24 You should use a different msg (second parameter)
dmac 2011/03/22 03:13:32 Done.
+COMPILE_ASSERT(static_cast<int>(Launchd::Local) ==
+ static_cast<int>(NSLocalDomainMask), foundation_value_changed);
+COMPILE_ASSERT(static_cast<int>(Launchd::Network) ==
+ static_cast<int>(NSNetworkDomainMask), foundation_value_changed);
+COMPILE_ASSERT(static_cast<int>(Launchd::System) ==
+ static_cast<int>(NSSystemDomainMask), foundation_value_changed);
+
+Launchd* Launchd::g_instance_ = NULL;
+
+Launchd* Launchd::GetInstance() {
+ if (!g_instance_) {
+ g_instance_ = Singleton<Launchd>::get();
+ }
+ return g_instance_;
+}
+
+void Launchd::SetInstance(Launchd* instance) {
+ if (instance) {
+ CHECK(!g_instance_);
+ }
+ g_instance_ = instance;
+}
+
+Launchd::~Launchd() { }
+
+CFDictionaryRef Launchd::CopyExports() {
+ return GTMCopyLaunchdExports();
+}
+
+CFDictionaryRef Launchd::CopyJobDictionary(CFStringRef label) {
+ return GTMSMJobCopyDictionary(label);
+}
+
+CFDictionaryRef Launchd::CopyDictionaryByCheckingIn(CFErrorRef* error) {
+ return GTMSMJobCheckIn(error);
+}
+
+bool Launchd::RemoveJob(CFStringRef label, CFErrorRef* error) {
+ return GTMSMJobRemove(label, error);
+}
+
+bool Launchd::RestartJob(Domain domain,
+ Type type,
+ CFStringRef name,
+ CFStringRef cf_session_type) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ NSURL* url = GetPlistURL(domain, type, name);
+ NSString* ns_path = [url path];
+ ns_path = SanitizeShellArgument(ns_path);
+ const char* file_path = [ns_path fileSystemRepresentation];
+
+ NSString* ns_session_type =
+ SanitizeShellArgument(base::mac::CFToNSCast(cf_session_type));
+ if (!file_path || !ns_session_type) {
+ return false;
+ }
+
+ std::vector<std::string> argv;
+ argv.push_back("/bin/bash");
+ argv.push_back("--noprofile");
+ argv.push_back("-c");
+ std::string command = base::StringPrintf(
+ "/bin/launchctl unload -S %s %s;"
+ "/bin/launchctl load -S %s %s;",
+ [ns_session_type UTF8String], file_path,
+ [ns_session_type UTF8String], file_path);
+ argv.push_back(command);
+ base::ProcessHandle handle;
+ return base::LaunchAppInNewProcessGroup(argv,
+ base::environment_vector(),
+ base::file_handle_mapping_vector(),
+ NO,
+ &handle);
+}
+
+CFMutableDictionaryRef Launchd::CreatePlistFromFile(Domain domain,
+ Type type,
+ CFStringRef name) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ NSURL* ns_url = GetPlistURL(domain, type, name);
+ NSMutableDictionary* plist =
+ [[NSMutableDictionary alloc] initWithContentsOfURL:ns_url];
+ return base::mac::NSToCFCast(plist);
+}
+
+bool Launchd::WritePlistToFile(Domain domain,
+ Type type,
+ CFStringRef name,
+ CFDictionaryRef dict) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ NSURL* ns_url = GetPlistURL(domain, type, name);
+ return [base::mac::CFToNSCast(dict) writeToURL:ns_url atomically:YES];
+}
+
+bool Launchd::DeletePlist(Domain domain, Type type, CFStringRef name) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ NSURL* ns_url = GetPlistURL(domain, type, name);
+ NSError* err = nil;
+ if (![[NSFileManager defaultManager] removeItemAtPath:[ns_url path]
+ error:&err]) {
+ if ([err code] != NSFileNoSuchFileError) {
+ LOG(ERROR) << "DeletePlist: " << base::mac::NSToCFCast(err);
+ }
+ return false;
+ }
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698