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

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: Move over to FilePathWatcher 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..ce3a319ee3416523060549362c831d9d9646123f
--- /dev/null
+++ b/chrome/common/launchd_mac.mm
@@ -0,0 +1,189 @@
+// 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 {
+
+std::string FileSystemPathFromCFURL(CFURLRef url) {
+ base::mac::ScopedCFTypeRef<CFStringRef> path(
+ CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle));
Mark Mentovai 2011/03/21 16:50:49 Might path be NULL? If url is bad in some way, lik
dmac 2011/03/21 22:59:19 Obsolete.
+
+ // TODO(dmaclach): Turn this into a more general utility
Mark Mentovai 2011/03/21 16:50:49 This comment applies to the entire function, right
dmac 2011/03/21 22:59:19 Obsolete.
+ // http://crbug.com/76928
+ CFIndex max = CFStringGetMaximumSizeOfFileSystemRepresentation(path);
Mark Mentovai 2011/03/21 16:50:49 I’d just use -[NSString fileSystemRepresentation]
dmac 2011/03/21 22:59:19 Obsolete.
+ std::vector<char> buffer(max);
+ CHECK(CFStringGetFileSystemRepresentation(path, &buffer[0], max));
+ return std::string(&buffer[0]);
+}
+
+CFURLRef CopyPListURL(Launchd::Domain domain,
Mark Mentovai 2011/03/21 16:50:49 CopyPlistURL, lowercase L, as you’ve done elsewher
dmac 2011/03/21 22:59:19 Done.
+ Launchd::Type type,
+ CFStringRef name) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ NSArray* library_paths = NSSearchPathForDirectoriesInDomains(
+ NSLibraryDirectory,
+ domain,
Mark Mentovai 2011/03/21 16:50:49 Come up with a classier way to break these lines u
dmac 2011/03/21 22:59:19 Done.
+ true);
+ 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];
Mark Mentovai 2011/03/21 16:50:49 4-space the continuation line.
dmac 2011/03/21 22:59:19 Done.
+
+ NSError* err;
+ if (![[NSFileManager defaultManager] createDirectoryAtPath:launch_dir
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:&err]) {
+ LOG(ERROR) << "CopyPListURL " << base::mac::NSToCFCast(err);
+ return NULL;
+ }
+
+ NSString* plist_file_path
Mark Mentovai 2011/03/21 16:50:49 = goes on this line, not the next.
dmac 2011/03/21 22:59:19 I hate that. Done.
+ = [launch_dir stringByAppendingPathComponent:base::mac::CFToNSCast(name)];
+ plist_file_path = [plist_file_path stringByAppendingPathExtension:@"plist"];
+ NSURL *url = [[NSURL alloc] initFileURLWithPath:plist_file_path
Mark Mentovai 2011/03/21 16:50:49 You’ve been putting the *s on the type and not the
dmac 2011/03/21 22:59:19 Done.
+ isDirectory:NO];
+ return base::mac::NSToCFCast(url);
+}
+
+}
Mark Mentovai 2011/03/21 16:50:49 } // namespace
dmac 2011/03/21 22:59:19 Done.
+
+Launchd* Launchd::g_instance_ = NULL;
+bool Launchd::g_set_to_singleton_ = false;
Mark Mentovai 2011/03/21 16:50:49 I don’t see why you need this.
dmac 2011/03/21 22:59:19 Done.
+
+Launchd* Launchd::GetInstance() {
+ if (!g_instance_) {
+ g_instance_ = Singleton<Launchd>::get();
+ g_set_to_singleton_ = true;
+ }
+ return g_instance_;
+}
+
+void Launchd::SetInstance(Launchd* instance) {
+ CHECK(!g_set_to_singleton_);
+ g_instance_ = instance;
+}
+
+Launchd::~Launchd() { }
+
+CFDictionaryRef Launchd::CopyLaunchdExports() {
+ return GTMCopyLaunchdExports();
Mark Mentovai 2011/03/21 16:50:49 I haven’t read this code or its API documentation,
dmac 2011/03/21 22:59:19 OK.. it's been working for a while now.
+}
+
+CFDictionaryRef Launchd::CopyLaunchdJobDictionary(CFStringRef label) {
+ return GTMSMJobCopyDictionary(label);
+}
+
+CFDictionaryRef Launchd::CopyLaunchdDictionaryByCheckingIn(CFErrorRef* error) {
+ return GTMSMJobCheckIn(error);
+}
+
+bool Launchd::RemoveLaunchdJob(CFStringRef label, CFErrorRef* error) {
+ return GTMSMJobRemove(label, error);
+}
+
+bool Launchd::ShutdownLaunchdJob(Domain domain,
+ Type type,
+ CFStringRef name,
+ CFStringRef cf_session_type) {
+ base::mac::ScopedCFTypeRef<CFURLRef> cf_url(CopyPListURL(domain, type, name));
+ std::string path(FileSystemPathFromCFURL(cf_url));
Mark Mentovai 2011/03/21 16:50:49 Isn’t it kind of obnoxious to use CopyPlistURL, wh
dmac 2011/03/21 22:59:19 Done. It made sense in the earlier CL because some
+ std::string session_type(base::SysCFStringRefToUTF8(cf_session_type));
+ std::vector<std::string> argv;
+ argv.push_back("/bin/launchctl");
+ argv.push_back("unload");
+ argv.push_back("-S");
+ argv.push_back(session_type);
+ argv.push_back(path);
+ base::ProcessHandle handle;
+ return base::LaunchAppInNewProcessGroup(argv,
+ base::environment_vector(),
+ base::file_handle_mapping_vector(),
+ NO,
+ &handle);
+}
+
+bool Launchd::RestartLaunchdJob(Domain domain,
+ Type type,
+ CFStringRef name,
+ CFStringRef cf_session_type) {
+ base::mac::ScopedCFTypeRef<CFURLRef> cf_url(CopyPListURL(domain, type, name));
+ std::string path(FileSystemPathFromCFURL(cf_url));
+ std::string session_type(base::SysCFStringRefToUTF8(cf_session_type));
+ 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\";",
+ session_type.c_str(), path.c_str(),
Mark Mentovai 2011/03/21 16:50:49 Didn’t I mention doing proper sanitization and esc
+ session_type.c_str(), path.c_str());
+ argv.push_back(command);
+ base::ProcessHandle handle;
+ return base::LaunchAppInNewProcessGroup(argv,
+ base::environment_vector(),
+ base::file_handle_mapping_vector(),
+ NO,
+ &handle);
+}
+
+CFMutableDictionaryRef Launchd::ReadLaunchdPlist(Domain domain,
+ Type type,
+ CFStringRef name) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ base::mac::ScopedCFTypeRef<CFURLRef> cf_url(CopyPListURL(domain, type, name));
+ NSURL* ns_url = base::mac::CFToNSCast(cf_url);
+ NSMutableDictionary* plist
Mark Mentovai 2011/03/21 16:50:49 = goes on this line.
+ = [[NSMutableDictionary alloc] initWithContentsOfURL:ns_url];
Mark Mentovai 2011/03/21 16:50:49 Continuation line uses a 4-space indent.
Mark Mentovai 2011/03/21 16:50:49 OK, I see, the caller owns the returned dictionary
+ return base::mac::NSToCFCast(plist);
+}
+
+bool Launchd::WriteLaunchdPlist(Domain domain,
+ Type type,
+ CFStringRef name,
+ CFDictionaryRef dict) {
+ base::mac::ScopedNSAutoreleasePool pool;
+ base::mac::ScopedCFTypeRef<CFURLRef> cf_url(CopyPListURL(domain, type, name));
+ base::mac::ScopedCFTypeRef<CFDataRef> cf_data(
+ CFPropertyListCreateXMLData(kCFAllocatorDefault,
+ dict));
Mark Mentovai 2011/03/21 16:50:49 dict fits on the previous line for sure.
+ Boolean good = false;
Mark Mentovai 2011/03/21 16:50:49 Just bool, not Boolean.
+ if (cf_url.get() && cf_data.get()) {
+ SInt32 error = 0;
+ good = CFURLWriteDataAndPropertiesToResource(cf_url, cf_data, NULL, &error);
+ if (!good) {
+ LOG(ERROR) << "WriteLaunchdPlist " << error;
+ }
+ }
+ return good;
+}
+
+bool Launchd::DeleteLaunchDPlist(Domain domain, Type type, CFStringRef name) {
+ base::mac::ScopedCFTypeRef<CFURLRef> url(CopyPListURL(domain, type, name));
+ if (!url) {
+ return false;
+ }
+ SInt32 error = 0;
+ if (!CFURLDestroyResource(url, &error)) {
+ LOG(ERROR) << "DeleteLaunchDPlist: " << error;
+ return false;
+ }
+ return true;
+}
+
Mark Mentovai 2011/03/21 16:50:49 Dump the blank line at EOF.

Powered by Google App Engine
This is Rietveld 408576698