Index: chrome/common/service_process_util_mac.mm |
diff --git a/chrome/common/service_process_util_mac.mm b/chrome/common/service_process_util_mac.mm |
index 0f5746fa002c2e01d6d70600531c78f1d29a6cd1..3313c112c582f9ffddf9b8b5604aa146ad7a7e6e 100644 |
--- a/chrome/common/service_process_util_mac.mm |
+++ b/chrome/common/service_process_util_mac.mm |
@@ -9,6 +9,7 @@ |
#include "base/command_line.h" |
#include "base/file_path.h" |
+#include "base/file_util.h" |
#include "base/mac/foundation_util.h" |
#include "base/mac/mac_util.h" |
#include "base/mac/scoped_nsautorelease_pool.h" |
@@ -81,7 +82,20 @@ NSURL* GetUserAgentPath() { |
return [NSURL fileURLWithPath:plist_file_path isDirectory:NO]; |
} |
-} |
+class ExecPathComponentWatcherDelegate |
+ : public base::FilePathComponentWatcher::Delegate { |
+ public: |
+ ExecPathComponentWatcherDelegate(Task* shutdown_task) |
+ : shutdown_task_(shutdown_task) { } |
+ virtual ~ExecPathComponentWatcherDelegate(); |
+ virtual void OnFilePathComponentsChanged(const FilePath& old_path, |
+ const FilePath& new_path) OVERRIDE; |
+ |
+private: |
+ Task* shutdown_task_; |
+}; |
+ |
+} // namespace |
// Gets the name of the service process IPC channel. |
IPC::ChannelHandle GetServiceProcessChannel() { |
@@ -166,6 +180,23 @@ bool ServiceProcessState::Initialize() { |
CFRelease(err); |
return false; |
} |
+ |
+ |
+ return true; |
+} |
+ |
+bool ServiceProcessState::SignalReadyPlatformSpecific(Task* shutdown_task) { |
+ NSDictionary *ns_launchd_conf = base::mac::CFToNSCast(state_->launchd_conf_); |
+ NSString *exe_path = [ns_launchd_conf objectForKey:@ LAUNCH_JOBKEY_PROGRAM]; |
+ if (!exe_path) { |
+ return false; |
+ } |
+ |
+ FilePath executable_path = FilePath([exe_path fileSystemRepresentation]); |
+ if (!state_->executable_watcher_.Watch( |
+ executable_path, new ExecPathComponentWatcherDelegate(shutdown_task))) { |
+ return false; |
+ } |
return true; |
} |
@@ -302,3 +333,29 @@ bool ServiceProcessState::RemoveFromAutoRun() { |
} |
return true; |
} |
+ |
+ExecPathComponentWatcherDelegate::~ExecPathComponentWatcherDelegate() { } |
+void ExecPathComponentWatcherDelegate::OnFilePathComponentsChanged( |
+ const FilePath& old_path, const FilePath& new_path) { |
+ bool needs_shutdown = false; |
+ bool needs_plist_rewrite = false; |
+ bool needs_plist_deletion = false; |
+ |
+ if (access(new_path.value().c_str(), W_OK) != 0) { |
+ // Can we execute it? |
+ needs_shutdown = true; |
+ needs_plist_deletion = true; |
+ } else if (file_util::IsInTrash(new_path)) { |
+ // Is it in the trash? |
+ needs_shutdown = true; |
+ needs_plist_deletion = true; |
+ } else if (!file_util::AreReferringToSameObject(old_path, new_path)) { |
+ // Did it get moved? |
+ needs_plist_rewrite = true; |
+ } |
+ |
+ if (needs_shutdown) { |
+ MessageLoop::current()->PostTask(FROM_HERE, shutdown_task_); |
+ } |
+} |
+ |