15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/mac/mock_launchd.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <CoreFoundation/CoreFoundation.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/un.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/foundation_util.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/scoped_cftyperef.h" 169ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/sys_string_conversions.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/mac/launchd.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/service_process_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sockaddr_un* throwaway_sockaddr_un; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kMaxPipeNameLength = 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(throwaway_sockaddr_un->sun_path); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MockLaunchd::MakeABundle(const base::FilePath& dst, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath* bundle_root, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath* executable) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bundle_root = dst.Append(name + std::string(".app")); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath contents = bundle_root->AppendASCII("Contents"); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath mac_os = contents.AppendASCII("MacOS"); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *executable = mac_os.Append(name); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath info_plist = contents.Append("Info.plist"); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_util::CreateDirectory(mac_os)) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *data = "#! testbundle\n"; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = strlen(data); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_util::WriteFile(*executable, data, len) != len) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chmod(executable->value().c_str(), 0555) != 0) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::VersionInfo version_info; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* info_plist_format = 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<plist version=\"1.0\">\n" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<dict>\n" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <key>CFBundleDevelopmentRegion</key>\n" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <string>English</string>\n" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <key>CFBundleExecutable</key>\n" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <string>%s</string>\n" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <key>CFBundleIdentifier</key>\n" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <string>com.test.%s</string>\n" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <key>CFBundleInfoDictionaryVersion</key>\n" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <string>6.0</string>\n" 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <key>CFBundleShortVersionString</key>\n" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <string>%s</string>\n" 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <key>CFBundleVersion</key>\n" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " <string>1</string>\n" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "</dict>\n" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "</plist>\n"; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string info_plist_data = 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf(info_plist_format, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name.c_str(), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name.c_str(), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version_info.Version().c_str()); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = info_plist_data.length(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_util::WriteFile(info_plist, info_plist_data.c_str(), len) != len) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UInt8* bundle_root_path = 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const UInt8*>(bundle_root->value().c_str()); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFURLRef> url( 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bundle_root_path, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bundle_root->value().length(), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true)); 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFBundleRef> bundle( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFBundleCreate(kCFAllocatorDefault, url)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bundle.get(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)MockLaunchd::MockLaunchd(const base::FilePath& file, 96a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop* loop, 97a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool create_socket, 98a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bool as_service) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : file_(file), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_(loop), 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_socket_(create_socket), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) as_service_(as_service), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restart_called_(false), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove_called_(false), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checkin_called_(false), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_called_(false), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_called_(false) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pipe_suffix("_SOCKET"); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath socket_path = file_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (socket_path.value().length() + pipe_suffix.length() > 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMaxPipeNameLength - 2) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_path = socket_path.DirName(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pipe_name_ = socket_path.value() + pipe_suffix; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockLaunchd::~MockLaunchd() { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFDictionaryRef MockLaunchd::CopyExports() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!create_socket_) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef env_var = 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::mac::NSToCFCast(GetServiceProcessLaunchDSocketEnvVar()); 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFStringRef> socket_path(CFStringCreateWithCString( 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kCFAllocatorDefault, pipe_name_.c_str(), kCFStringEncodingUTF8)); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *keys[] = { env_var }; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *values[] = { socket_path }; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(arraysize(keys) == arraysize(values), array_sizes_must_match); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CFDictionaryCreate(kCFAllocatorDefault, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(keys), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryKeyCallBacks, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryValueCallBacks); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFDictionaryRef MockLaunchd::CopyJobDictionary(CFStringRef label) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!as_service_) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MultiProcessLock> running_lock( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TakeNamedLock(pipe_name_, false)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (running_lock.get()) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef program_pid = CFSTR(LAUNCH_JOBKEY_PID); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *keys[] = { program, program_pid }; 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFStringRef> path( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SysUTF8ToCFStringRef(file_.value())); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id = base::GetCurrentProcId(); 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFNumberRef> pid( 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFNumberCreate(NULL, kCFNumberIntType, &process_id)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *values[] = { path, pid }; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(arraysize(keys) == arraysize(values), array_sizes_must_match); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CFDictionaryCreate(kCFAllocatorDefault, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(keys), 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryKeyCallBacks, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryValueCallBacks); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFDictionaryRef MockLaunchd::CopyDictionaryByCheckingIn(CFErrorRef* error) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) checkin_called_ = true; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef program_args = CFSTR(LAUNCH_JOBKEY_PROGRAMARGUMENTS); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFStringRef> path( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SysUTF8ToCFStringRef(file_.value())); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *array_values[] = { path.get() }; 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFArrayRef> args(CFArrayCreate( 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kCFAllocatorDefault, array_values, 1, &kCFTypeArrayCallBacks)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!create_socket_) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *keys[] = { program, program_args }; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *values[] = { path, args }; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(arraysize(keys) == arraysize(values), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array_sizes_must_match); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CFDictionaryCreate(kCFAllocatorDefault, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(keys), 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryKeyCallBacks, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryValueCallBacks); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef socket_key = CFSTR(LAUNCH_JOBKEY_SOCKETS); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int local_pipe = -1; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(as_service_); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create unix_addr structure. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sockaddr_un unix_addr = {0}; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unix_addr.sun_family = AF_UNIX; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t path_len = 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::strlcpy(unix_addr.sun_path, pipe_name_.c_str(), kMaxPipeNameLength); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(pipe_name_.length(), path_len); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unix_addr.sun_len = SUN_LEN(&unix_addr); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFSocketSignature signature; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.protocolFamily = PF_UNIX; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.socketType = SOCK_STREAM; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.protocol = 0; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t unix_addr_len = offsetof(struct sockaddr_un, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sun_path) + path_len + 1; 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFDataRef> address( 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFDataCreate(NULL, reinterpret_cast<UInt8*>(&unix_addr), unix_addr_len)); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature.address = address; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFSocketRef socket = 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFSocketCreateWithSocketSignature(NULL, &signature, 0, NULL, NULL); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_pipe = CFSocketGetNative(socket); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE(-1, local_pipe); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (local_pipe == -1) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno, NULL); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFNumberRef> socket_fd( 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFNumberCreate(NULL, kCFNumberIntType, &local_pipe)); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *socket_array_values[] = { socket_fd }; 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFArrayRef> sockets(CFArrayCreate( 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kCFAllocatorDefault, socket_array_values, 1, &kCFTypeArrayCallBacks)); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef socket_dict_key = CFSTR("ServiceProcessSocket"); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *socket_keys[] = { socket_dict_key }; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *socket_values[] = { sockets }; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(arraysize(socket_keys) == arraysize(socket_values), 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_array_sizes_must_match); 235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFDictionaryRef> socket_dict( 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFDictionaryCreate(kCFAllocatorDefault, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_keys, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_values, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(socket_keys), 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryKeyCallBacks, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryValueCallBacks)); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *keys[] = { program, program_args, socket_key }; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *values[] = { path, args, socket_dict }; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(arraysize(keys) == arraysize(values), array_sizes_must_match); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CFDictionaryCreate(kCFAllocatorDefault, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(keys), 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryKeyCallBacks, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kCFTypeDictionaryValueCallBacks); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockLaunchd::RemoveJob(CFStringRef label, CFErrorRef* error) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remove_called_ = true; 255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockLaunchd::RestartJob(Domain domain, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef name, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef session_type) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restart_called_ = true; 264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) message_loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CFMutableDictionaryRef MockLaunchd::CreatePlistFromFile( 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Domain domain, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef name) { 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ScopedCFTypeRef<CFDictionaryRef> dict(CopyDictionaryByCheckingIn(NULL)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, dict); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockLaunchd::WritePlistToFile(Domain domain, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef name, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFDictionaryRef dict) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_called_ = true; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockLaunchd::DeletePlist(Domain domain, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFStringRef name) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_called_ = true; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockLaunchd::SignalReady() { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(as_service_); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) running_lock_.reset(TakeNamedLock(pipe_name_, true)); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295