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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "chrome/common/launchd_mac.h"
6
7 #import <Foundation/Foundation.h>
8 #include <launch.h>
9
10 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/scoped_nsautorelease_pool.h"
13 #include "base/process_util.h"
14 #include "base/stringprintf.h"
15 #include "base/sys_string_conversions.h"
16 #include "third_party/GTM/Foundation/GTMServiceManagement.h"
17
18 namespace {
19
20 NSString* SanitizeShellArgument(NSString* arg) {
21 if (!arg) {
22 return nil;
23 }
24 NSString *sanitize = [arg stringByReplacingOccurrencesOfString:@"'"
25 withString:@"'\''"];
26 return [NSString stringWithFormat:@"'%@'", sanitize];
27 }
28
29 NSURL* GetPlistURL(Launchd::Domain domain,
30 Launchd::Type type,
31 CFStringRef name) {
32 NSArray* library_paths =
33 NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, domain, YES);
34 DCHECK_EQ([library_paths count], 1U);
35 NSString* library_path = [library_paths objectAtIndex:0];
36
37 NSString *launch_dir_name = (type == Launchd::Daemon) ? @"LaunchDaemons"
38 : @"LaunchAgents";
39 NSString* launch_dir =
40 [library_path stringByAppendingPathComponent:launch_dir_name];
41
42 NSError* err;
43 if (![[NSFileManager defaultManager] createDirectoryAtPath:launch_dir
44 withIntermediateDirectories:YES
45 attributes:nil
46 error:&err]) {
47 LOG(ERROR) << "GetPlistURL " << base::mac::NSToCFCast(err);
48 return nil;
49 }
50
51 NSString* plist_file_path =
52 [launch_dir stringByAppendingPathComponent:base::mac::CFToNSCast(name)];
53 plist_file_path = [plist_file_path stringByAppendingPathExtension:@"plist"];
54 return [NSURL fileURLWithPath:plist_file_path isDirectory:NO];
55 }
56
57 } // namespace
58
59 COMPILE_ASSERT(static_cast<int>(Launchd::User) ==
60 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.
61 COMPILE_ASSERT(static_cast<int>(Launchd::Local) ==
62 static_cast<int>(NSLocalDomainMask), foundation_value_changed);
63 COMPILE_ASSERT(static_cast<int>(Launchd::Network) ==
64 static_cast<int>(NSNetworkDomainMask), foundation_value_changed);
65 COMPILE_ASSERT(static_cast<int>(Launchd::System) ==
66 static_cast<int>(NSSystemDomainMask), foundation_value_changed);
67
68 Launchd* Launchd::g_instance_ = NULL;
69
70 Launchd* Launchd::GetInstance() {
71 if (!g_instance_) {
72 g_instance_ = Singleton<Launchd>::get();
73 }
74 return g_instance_;
75 }
76
77 void Launchd::SetInstance(Launchd* instance) {
78 if (instance) {
79 CHECK(!g_instance_);
80 }
81 g_instance_ = instance;
82 }
83
84 Launchd::~Launchd() { }
85
86 CFDictionaryRef Launchd::CopyExports() {
87 return GTMCopyLaunchdExports();
88 }
89
90 CFDictionaryRef Launchd::CopyJobDictionary(CFStringRef label) {
91 return GTMSMJobCopyDictionary(label);
92 }
93
94 CFDictionaryRef Launchd::CopyDictionaryByCheckingIn(CFErrorRef* error) {
95 return GTMSMJobCheckIn(error);
96 }
97
98 bool Launchd::RemoveJob(CFStringRef label, CFErrorRef* error) {
99 return GTMSMJobRemove(label, error);
100 }
101
102 bool Launchd::RestartJob(Domain domain,
103 Type type,
104 CFStringRef name,
105 CFStringRef cf_session_type) {
106 base::mac::ScopedNSAutoreleasePool pool;
107 NSURL* url = GetPlistURL(domain, type, name);
108 NSString* ns_path = [url path];
109 ns_path = SanitizeShellArgument(ns_path);
110 const char* file_path = [ns_path fileSystemRepresentation];
111
112 NSString* ns_session_type =
113 SanitizeShellArgument(base::mac::CFToNSCast(cf_session_type));
114 if (!file_path || !ns_session_type) {
115 return false;
116 }
117
118 std::vector<std::string> argv;
119 argv.push_back("/bin/bash");
120 argv.push_back("--noprofile");
121 argv.push_back("-c");
122 std::string command = base::StringPrintf(
123 "/bin/launchctl unload -S %s %s;"
124 "/bin/launchctl load -S %s %s;",
125 [ns_session_type UTF8String], file_path,
126 [ns_session_type UTF8String], file_path);
127 argv.push_back(command);
128 base::ProcessHandle handle;
129 return base::LaunchAppInNewProcessGroup(argv,
130 base::environment_vector(),
131 base::file_handle_mapping_vector(),
132 NO,
133 &handle);
134 }
135
136 CFMutableDictionaryRef Launchd::CreatePlistFromFile(Domain domain,
137 Type type,
138 CFStringRef name) {
139 base::mac::ScopedNSAutoreleasePool pool;
140 NSURL* ns_url = GetPlistURL(domain, type, name);
141 NSMutableDictionary* plist =
142 [[NSMutableDictionary alloc] initWithContentsOfURL:ns_url];
143 return base::mac::NSToCFCast(plist);
144 }
145
146 bool Launchd::WritePlistToFile(Domain domain,
147 Type type,
148 CFStringRef name,
149 CFDictionaryRef dict) {
150 base::mac::ScopedNSAutoreleasePool pool;
151 NSURL* ns_url = GetPlistURL(domain, type, name);
152 return [base::mac::CFToNSCast(dict) writeToURL:ns_url atomically:YES];
153 }
154
155 bool Launchd::DeletePlist(Domain domain, Type type, CFStringRef name) {
156 base::mac::ScopedNSAutoreleasePool pool;
157 NSURL* ns_url = GetPlistURL(domain, type, name);
158 NSError* err = nil;
159 if (![[NSFileManager defaultManager] removeItemAtPath:[ns_url path]
160 error:&err]) {
161 if ([err code] != NSFileNoSuchFileError) {
162 LOG(ERROR) << "DeletePlist: " << base::mac::NSToCFCast(err);
163 }
164 return false;
165 }
166 return true;
167 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698