Remove base/process/launch*
And some unused unittest files.
Change-Id: I9900f676c79644cb0fe1a35a4da6857bc5a5b5bf
Reviewed-on: https://gn-review.googlesource.com/1620
Commit-Queue: Scott Graham <scottmg@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/base/linux_util.cc b/base/linux_util.cc
index f2d29ec..1f3ae49 100644
--- a/base/linux_util.cc
+++ b/base/linux_util.cc
@@ -19,7 +19,6 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/memory/singleton.h"
-#include "base/process/launch.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
diff --git a/base/mac/bind_objc_block_unittest.mm b/base/mac/bind_objc_block_unittest.mm
deleted file mode 100644
index 38da5aa..0000000
--- a/base/mac/bind_objc_block_unittest.mm
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2012 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.
-
-#import "base/mac/bind_objc_block.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-
-#if defined(OS_IOS)
-#include "base/ios/weak_nsobject.h"
-#include "base/mac/scoped_nsautorelease_pool.h"
-#endif
-
-namespace {
-
-TEST(BindObjcBlockTest, TestScopedClosureRunnerExitScope) {
- int run_count = 0;
- int* ptr = &run_count;
- {
- base::ScopedClosureRunner runner(base::BindBlock(^{
- (*ptr)++;
- }));
- EXPECT_EQ(0, run_count);
- }
- EXPECT_EQ(1, run_count);
-}
-
-TEST(BindObjcBlockTest, TestScopedClosureRunnerRelease) {
- int run_count = 0;
- int* ptr = &run_count;
- base::OnceClosure c;
- {
- base::ScopedClosureRunner runner(base::BindBlock(^{
- (*ptr)++;
- }));
- c = runner.Release();
- EXPECT_EQ(0, run_count);
- }
- EXPECT_EQ(0, run_count);
- std::move(c).Run();
- EXPECT_EQ(1, run_count);
-}
-
-TEST(BindObjcBlockTest, TestReturnValue) {
- const int kReturnValue = 42;
- base::Callback<int(void)> c = base::BindBlock(^{return kReturnValue;});
- EXPECT_EQ(kReturnValue, c.Run());
-}
-
-TEST(BindObjcBlockTest, TestArgument) {
- const int kArgument = 42;
- base::Callback<int(int)> c = base::BindBlock(^(int a){return a + 1;});
- EXPECT_EQ(kArgument + 1, c.Run(kArgument));
-}
-
-TEST(BindObjcBlockTest, TestTwoArguments) {
- std::string result;
- std::string* ptr = &result;
- base::Callback<void(const std::string&, const std::string&)> c =
- base::BindBlock(^(const std::string& a, const std::string& b) {
- *ptr = a + b;
- });
- c.Run("forty", "two");
- EXPECT_EQ(result, "fortytwo");
-}
-
-TEST(BindObjcBlockTest, TestThreeArguments) {
- std::string result;
- std::string* ptr = &result;
- base::Callback<void(const std::string&,
- const std::string&,
- const std::string&)> c =
- base::BindBlock(^(const std::string& a,
- const std::string& b,
- const std::string& c) {
- *ptr = a + b + c;
- });
- c.Run("six", "times", "nine");
- EXPECT_EQ(result, "sixtimesnine");
-}
-
-TEST(BindObjcBlockTest, TestSixArguments) {
- std::string result1;
- std::string* ptr = &result1;
- int result2;
- int* ptr2 = &result2;
- base::Callback<void(int, int, const std::string&, const std::string&,
- int, const std::string&)> c =
- base::BindBlock(^(int a, int b, const std::string& c,
- const std::string& d, int e, const std::string& f) {
- *ptr = c + d + f;
- *ptr2 = a + b + e;
- });
- c.Run(1, 2, "infinite", "improbability", 3, "drive");
- EXPECT_EQ(result1, "infiniteimprobabilitydrive");
- EXPECT_EQ(result2, 6);
-}
-
-#if defined(OS_IOS)
-
-TEST(BindObjcBlockTest, TestBlockReleased) {
- base::WeakNSObject<NSObject> weak_nsobject;
- {
- base::mac::ScopedNSAutoreleasePool autorelease_pool;
- NSObject* nsobject = [[[NSObject alloc] init] autorelease];
- weak_nsobject.reset(nsobject);
-
- auto callback = base::BindBlock(^{
- [nsobject description];
- });
- }
- EXPECT_NSEQ(nil, weak_nsobject);
-}
-
-#endif
-
-} // namespace
diff --git a/base/mac/bind_objc_block_unittest_arc.mm b/base/mac/bind_objc_block_unittest_arc.mm
deleted file mode 100644
index f5f953d..0000000
--- a/base/mac/bind_objc_block_unittest_arc.mm
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2012 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.
-
-#import "base/mac/bind_objc_block.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/callback_helpers.h"
-#include "build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-TEST(BindObjcBlockTestARC, TestScopedClosureRunnerExitScope) {
- int run_count = 0;
- int* ptr = &run_count;
- {
- base::ScopedClosureRunner runner(base::BindBlockArc(^{
- (*ptr)++;
- }));
- EXPECT_EQ(0, run_count);
- }
- EXPECT_EQ(1, run_count);
-}
-
-TEST(BindObjcBlockTestARC, TestScopedClosureRunnerRelease) {
- int run_count = 0;
- int* ptr = &run_count;
- base::OnceClosure c;
- {
- base::ScopedClosureRunner runner(base::BindBlockArc(^{
- (*ptr)++;
- }));
- c = runner.Release();
- EXPECT_EQ(0, run_count);
- }
- EXPECT_EQ(0, run_count);
- std::move(c).Run();
- EXPECT_EQ(1, run_count);
-}
-
-TEST(BindObjcBlockTestARC, TestReturnValue) {
- const int kReturnValue = 42;
- base::Callback<int(void)> c = base::BindBlockArc(^{
- return kReturnValue;
- });
- EXPECT_EQ(kReturnValue, c.Run());
-}
-
-TEST(BindObjcBlockTestARC, TestArgument) {
- const int kArgument = 42;
- base::Callback<int(int)> c = base::BindBlockArc(^(int a) {
- return a + 1;
- });
- EXPECT_EQ(kArgument + 1, c.Run(kArgument));
-}
-
-TEST(BindObjcBlockTestARC, TestTwoArguments) {
- std::string result;
- std::string* ptr = &result;
- base::Callback<void(const std::string&, const std::string&)> c =
- base::BindBlockArc(^(const std::string& a, const std::string& b) {
- *ptr = a + b;
- });
- c.Run("forty", "two");
- EXPECT_EQ(result, "fortytwo");
-}
-
-TEST(BindObjcBlockTestARC, TestThreeArguments) {
- std::string result;
- std::string* ptr = &result;
- base::Callback<void(const std::string&, const std::string&,
- const std::string&)>
- c = base::BindBlockArc(
- ^(const std::string& a, const std::string& b, const std::string& c) {
- *ptr = a + b + c;
- });
- c.Run("six", "times", "nine");
- EXPECT_EQ(result, "sixtimesnine");
-}
-
-TEST(BindObjcBlockTestARC, TestSixArguments) {
- std::string result1;
- std::string* ptr = &result1;
- int result2;
- int* ptr2 = &result2;
- base::Callback<void(int, int, const std::string&, const std::string&, int,
- const std::string&)>
- c = base::BindBlockArc(^(int a, int b, const std::string& c,
- const std::string& d, int e,
- const std::string& f) {
- *ptr = c + d + f;
- *ptr2 = a + b + e;
- });
- c.Run(1, 2, "infinite", "improbability", 3, "drive");
- EXPECT_EQ(result1, "infiniteimprobabilitydrive");
- EXPECT_EQ(result2, 6);
-}
-
-#if defined(OS_IOS)
-
-TEST(BindObjcBlockTestARC, TestBlockReleased) {
- __weak NSObject* weak_nsobject;
- @autoreleasepool {
- NSObject* nsobject = [[NSObject alloc] init];
- weak_nsobject = nsobject;
-
- auto callback = base::BindBlockArc(^{
- [nsobject description];
- });
- }
- EXPECT_NSEQ(nil, weak_nsobject);
-}
-
-#endif
-
-} // namespace
diff --git a/base/mac/call_with_eh_frame_unittest.mm b/base/mac/call_with_eh_frame_unittest.mm
deleted file mode 100644
index 4dad822..0000000
--- a/base/mac/call_with_eh_frame_unittest.mm
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2015 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 "base/mac/call_with_eh_frame.h"
-
-#import <Foundation/Foundation.h>
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-namespace mac {
-namespace {
-
-class CallWithEHFrameTest : public testing::Test {
- protected:
- void ThrowException() {
- @throw [NSException exceptionWithName:@"TestException"
- reason:@"Testing exceptions"
- userInfo:nil];
- }
-};
-
-// Catching from within the EHFrame is allowed.
-TEST_F(CallWithEHFrameTest, CatchExceptionHigher) {
- bool __block saw_exception = false;
- base::mac::CallWithEHFrame(^{
- @try {
- ThrowException();
- } @catch (NSException* exception) {
- saw_exception = true;
- }
- });
- EXPECT_TRUE(saw_exception);
-}
-
-// Trying to catch an exception outside the EHFrame is blocked.
-TEST_F(CallWithEHFrameTest, CatchExceptionLower) {
- auto catch_exception_lower = ^{
- bool saw_exception = false;
- @try {
- base::mac::CallWithEHFrame(^{
- ThrowException();
- });
- } @catch (NSException* exception) {
- saw_exception = true;
- }
- ASSERT_FALSE(saw_exception);
- };
- EXPECT_DEATH(catch_exception_lower(), "");
-}
-
-} // namespace
-} // namespace mac
-} // namespace base
diff --git a/base/mac/foundation_util_unittest.mm b/base/mac/foundation_util_unittest.mm
deleted file mode 100644
index ce02163..0000000
--- a/base/mac/foundation_util_unittest.mm
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright (c) 2012 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 "base/mac/foundation_util.h"
-
-#include <limits.h>
-#include <stddef.h>
-
-#include "base/compiler_specific.h"
-#include "base/files/file_path.h"
-#include "base/format_macros.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/macros.h"
-#include "base/strings/stringprintf.h"
-#include "build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#import "testing/gtest_mac.h"
-
-namespace base {
-namespace mac {
-
-TEST(FoundationUtilTest, CFCast) {
- // Build out the CF types to be tested as empty containers.
- ScopedCFTypeRef<CFTypeRef> test_array(
- CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks));
- ScopedCFTypeRef<CFTypeRef> test_array_mutable(
- CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
- ScopedCFTypeRef<CFTypeRef> test_bag(
- CFBagCreate(NULL, NULL, 0, &kCFTypeBagCallBacks));
- ScopedCFTypeRef<CFTypeRef> test_bag_mutable(
- CFBagCreateMutable(NULL, 0, &kCFTypeBagCallBacks));
- CFTypeRef test_bool = kCFBooleanTrue;
- ScopedCFTypeRef<CFTypeRef> test_data(
- CFDataCreate(NULL, NULL, 0));
- ScopedCFTypeRef<CFTypeRef> test_data_mutable(
- CFDataCreateMutable(NULL, 0));
- ScopedCFTypeRef<CFTypeRef> test_date(
- CFDateCreate(NULL, 0));
- ScopedCFTypeRef<CFTypeRef> test_dict(
- CFDictionaryCreate(NULL, NULL, NULL, 0,
- &kCFCopyStringDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
- ScopedCFTypeRef<CFTypeRef> test_dict_mutable(
- CFDictionaryCreateMutable(NULL, 0,
- &kCFCopyStringDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
- int int_val = 256;
- ScopedCFTypeRef<CFTypeRef> test_number(
- CFNumberCreate(NULL, kCFNumberIntType, &int_val));
- CFTypeRef test_null = kCFNull;
- ScopedCFTypeRef<CFTypeRef> test_set(
- CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks));
- ScopedCFTypeRef<CFTypeRef> test_set_mutable(
- CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks));
- ScopedCFTypeRef<CFTypeRef> test_str(
- CFStringCreateWithBytes(NULL, NULL, 0, kCFStringEncodingASCII, false));
- CFTypeRef test_str_const = CFSTR("hello");
- ScopedCFTypeRef<CFTypeRef> test_str_mutable(CFStringCreateMutable(NULL, 0));
-
- // Make sure the allocations of CF types are good.
- EXPECT_TRUE(test_array);
- EXPECT_TRUE(test_array_mutable);
- EXPECT_TRUE(test_bag);
- EXPECT_TRUE(test_bag_mutable);
- EXPECT_TRUE(test_bool);
- EXPECT_TRUE(test_data);
- EXPECT_TRUE(test_data_mutable);
- EXPECT_TRUE(test_date);
- EXPECT_TRUE(test_dict);
- EXPECT_TRUE(test_dict_mutable);
- EXPECT_TRUE(test_number);
- EXPECT_TRUE(test_null);
- EXPECT_TRUE(test_set);
- EXPECT_TRUE(test_set_mutable);
- EXPECT_TRUE(test_str);
- EXPECT_TRUE(test_str_const);
- EXPECT_TRUE(test_str_mutable);
-
- // Casting the CFTypeRef objects correctly provides the same pointer.
- EXPECT_EQ(test_array, CFCast<CFArrayRef>(test_array));
- EXPECT_EQ(test_array_mutable, CFCast<CFArrayRef>(test_array_mutable));
- EXPECT_EQ(test_bag, CFCast<CFBagRef>(test_bag));
- EXPECT_EQ(test_bag_mutable, CFCast<CFBagRef>(test_bag_mutable));
- EXPECT_EQ(test_bool, CFCast<CFBooleanRef>(test_bool));
- EXPECT_EQ(test_data, CFCast<CFDataRef>(test_data));
- EXPECT_EQ(test_data_mutable, CFCast<CFDataRef>(test_data_mutable));
- EXPECT_EQ(test_date, CFCast<CFDateRef>(test_date));
- EXPECT_EQ(test_dict, CFCast<CFDictionaryRef>(test_dict));
- EXPECT_EQ(test_dict_mutable, CFCast<CFDictionaryRef>(test_dict_mutable));
- EXPECT_EQ(test_number, CFCast<CFNumberRef>(test_number));
- EXPECT_EQ(test_null, CFCast<CFNullRef>(test_null));
- EXPECT_EQ(test_set, CFCast<CFSetRef>(test_set));
- EXPECT_EQ(test_set_mutable, CFCast<CFSetRef>(test_set_mutable));
- EXPECT_EQ(test_str, CFCast<CFStringRef>(test_str));
- EXPECT_EQ(test_str_const, CFCast<CFStringRef>(test_str_const));
- EXPECT_EQ(test_str_mutable, CFCast<CFStringRef>(test_str_mutable));
-
- // When given an incorrect CF cast, provide NULL.
- EXPECT_FALSE(CFCast<CFStringRef>(test_array));
- EXPECT_FALSE(CFCast<CFStringRef>(test_array_mutable));
- EXPECT_FALSE(CFCast<CFStringRef>(test_bag));
- EXPECT_FALSE(CFCast<CFSetRef>(test_bag_mutable));
- EXPECT_FALSE(CFCast<CFSetRef>(test_bool));
- EXPECT_FALSE(CFCast<CFNullRef>(test_data));
- EXPECT_FALSE(CFCast<CFDictionaryRef>(test_data_mutable));
- EXPECT_FALSE(CFCast<CFDictionaryRef>(test_date));
- EXPECT_FALSE(CFCast<CFNumberRef>(test_dict));
- EXPECT_FALSE(CFCast<CFDateRef>(test_dict_mutable));
- EXPECT_FALSE(CFCast<CFDataRef>(test_number));
- EXPECT_FALSE(CFCast<CFDataRef>(test_null));
- EXPECT_FALSE(CFCast<CFBooleanRef>(test_set));
- EXPECT_FALSE(CFCast<CFBagRef>(test_set_mutable));
- EXPECT_FALSE(CFCast<CFBagRef>(test_str));
- EXPECT_FALSE(CFCast<CFArrayRef>(test_str_const));
- EXPECT_FALSE(CFCast<CFArrayRef>(test_str_mutable));
-
- // Giving a NULL provides a NULL.
- EXPECT_FALSE(CFCast<CFArrayRef>(NULL));
- EXPECT_FALSE(CFCast<CFBagRef>(NULL));
- EXPECT_FALSE(CFCast<CFBooleanRef>(NULL));
- EXPECT_FALSE(CFCast<CFDataRef>(NULL));
- EXPECT_FALSE(CFCast<CFDateRef>(NULL));
- EXPECT_FALSE(CFCast<CFDictionaryRef>(NULL));
- EXPECT_FALSE(CFCast<CFNullRef>(NULL));
- EXPECT_FALSE(CFCast<CFNumberRef>(NULL));
- EXPECT_FALSE(CFCast<CFSetRef>(NULL));
- EXPECT_FALSE(CFCast<CFStringRef>(NULL));
-
- // CFCastStrict: correct cast results in correct pointer being returned.
- EXPECT_EQ(test_array, CFCastStrict<CFArrayRef>(test_array));
- EXPECT_EQ(test_array_mutable, CFCastStrict<CFArrayRef>(test_array_mutable));
- EXPECT_EQ(test_bag, CFCastStrict<CFBagRef>(test_bag));
- EXPECT_EQ(test_bag_mutable, CFCastStrict<CFBagRef>(test_bag_mutable));
- EXPECT_EQ(test_bool, CFCastStrict<CFBooleanRef>(test_bool));
- EXPECT_EQ(test_data, CFCastStrict<CFDataRef>(test_data));
- EXPECT_EQ(test_data_mutable, CFCastStrict<CFDataRef>(test_data_mutable));
- EXPECT_EQ(test_date, CFCastStrict<CFDateRef>(test_date));
- EXPECT_EQ(test_dict, CFCastStrict<CFDictionaryRef>(test_dict));
- EXPECT_EQ(test_dict_mutable,
- CFCastStrict<CFDictionaryRef>(test_dict_mutable));
- EXPECT_EQ(test_number, CFCastStrict<CFNumberRef>(test_number));
- EXPECT_EQ(test_null, CFCastStrict<CFNullRef>(test_null));
- EXPECT_EQ(test_set, CFCastStrict<CFSetRef>(test_set));
- EXPECT_EQ(test_set_mutable, CFCastStrict<CFSetRef>(test_set_mutable));
- EXPECT_EQ(test_str, CFCastStrict<CFStringRef>(test_str));
- EXPECT_EQ(test_str_const, CFCastStrict<CFStringRef>(test_str_const));
- EXPECT_EQ(test_str_mutable, CFCastStrict<CFStringRef>(test_str_mutable));
-
- // CFCastStrict: Giving a NULL provides a NULL.
- EXPECT_FALSE(CFCastStrict<CFArrayRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFBagRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFBooleanRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFDataRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFDateRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFDictionaryRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFNullRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFNumberRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFSetRef>(NULL));
- EXPECT_FALSE(CFCastStrict<CFStringRef>(NULL));
-}
-
-TEST(FoundationUtilTest, ObjCCast) {
- ScopedNSAutoreleasePool pool;
-
- id test_array = @[];
- id test_array_mutable = [NSMutableArray array];
- id test_data = [NSData data];
- id test_data_mutable = [NSMutableData dataWithCapacity:10];
- id test_date = [NSDate date];
- id test_dict = @{ @"meaning" : @42 };
- id test_dict_mutable = [NSMutableDictionary dictionaryWithCapacity:10];
- id test_number = @42;
- id test_null = [NSNull null];
- id test_set = [NSSet setWithObject:@"string object"];
- id test_set_mutable = [NSMutableSet setWithCapacity:10];
- id test_str = [NSString string];
- id test_str_const = @"bonjour";
- id test_str_mutable = [NSMutableString stringWithCapacity:10];
-
- // Make sure the allocations of NS types are good.
- EXPECT_TRUE(test_array);
- EXPECT_TRUE(test_array_mutable);
- EXPECT_TRUE(test_data);
- EXPECT_TRUE(test_data_mutable);
- EXPECT_TRUE(test_date);
- EXPECT_TRUE(test_dict);
- EXPECT_TRUE(test_dict_mutable);
- EXPECT_TRUE(test_number);
- EXPECT_TRUE(test_null);
- EXPECT_TRUE(test_set);
- EXPECT_TRUE(test_set_mutable);
- EXPECT_TRUE(test_str);
- EXPECT_TRUE(test_str_const);
- EXPECT_TRUE(test_str_mutable);
-
- // Casting the id correctly provides the same pointer.
- EXPECT_EQ(test_array, ObjCCast<NSArray>(test_array));
- EXPECT_EQ(test_array_mutable, ObjCCast<NSArray>(test_array_mutable));
- EXPECT_EQ(test_data, ObjCCast<NSData>(test_data));
- EXPECT_EQ(test_data_mutable, ObjCCast<NSData>(test_data_mutable));
- EXPECT_EQ(test_date, ObjCCast<NSDate>(test_date));
- EXPECT_EQ(test_dict, ObjCCast<NSDictionary>(test_dict));
- EXPECT_EQ(test_dict_mutable, ObjCCast<NSDictionary>(test_dict_mutable));
- EXPECT_EQ(test_number, ObjCCast<NSNumber>(test_number));
- EXPECT_EQ(test_null, ObjCCast<NSNull>(test_null));
- EXPECT_EQ(test_set, ObjCCast<NSSet>(test_set));
- EXPECT_EQ(test_set_mutable, ObjCCast<NSSet>(test_set_mutable));
- EXPECT_EQ(test_str, ObjCCast<NSString>(test_str));
- EXPECT_EQ(test_str_const, ObjCCast<NSString>(test_str_const));
- EXPECT_EQ(test_str_mutable, ObjCCast<NSString>(test_str_mutable));
-
- // When given an incorrect ObjC cast, provide nil.
- EXPECT_FALSE(ObjCCast<NSString>(test_array));
- EXPECT_FALSE(ObjCCast<NSString>(test_array_mutable));
- EXPECT_FALSE(ObjCCast<NSString>(test_data));
- EXPECT_FALSE(ObjCCast<NSString>(test_data_mutable));
- EXPECT_FALSE(ObjCCast<NSSet>(test_date));
- EXPECT_FALSE(ObjCCast<NSSet>(test_dict));
- EXPECT_FALSE(ObjCCast<NSNumber>(test_dict_mutable));
- EXPECT_FALSE(ObjCCast<NSNull>(test_number));
- EXPECT_FALSE(ObjCCast<NSDictionary>(test_null));
- EXPECT_FALSE(ObjCCast<NSDictionary>(test_set));
- EXPECT_FALSE(ObjCCast<NSDate>(test_set_mutable));
- EXPECT_FALSE(ObjCCast<NSData>(test_str));
- EXPECT_FALSE(ObjCCast<NSData>(test_str_const));
- EXPECT_FALSE(ObjCCast<NSArray>(test_str_mutable));
-
- // Giving a nil provides a nil.
- EXPECT_FALSE(ObjCCast<NSArray>(nil));
- EXPECT_FALSE(ObjCCast<NSData>(nil));
- EXPECT_FALSE(ObjCCast<NSDate>(nil));
- EXPECT_FALSE(ObjCCast<NSDictionary>(nil));
- EXPECT_FALSE(ObjCCast<NSNull>(nil));
- EXPECT_FALSE(ObjCCast<NSNumber>(nil));
- EXPECT_FALSE(ObjCCast<NSSet>(nil));
- EXPECT_FALSE(ObjCCast<NSString>(nil));
-
- // ObjCCastStrict: correct cast results in correct pointer being returned.
- EXPECT_EQ(test_array, ObjCCastStrict<NSArray>(test_array));
- EXPECT_EQ(test_array_mutable,
- ObjCCastStrict<NSArray>(test_array_mutable));
- EXPECT_EQ(test_data, ObjCCastStrict<NSData>(test_data));
- EXPECT_EQ(test_data_mutable,
- ObjCCastStrict<NSData>(test_data_mutable));
- EXPECT_EQ(test_date, ObjCCastStrict<NSDate>(test_date));
- EXPECT_EQ(test_dict, ObjCCastStrict<NSDictionary>(test_dict));
- EXPECT_EQ(test_dict_mutable,
- ObjCCastStrict<NSDictionary>(test_dict_mutable));
- EXPECT_EQ(test_number, ObjCCastStrict<NSNumber>(test_number));
- EXPECT_EQ(test_null, ObjCCastStrict<NSNull>(test_null));
- EXPECT_EQ(test_set, ObjCCastStrict<NSSet>(test_set));
- EXPECT_EQ(test_set_mutable,
- ObjCCastStrict<NSSet>(test_set_mutable));
- EXPECT_EQ(test_str, ObjCCastStrict<NSString>(test_str));
- EXPECT_EQ(test_str_const,
- ObjCCastStrict<NSString>(test_str_const));
- EXPECT_EQ(test_str_mutable,
- ObjCCastStrict<NSString>(test_str_mutable));
-
- // ObjCCastStrict: Giving a nil provides a nil.
- EXPECT_FALSE(ObjCCastStrict<NSArray>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSData>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSDate>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSDictionary>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSNull>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSNumber>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSSet>(nil));
- EXPECT_FALSE(ObjCCastStrict<NSString>(nil));
-}
-
-TEST(FoundationUtilTest, GetValueFromDictionary) {
- int one = 1, two = 2, three = 3;
-
- ScopedCFTypeRef<CFNumberRef> cf_one(
- CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &one));
- ScopedCFTypeRef<CFNumberRef> cf_two(
- CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &two));
- ScopedCFTypeRef<CFNumberRef> cf_three(
- CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &three));
-
- CFStringRef keys[] = { CFSTR("one"), CFSTR("two"), CFSTR("three") };
- CFNumberRef values[] = { cf_one, cf_two, cf_three };
-
- static_assert(arraysize(keys) == arraysize(values),
- "keys and values arrays must have the same size");
-
- ScopedCFTypeRef<CFDictionaryRef> test_dict(
- CFDictionaryCreate(kCFAllocatorDefault,
- reinterpret_cast<const void**>(keys),
- reinterpret_cast<const void**>(values),
- arraysize(values),
- &kCFCopyStringDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
-
- // GetValueFromDictionary<>(_, _) should produce the correct
- // expected output.
- EXPECT_EQ(values[0],
- GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("one")));
- EXPECT_EQ(values[1],
- GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("two")));
- EXPECT_EQ(values[2],
- GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("three")));
-
- // Bad input should produce bad output.
- EXPECT_FALSE(GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("four")));
- EXPECT_FALSE(GetValueFromDictionary<CFStringRef>(test_dict, CFSTR("one")));
-}
-
-TEST(FoundationUtilTest, FilePathToNSString) {
- EXPECT_NSEQ(nil, FilePathToNSString(FilePath()));
- EXPECT_NSEQ(@"/a/b", FilePathToNSString(FilePath("/a/b")));
-}
-
-TEST(FoundationUtilTest, NSStringToFilePath) {
- EXPECT_EQ(FilePath(), NSStringToFilePath(nil));
- EXPECT_EQ(FilePath(), NSStringToFilePath(@""));
- EXPECT_EQ(FilePath("/a/b"), NSStringToFilePath(@"/a/b"));
-}
-
-TEST(FoundationUtilTest, CFRangeToNSRange) {
- NSRange range_out;
- EXPECT_TRUE(CFRangeToNSRange(CFRangeMake(10, 5), &range_out));
- EXPECT_EQ(10UL, range_out.location);
- EXPECT_EQ(5UL, range_out.length);
- EXPECT_FALSE(CFRangeToNSRange(CFRangeMake(-1, 5), &range_out));
- EXPECT_FALSE(CFRangeToNSRange(CFRangeMake(5, -1), &range_out));
- EXPECT_FALSE(CFRangeToNSRange(CFRangeMake(-1, -1), &range_out));
- EXPECT_FALSE(CFRangeToNSRange(CFRangeMake(LONG_MAX, LONG_MAX), &range_out));
- EXPECT_FALSE(CFRangeToNSRange(CFRangeMake(LONG_MIN, LONG_MAX), &range_out));
-}
-
-TEST(StringNumberConversionsTest, FormatNSInteger) {
- // The PRI[dxu]NS macro assumes that NSInteger is a typedef to "int" on
- // 32-bit architecture and a typedef to "long" on 64-bit architecture
- // (respectively "unsigned int" and "unsigned long" for NSUInteger). Use
- // pointer incompatibility to validate this at compilation.
-#if defined(ARCH_CPU_64_BITS)
- typedef long FormatNSIntegerAsType;
- typedef unsigned long FormatNSUIntegerAsType;
-#else
- typedef int FormatNSIntegerAsType;
- typedef unsigned int FormatNSUIntegerAsType;
-#endif // defined(ARCH_CPU_64_BITS)
-
- NSInteger some_nsinteger;
- FormatNSIntegerAsType* pointer_to_some_nsinteger = &some_nsinteger;
- ALLOW_UNUSED_LOCAL(pointer_to_some_nsinteger);
-
- NSUInteger some_nsuinteger;
- FormatNSUIntegerAsType* pointer_to_some_nsuinteger = &some_nsuinteger;
- ALLOW_UNUSED_LOCAL(pointer_to_some_nsuinteger);
-
- // Check that format specifier works correctly for NSInteger.
- const struct {
- NSInteger value;
- const char* expected;
- const char* expected_hex;
- } nsinteger_cases[] = {
-#if !defined(ARCH_CPU_64_BITS)
- {12345678, "12345678", "bc614e"},
- {-12345678, "-12345678", "ff439eb2"},
-#else
- {12345678, "12345678", "bc614e"},
- {-12345678, "-12345678", "ffffffffff439eb2"},
- {137451299150l, "137451299150", "2000bc614e"},
- {-137451299150l, "-137451299150", "ffffffdfff439eb2"},
-#endif // !defined(ARCH_CPU_64_BITS)
- };
-
- for (size_t i = 0; i < arraysize(nsinteger_cases); ++i) {
- EXPECT_EQ(nsinteger_cases[i].expected,
- StringPrintf("%" PRIdNS, nsinteger_cases[i].value));
- EXPECT_EQ(nsinteger_cases[i].expected_hex,
- StringPrintf("%" PRIxNS, nsinteger_cases[i].value));
- }
-
- // Check that format specifier works correctly for NSUInteger.
- const struct {
- NSUInteger value;
- const char* expected;
- const char* expected_hex;
- } nsuinteger_cases[] = {
-#if !defined(ARCH_CPU_64_BITS)
- {12345678u, "12345678", "bc614e"},
- {4282621618u, "4282621618", "ff439eb2"},
-#else
- {12345678u, "12345678", "bc614e"},
- {4282621618u, "4282621618", "ff439eb2"},
- {137451299150ul, "137451299150", "2000bc614e"},
- {18446743936258252466ul, "18446743936258252466", "ffffffdfff439eb2"},
-#endif // !defined(ARCH_CPU_64_BITS)
- };
-
- for (size_t i = 0; i < arraysize(nsuinteger_cases); ++i) {
- EXPECT_EQ(nsuinteger_cases[i].expected,
- StringPrintf("%" PRIuNS, nsuinteger_cases[i].value));
- EXPECT_EQ(nsuinteger_cases[i].expected_hex,
- StringPrintf("%" PRIxNS, nsuinteger_cases[i].value));
- }
-}
-
-} // namespace mac
-} // namespace base
diff --git a/base/mac/mac_util_unittest.mm b/base/mac/mac_util_unittest.mm
deleted file mode 100644
index 266d1c4..0000000
--- a/base/mac/mac_util_unittest.mm
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (c) 2012 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.
-
-#import <Cocoa/Cocoa.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/mac/mac_util.h"
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/macros.h"
-#include "base/sys_info.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-#include <errno.h>
-#include <sys/xattr.h>
-
-namespace base {
-namespace mac {
-
-namespace {
-
-typedef PlatformTest MacUtilTest;
-
-TEST_F(MacUtilTest, GetUserDirectoryTest) {
- // Try a few keys, make sure they come back with non-empty paths.
- FilePath caches_dir;
- EXPECT_TRUE(GetUserDirectory(NSCachesDirectory, &caches_dir));
- EXPECT_FALSE(caches_dir.empty());
-
- FilePath application_support_dir;
- EXPECT_TRUE(GetUserDirectory(NSApplicationSupportDirectory,
- &application_support_dir));
- EXPECT_FALSE(application_support_dir.empty());
-
- FilePath library_dir;
- EXPECT_TRUE(GetUserDirectory(NSLibraryDirectory, &library_dir));
- EXPECT_FALSE(library_dir.empty());
-}
-
-TEST_F(MacUtilTest, TestLibraryPath) {
- FilePath library_dir = GetUserLibraryPath();
- // Make sure the string isn't empty.
- EXPECT_FALSE(library_dir.value().empty());
-}
-
-TEST_F(MacUtilTest, TestGetAppBundlePath) {
- FilePath out;
-
- // Make sure it doesn't crash.
- out = GetAppBundlePath(FilePath());
- EXPECT_TRUE(out.empty());
-
- // Some more invalid inputs.
- const char* const invalid_inputs[] = {
- "/", "/foo", "foo", "/foo/bar.", "foo/bar.", "/foo/bar./bazquux",
- "foo/bar./bazquux", "foo/.app", "//foo",
- };
- for (size_t i = 0; i < arraysize(invalid_inputs); i++) {
- out = GetAppBundlePath(FilePath(invalid_inputs[i]));
- EXPECT_TRUE(out.empty()) << "loop: " << i;
- }
-
- // Some valid inputs; this and |expected_outputs| should be in sync.
- struct {
- const char *in;
- const char *expected_out;
- } valid_inputs[] = {
- { "FooBar.app/", "FooBar.app" },
- { "/FooBar.app", "/FooBar.app" },
- { "/FooBar.app/", "/FooBar.app" },
- { "//FooBar.app", "//FooBar.app" },
- { "/Foo/Bar.app", "/Foo/Bar.app" },
- { "/Foo/Bar.app/", "/Foo/Bar.app" },
- { "/F/B.app", "/F/B.app" },
- { "/F/B.app/", "/F/B.app" },
- { "/Foo/Bar.app/baz", "/Foo/Bar.app" },
- { "/Foo/Bar.app/baz/", "/Foo/Bar.app" },
- { "/Foo/Bar.app/baz/quux.app/quuux", "/Foo/Bar.app" },
- { "/Applications/Google Foo.app/bar/Foo Helper.app/quux/Foo Helper",
- "/Applications/Google Foo.app" },
- };
- for (size_t i = 0; i < arraysize(valid_inputs); i++) {
- out = GetAppBundlePath(FilePath(valid_inputs[i].in));
- EXPECT_FALSE(out.empty()) << "loop: " << i;
- EXPECT_STREQ(valid_inputs[i].expected_out,
- out.value().c_str()) << "loop: " << i;
- }
-}
-
-// http://crbug.com/425745
-TEST_F(MacUtilTest, DISABLED_TestExcludeFileFromBackups) {
- // The file must already exist in order to set its exclusion property.
- ScopedTempDir temp_dir_;
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- FilePath dummy_file_path = temp_dir_.GetPath().Append("DummyFile");
- const char dummy_data[] = "All your base are belong to us!";
- // Dump something real into the file.
- ASSERT_EQ(static_cast<int>(arraysize(dummy_data)),
- WriteFile(dummy_file_path, dummy_data, arraysize(dummy_data)));
- NSString* fileURLString =
- [NSString stringWithUTF8String:dummy_file_path.value().c_str()];
- NSURL* fileURL = [NSURL URLWithString:fileURLString];
- // Initial state should be non-excluded.
- EXPECT_FALSE(CSBackupIsItemExcluded(base::mac::NSToCFCast(fileURL), NULL));
- // Exclude the file.
- EXPECT_TRUE(SetFileBackupExclusion(dummy_file_path));
- // SetFileBackupExclusion never excludes by path.
- Boolean excluded_by_path = FALSE;
- Boolean excluded =
- CSBackupIsItemExcluded(base::mac::NSToCFCast(fileURL), &excluded_by_path);
- EXPECT_TRUE(excluded);
- EXPECT_FALSE(excluded_by_path);
-}
-
-TEST_F(MacUtilTest, NSObjectRetainRelease) {
- base::scoped_nsobject<NSArray> array(
- [[NSArray alloc] initWithObjects:@"foo", nil]);
- EXPECT_EQ(1U, [array retainCount]);
-
- NSObjectRetain(array);
- EXPECT_EQ(2U, [array retainCount]);
-
- NSObjectRelease(array);
- EXPECT_EQ(1U, [array retainCount]);
-}
-
-TEST_F(MacUtilTest, IsOSEllipsis) {
- int32_t major, minor, bugfix;
- base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix);
-
- if (major == 10) {
- if (minor == 9) {
- EXPECT_TRUE(IsOS10_9());
- EXPECT_TRUE(IsAtMostOS10_9());
- EXPECT_TRUE(IsAtLeastOS10_9());
- EXPECT_FALSE(IsOS10_10());
- EXPECT_TRUE(IsAtMostOS10_10());
- EXPECT_FALSE(IsAtLeastOS10_10());
- EXPECT_FALSE(IsOS10_11());
- EXPECT_TRUE(IsAtMostOS10_11());
- EXPECT_FALSE(IsAtLeastOS10_11());
- EXPECT_FALSE(IsOS10_12());
- EXPECT_FALSE(IsAtLeastOS10_12());
- EXPECT_TRUE(IsAtMostOS10_12());
- EXPECT_FALSE(IsOS10_13());
- EXPECT_FALSE(IsAtLeastOS10_13());
- EXPECT_TRUE(IsAtMostOS10_13());
- EXPECT_FALSE(IsOSLaterThan10_13_DontCallThis());
- } else if (minor == 10) {
- EXPECT_FALSE(IsOS10_9());
- EXPECT_FALSE(IsAtMostOS10_9());
- EXPECT_TRUE(IsAtLeastOS10_9());
- EXPECT_TRUE(IsOS10_10());
- EXPECT_TRUE(IsAtMostOS10_10());
- EXPECT_TRUE(IsAtLeastOS10_10());
- EXPECT_FALSE(IsOS10_11());
- EXPECT_TRUE(IsAtMostOS10_11());
- EXPECT_FALSE(IsAtLeastOS10_11());
- EXPECT_FALSE(IsOS10_12());
- EXPECT_FALSE(IsAtLeastOS10_12());
- EXPECT_TRUE(IsAtMostOS10_12());
- EXPECT_FALSE(IsOS10_13());
- EXPECT_FALSE(IsAtLeastOS10_13());
- EXPECT_TRUE(IsAtMostOS10_13());
- EXPECT_FALSE(IsOSLaterThan10_13_DontCallThis());
- } else if (minor == 11) {
- EXPECT_FALSE(IsOS10_9());
- EXPECT_FALSE(IsAtMostOS10_9());
- EXPECT_TRUE(IsAtLeastOS10_9());
- EXPECT_FALSE(IsOS10_10());
- EXPECT_FALSE(IsAtMostOS10_10());
- EXPECT_TRUE(IsAtLeastOS10_10());
- EXPECT_TRUE(IsOS10_11());
- EXPECT_TRUE(IsAtMostOS10_11());
- EXPECT_TRUE(IsAtLeastOS10_11());
- EXPECT_FALSE(IsOS10_12());
- EXPECT_FALSE(IsAtLeastOS10_12());
- EXPECT_TRUE(IsAtMostOS10_12());
- EXPECT_FALSE(IsOS10_13());
- EXPECT_FALSE(IsAtLeastOS10_13());
- EXPECT_TRUE(IsAtMostOS10_13());
- EXPECT_FALSE(IsOSLaterThan10_13_DontCallThis());
- } else if (minor == 12) {
- EXPECT_FALSE(IsOS10_9());
- EXPECT_FALSE(IsAtMostOS10_9());
- EXPECT_TRUE(IsAtLeastOS10_9());
- EXPECT_FALSE(IsOS10_10());
- EXPECT_FALSE(IsAtMostOS10_10());
- EXPECT_TRUE(IsAtLeastOS10_10());
- EXPECT_FALSE(IsOS10_11());
- EXPECT_FALSE(IsAtMostOS10_11());
- EXPECT_TRUE(IsAtLeastOS10_11());
- EXPECT_TRUE(IsOS10_12());
- EXPECT_TRUE(IsAtMostOS10_12());
- EXPECT_TRUE(IsAtLeastOS10_12());
- EXPECT_FALSE(IsOS10_13());
- EXPECT_FALSE(IsAtLeastOS10_13());
- EXPECT_TRUE(IsAtMostOS10_13());
- EXPECT_FALSE(IsOSLaterThan10_13_DontCallThis());
- } else if (minor == 13) {
- EXPECT_FALSE(IsOS10_9());
- EXPECT_FALSE(IsAtMostOS10_9());
- EXPECT_TRUE(IsAtLeastOS10_9());
- EXPECT_FALSE(IsOS10_10());
- EXPECT_FALSE(IsAtMostOS10_10());
- EXPECT_TRUE(IsAtLeastOS10_10());
- EXPECT_FALSE(IsOS10_11());
- EXPECT_FALSE(IsAtMostOS10_11());
- EXPECT_TRUE(IsAtLeastOS10_11());
- EXPECT_FALSE(IsOS10_12());
- EXPECT_FALSE(IsAtMostOS10_12());
- EXPECT_TRUE(IsAtLeastOS10_12());
- EXPECT_TRUE(IsOS10_13());
- EXPECT_TRUE(IsAtLeastOS10_13());
- EXPECT_TRUE(IsAtMostOS10_13());
- EXPECT_FALSE(IsOSLaterThan10_13_DontCallThis());
- } else {
- // Not nine, ten, eleven, twelve, or thirteen. Ah, ah, ah.
- EXPECT_TRUE(false);
- }
- } else {
- // Not ten. What you gonna do?
- EXPECT_FALSE(true);
- }
-}
-
-TEST_F(MacUtilTest, ParseModelIdentifier) {
- std::string model;
- int32_t major = 1, minor = 2;
-
- EXPECT_FALSE(ParseModelIdentifier("", &model, &major, &minor));
- EXPECT_EQ(0U, model.length());
- EXPECT_EQ(1, major);
- EXPECT_EQ(2, minor);
- EXPECT_FALSE(ParseModelIdentifier("FooBar", &model, &major, &minor));
-
- EXPECT_TRUE(ParseModelIdentifier("MacPro4,1", &model, &major, &minor));
- EXPECT_EQ(model, "MacPro");
- EXPECT_EQ(4, major);
- EXPECT_EQ(1, minor);
-
- EXPECT_TRUE(ParseModelIdentifier("MacBookPro6,2", &model, &major, &minor));
- EXPECT_EQ(model, "MacBookPro");
- EXPECT_EQ(6, major);
- EXPECT_EQ(2, minor);
-}
-
-TEST_F(MacUtilTest, TestRemoveQuarantineAttribute) {
- ScopedTempDir temp_dir_;
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- FilePath dummy_folder_path = temp_dir_.GetPath().Append("DummyFolder");
- ASSERT_TRUE(base::CreateDirectory(dummy_folder_path));
- const char* quarantine_str = "0000;4b392bb2;Chromium;|org.chromium.Chromium";
- const char* file_path_str = dummy_folder_path.value().c_str();
- EXPECT_EQ(0, setxattr(file_path_str, "com.apple.quarantine",
- quarantine_str, strlen(quarantine_str), 0, 0));
- EXPECT_EQ(static_cast<long>(strlen(quarantine_str)),
- getxattr(file_path_str, "com.apple.quarantine",
- NULL, 0, 0, 0));
- EXPECT_TRUE(RemoveQuarantineAttribute(dummy_folder_path));
- EXPECT_EQ(-1, getxattr(file_path_str, "com.apple.quarantine", NULL, 0, 0, 0));
- EXPECT_EQ(ENOATTR, errno);
-}
-
-TEST_F(MacUtilTest, TestRemoveQuarantineAttributeTwice) {
- ScopedTempDir temp_dir_;
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- FilePath dummy_folder_path = temp_dir_.GetPath().Append("DummyFolder");
- const char* file_path_str = dummy_folder_path.value().c_str();
- ASSERT_TRUE(base::CreateDirectory(dummy_folder_path));
- EXPECT_EQ(-1, getxattr(file_path_str, "com.apple.quarantine", NULL, 0, 0, 0));
- // No quarantine attribute to begin with, but RemoveQuarantineAttribute still
- // succeeds because in the end the folder still doesn't have the quarantine
- // attribute set.
- EXPECT_TRUE(RemoveQuarantineAttribute(dummy_folder_path));
- EXPECT_TRUE(RemoveQuarantineAttribute(dummy_folder_path));
- EXPECT_EQ(ENOATTR, errno);
-}
-
-TEST_F(MacUtilTest, TestRemoveQuarantineAttributeNonExistentPath) {
- ScopedTempDir temp_dir_;
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- FilePath non_existent_path = temp_dir_.GetPath().Append("DummyPath");
- ASSERT_FALSE(PathExists(non_existent_path));
- EXPECT_FALSE(RemoveQuarantineAttribute(non_existent_path));
-}
-
-} // namespace
-
-} // namespace mac
-} // namespace base
diff --git a/base/mac/objc_release_properties_unittest.mm b/base/mac/objc_release_properties_unittest.mm
deleted file mode 100644
index 2d90127..0000000
--- a/base/mac/objc_release_properties_unittest.mm
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright 2016 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 "base/mac/objc_release_properties.h"
-#include "base/stl_util.h"
-
-#import "base/mac/scoped_nsautorelease_pool.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#import <objc/runtime.h>
-
-// "When I'm alone, I count myself."
-// --Count von Count, http://www.youtube.com/watch?v=FKzszqa9WA4
-
-namespace {
-
-// The number of CountVonCounts outstanding.
-int ah_ah_ah;
-
-// NumberHolder exists to exercise the property attribute string parser by
-// providing a named struct and an anonymous union.
-struct NumberHolder {
- union {
- long long sixty_four;
- int thirty_two;
- short sixteen;
- char eight;
- } what;
- enum { SIXTY_FOUR, THIRTY_TWO, SIXTEEN, EIGHT } how;
-};
-
-} // namespace
-
-@interface CountVonCount : NSObject<NSCopying>
-
-+ (CountVonCount*)countVonCount;
-
-@end // @interface CountVonCount
-
-@implementation CountVonCount
-
-+ (CountVonCount*)countVonCount {
- return [[[CountVonCount alloc] init] autorelease];
-}
-
-- (id)init {
- ++ah_ah_ah;
- return [super init];
-}
-
-- (void)dealloc {
- --ah_ah_ah;
- [super dealloc];
-}
-
-- (id)copyWithZone:(NSZone*)zone {
- return [[CountVonCount allocWithZone:zone] init];
-}
-
-@end // @implementation CountVonCount
-
-@interface ObjCPropertyTestBase : NSObject {
- @private
- CountVonCount* baseCvcRetain_;
- CountVonCount* baseCvcCopy_;
- CountVonCount* baseCvcAssign_;
- CountVonCount* baseCvcNotProperty_;
- CountVonCount* baseCvcNil_;
- CountVonCount* baseCvcCustom_;
- int baseInt_;
- double baseDouble_;
- void* basePointer_;
- NumberHolder baseStruct_;
-}
-
-@property(retain, nonatomic) CountVonCount* baseCvcRetain;
-@property(copy, nonatomic) CountVonCount* baseCvcCopy;
-@property(assign, nonatomic) CountVonCount* baseCvcAssign;
-@property(retain, nonatomic) CountVonCount* baseCvcNil;
-@property(retain, nonatomic, getter=baseCustom, setter=setBaseCustom:)
- CountVonCount* baseCvcCustom;
-@property(readonly, retain, nonatomic) CountVonCount* baseCvcReadOnly;
-@property(retain, nonatomic) CountVonCount* baseCvcDynamic;
-@property(assign, nonatomic) int baseInt;
-@property(assign, nonatomic) double baseDouble;
-@property(assign, nonatomic) void* basePointer;
-@property(assign, nonatomic) NumberHolder baseStruct;
-
-- (void)setBaseCvcNotProperty:(CountVonCount*)cvc;
-
-@end // @interface ObjCPropertyTestBase
-
-@implementation ObjCPropertyTestBase
-
-@synthesize baseCvcRetain = baseCvcRetain_;
-@synthesize baseCvcCopy = baseCvcCopy_;
-@synthesize baseCvcAssign = baseCvcAssign_;
-@synthesize baseCvcNil = baseCvcNil_;
-@synthesize baseCvcCustom = baseCvcCustom_;
-@synthesize baseCvcReadOnly = baseCvcReadOnly_;
-@dynamic baseCvcDynamic;
-@synthesize baseInt = baseInt_;
-@synthesize baseDouble = baseDouble_;
-@synthesize basePointer = basePointer_;
-@synthesize baseStruct = baseStruct_;
-
-- (void)dealloc {
- [baseCvcNotProperty_ release];
- base::mac::ReleaseProperties(self);
- [super dealloc];
-}
-
-- (void)setBaseCvcNotProperty:(CountVonCount*)cvc {
- if (cvc != baseCvcNotProperty_) {
- [baseCvcNotProperty_ release];
- baseCvcNotProperty_ = [cvc retain];
- }
-}
-
-- (void)setBaseCvcReadOnlyProperty:(CountVonCount*)cvc {
- if (cvc != baseCvcReadOnly_) {
- [baseCvcReadOnly_ release];
- baseCvcReadOnly_ = [cvc retain];
- }
-}
-
-@end // @implementation ObjCPropertyTestBase
-
-@protocol ObjCPropertyTestProtocol
-
-@property(retain, nonatomic) CountVonCount* protoCvcRetain;
-@property(copy, nonatomic) CountVonCount* protoCvcCopy;
-@property(assign, nonatomic) CountVonCount* protoCvcAssign;
-@property(retain, nonatomic) CountVonCount* protoCvcNil;
-@property(retain, nonatomic, getter=protoCustom, setter=setProtoCustom:)
- CountVonCount* protoCvcCustom;
-@property(retain, nonatomic) CountVonCount* protoCvcDynamic;
-@property(assign, nonatomic) int protoInt;
-@property(assign, nonatomic) double protoDouble;
-@property(assign, nonatomic) void* protoPointer;
-@property(assign, nonatomic) NumberHolder protoStruct;
-
-@end // @protocol ObjCPropertyTestProtocol
-
-// @protocol(NSObject) declares some (copy, readonly) properties (superclass,
-// description, debugDescription, and hash), but we're not expected to release
-// them. The current implementation only releases properties backed by instance
-// variables, and this makes sure that doesn't change in a breaking way.
-@interface ObjCPropertyTestDerived
- : ObjCPropertyTestBase<ObjCPropertyTestProtocol, NSObject> {
- @private
- CountVonCount* derivedCvcRetain_;
- CountVonCount* derivedCvcCopy_;
- CountVonCount* derivedCvcAssign_;
- CountVonCount* derivedCvcNotProperty_;
- CountVonCount* derivedCvcNil_;
- CountVonCount* derivedCvcCustom_;
- int derivedInt_;
- double derivedDouble_;
- void* derivedPointer_;
- NumberHolder derivedStruct_;
-
- CountVonCount* protoCvcRetain_;
- CountVonCount* protoCvcCopy_;
- CountVonCount* protoCvcAssign_;
- CountVonCount* protoCvcNil_;
- CountVonCount* protoCvcCustom_;
- int protoInt_;
- double protoDouble_;
- void* protoPointer_;
- NumberHolder protoStruct_;
-}
-
-@property(retain, nonatomic) CountVonCount* derivedCvcRetain;
-@property(copy, nonatomic) CountVonCount* derivedCvcCopy;
-@property(assign, nonatomic) CountVonCount* derivedCvcAssign;
-@property(retain, nonatomic) CountVonCount* derivedCvcNil;
-@property(retain, nonatomic, getter=derivedCustom, setter=setDerivedCustom:)
- CountVonCount* derivedCvcCustom;
-@property(retain, nonatomic) CountVonCount* derivedCvcDynamic;
-@property(assign, nonatomic) int derivedInt;
-@property(assign, nonatomic) double derivedDouble;
-@property(assign, nonatomic) void* derivedPointer;
-@property(assign, nonatomic) NumberHolder derivedStruct;
-
-- (void)setDerivedCvcNotProperty:(CountVonCount*)cvc;
-
-@end // @interface ObjCPropertyTestDerived
-
-@implementation ObjCPropertyTestDerived
-
-@synthesize derivedCvcRetain = derivedCvcRetain_;
-@synthesize derivedCvcCopy = derivedCvcCopy_;
-@synthesize derivedCvcAssign = derivedCvcAssign_;
-@synthesize derivedCvcNil = derivedCvcNil_;
-@synthesize derivedCvcCustom = derivedCvcCustom_;
-@dynamic derivedCvcDynamic;
-@synthesize derivedInt = derivedInt_;
-@synthesize derivedDouble = derivedDouble_;
-@synthesize derivedPointer = derivedPointer_;
-@synthesize derivedStruct = derivedStruct_;
-
-@synthesize protoCvcRetain = protoCvcRetain_;
-@synthesize protoCvcCopy = protoCvcCopy_;
-@synthesize protoCvcAssign = protoCvcAssign_;
-@synthesize protoCvcNil = protoCvcNil_;
-@synthesize protoCvcCustom = protoCvcCustom_;
-@dynamic protoCvcDynamic;
-@synthesize protoInt = protoInt_;
-@synthesize protoDouble = protoDouble_;
-@synthesize protoPointer = protoPointer_;
-@synthesize protoStruct = protoStruct_;
-
-+ (BOOL)resolveInstanceMethod:(SEL)sel {
- static const std::vector<SEL> dynamicMethods {
- @selector(baseCvcDynamic), @selector(derivedCvcDynamic),
- @selector(protoCvcDynamic),
- };
- if (!base::ContainsValue(dynamicMethods, sel)) {
- return NO;
- }
- id (*imp)() = []() -> id { return nil; };
- class_addMethod([self class], sel, reinterpret_cast<IMP>(imp), "@@:");
- return YES;
-}
-
-- (void)dealloc {
- base::mac::ReleaseProperties(self);
- [derivedCvcNotProperty_ release];
- [super dealloc];
-}
-
-- (void)setDerivedCvcNotProperty:(CountVonCount*)cvc {
- if (cvc != derivedCvcNotProperty_) {
- [derivedCvcNotProperty_ release];
- derivedCvcNotProperty_ = [cvc retain];
- }
-}
-
-@end // @implementation ObjCPropertyTestDerived
-
-@interface ObjcPropertyTestEmpty : NSObject
-@end
-
-@implementation ObjcPropertyTestEmpty
-
-- (void)dealloc {
- base::mac::ReleaseProperties(self);
- [super dealloc];
-}
-
-@end // @implementation ObjcPropertyTestEmpty
-
-namespace {
-
-TEST(ObjCReleasePropertiesTest, SesameStreet) {
- ObjCPropertyTestDerived* test_object = [[ObjCPropertyTestDerived alloc] init];
-
- // Assure a clean slate.
- EXPECT_EQ(0, ah_ah_ah);
- EXPECT_EQ(1U, [test_object retainCount]);
-
- CountVonCount* baseAssign = [[CountVonCount alloc] init];
- CountVonCount* derivedAssign = [[CountVonCount alloc] init];
- CountVonCount* protoAssign = [[CountVonCount alloc] init];
-
- // Make sure that worked before things get more involved.
- EXPECT_EQ(3, ah_ah_ah);
-
- {
- base::mac::ScopedNSAutoreleasePool pool;
-
- test_object.baseCvcRetain = [CountVonCount countVonCount];
- test_object.baseCvcCopy = [CountVonCount countVonCount];
- test_object.baseCvcAssign = baseAssign;
- test_object.baseCvcCustom = [CountVonCount countVonCount];
- [test_object setBaseCvcReadOnlyProperty:[CountVonCount countVonCount]];
- [test_object setBaseCvcNotProperty:[CountVonCount countVonCount]];
-
- // That added 5 objects, plus 1 more that was copied.
- EXPECT_EQ(9, ah_ah_ah);
-
- test_object.derivedCvcRetain = [CountVonCount countVonCount];
- test_object.derivedCvcCopy = [CountVonCount countVonCount];
- test_object.derivedCvcAssign = derivedAssign;
- test_object.derivedCvcCustom = [CountVonCount countVonCount];
- [test_object setDerivedCvcNotProperty:[CountVonCount countVonCount]];
-
- // That added 4 objects, plus 1 more that was copied.
- EXPECT_EQ(14, ah_ah_ah);
-
- test_object.protoCvcRetain = [CountVonCount countVonCount];
- test_object.protoCvcCopy = [CountVonCount countVonCount];
- test_object.protoCvcAssign = protoAssign;
- test_object.protoCvcCustom = [CountVonCount countVonCount];
-
- // That added 3 objects, plus 1 more that was copied.
- EXPECT_EQ(18, ah_ah_ah);
- }
-
- // Now that the autorelease pool has been popped, the 3 objects that were
- // copied when placed into the test object will have been deallocated.
- EXPECT_EQ(15, ah_ah_ah);
-
- // Make sure that the setters wo/rk and have the expected semantics.
- test_object.baseCvcRetain = nil;
- test_object.baseCvcCopy = nil;
- test_object.baseCvcAssign = nil;
- test_object.baseCvcCustom = nil;
- test_object.derivedCvcRetain = nil;
- test_object.derivedCvcCopy = nil;
- test_object.derivedCvcAssign = nil;
- test_object.derivedCvcCustom = nil;
- test_object.protoCvcRetain = nil;
- test_object.protoCvcCopy = nil;
- test_object.protoCvcAssign = nil;
- test_object.protoCvcCustom = nil;
-
- // The CountVonCounts marked "retain" and "copy" should have been
- // deallocated. Those marked assign should not have been. The only ones that
- // should exist now are the ones marked "assign", the ones held in
- // non-property instance variables, and the ones held in properties marked
- // readonly.
- EXPECT_EQ(6, ah_ah_ah);
-
- {
- base::mac::ScopedNSAutoreleasePool pool;
-
- // Put things back to how they were.
- test_object.baseCvcRetain = [CountVonCount countVonCount];
- test_object.baseCvcCopy = [CountVonCount countVonCount];
- test_object.baseCvcAssign = baseAssign;
- test_object.baseCvcCustom = [CountVonCount countVonCount];
- test_object.derivedCvcRetain = [CountVonCount countVonCount];
- test_object.derivedCvcCopy = [CountVonCount countVonCount];
- test_object.derivedCvcAssign = derivedAssign;
- test_object.derivedCvcCustom = [CountVonCount countVonCount];
- test_object.protoCvcRetain = [CountVonCount countVonCount];
- test_object.protoCvcCopy = [CountVonCount countVonCount];
- test_object.protoCvcAssign = protoAssign;
- test_object.protoCvcCustom = [CountVonCount countVonCount];
-
- // 9 more CountVonCounts, 3 of which were copied.
- EXPECT_EQ(18, ah_ah_ah);
- }
-
- // Now that the autorelease pool has been popped, the 3 copies are gone.
- EXPECT_EQ(15, ah_ah_ah);
-
- // Releasing the test object should get rid of everything that it owns.
- [test_object release];
-
- // base::mac::ReleaseProperties(self) should have released all of the
- // CountVonCounts associated with properties marked "retain" or "copy". The
- // -dealloc methods in each should have released the single non-property
- // objects in each. Only the CountVonCounts assigned to the properties marked
- // "assign" should remain.
- EXPECT_EQ(3, ah_ah_ah);
-
- [baseAssign release];
- [derivedAssign release];
- [protoAssign release];
-
- // Zero! Zero counts! Ah, ah, ah.
- EXPECT_EQ(0, ah_ah_ah);
-}
-
-TEST(ObjCReleasePropertiesTest, EmptyObject) {
- // Test that ReleaseProperties doesn't do anything unexpected to a class
- // with no properties.
- [[[ObjcPropertyTestEmpty alloc] init] release];
-}
-
-} // namespace
diff --git a/base/mac/scoped_nsobject_unittest.mm b/base/mac/scoped_nsobject_unittest.mm
deleted file mode 100644
index 72d5242..0000000
--- a/base/mac/scoped_nsobject_unittest.mm
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012 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 <vector>
-
-#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/mac/scoped_nsobject.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-TEST(ScopedNSObjectTest, ScopedNSObject) {
- base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
- ASSERT_TRUE(p1.get());
- ASSERT_EQ(1u, [p1 retainCount]);
- base::scoped_nsobject<NSObject> p2(p1);
- ASSERT_EQ(p1.get(), p2.get());
- ASSERT_EQ(2u, [p1 retainCount]);
- p2.reset();
- ASSERT_EQ(nil, p2.get());
- ASSERT_EQ(1u, [p1 retainCount]);
- {
- base::scoped_nsobject<NSObject> p3 = p1;
- ASSERT_EQ(p1.get(), p3.get());
- ASSERT_EQ(2u, [p1 retainCount]);
- {
- base::mac::ScopedNSAutoreleasePool pool;
- p3 = p1;
- }
- ASSERT_EQ(p1.get(), p3.get());
- ASSERT_EQ(2u, [p1 retainCount]);
- }
- ASSERT_EQ(1u, [p1 retainCount]);
- base::scoped_nsobject<NSObject> p4([p1.get() retain]);
- ASSERT_EQ(2u, [p1 retainCount]);
- ASSERT_TRUE(p1 == p1.get());
- ASSERT_TRUE(p1 == p1);
- ASSERT_FALSE(p1 != p1);
- ASSERT_FALSE(p1 != p1.get());
- base::scoped_nsobject<NSObject> p5([[NSObject alloc] init]);
- ASSERT_TRUE(p1 != p5);
- ASSERT_TRUE(p1 != p5.get());
- ASSERT_FALSE(p1 == p5);
- ASSERT_FALSE(p1 == p5.get());
-
- base::scoped_nsobject<NSObject> p6 = p1;
- ASSERT_EQ(3u, [p6 retainCount]);
- {
- base::mac::ScopedNSAutoreleasePool pool;
- p6.autorelease();
- ASSERT_EQ(nil, p6.get());
- ASSERT_EQ(3u, [p1 retainCount]);
- }
- ASSERT_EQ(2u, [p1 retainCount]);
-
- base::scoped_nsobject<NSObject> p7([NSObject new]);
- base::scoped_nsobject<NSObject> p8(std::move(p7));
- ASSERT_TRUE(p8);
- ASSERT_EQ(1u, [p8 retainCount]);
- ASSERT_FALSE(p7.get());
-}
-
-// Instantiating scoped_nsobject<> with T=NSAutoreleasePool should trip a
-// static_assert.
-#if 0
-TEST(ScopedNSObjectTest, FailToCreateScopedNSObjectAutoreleasePool) {
- base::scoped_nsobject<NSAutoreleasePool> pool;
-}
-#endif
-
-TEST(ScopedNSObjectTest, ScopedNSObjectInContainer) {
- base::scoped_nsobject<id> p([[NSObject alloc] init]);
- ASSERT_TRUE(p.get());
- ASSERT_EQ(1u, [p retainCount]);
- {
- std::vector<base::scoped_nsobject<id>> objects;
- objects.push_back(p);
- ASSERT_EQ(2u, [p retainCount]);
- ASSERT_EQ(p.get(), objects[0].get());
- objects.push_back(base::scoped_nsobject<id>([[NSObject alloc] init]));
- ASSERT_TRUE(objects[1].get());
- ASSERT_EQ(1u, [objects[1] retainCount]);
- }
- ASSERT_EQ(1u, [p retainCount]);
-}
-
-TEST(ScopedNSObjectTest, ScopedNSObjectFreeFunctions) {
- base::scoped_nsobject<id> p1([[NSObject alloc] init]);
- id o1 = p1.get();
- ASSERT_TRUE(o1 == p1);
- ASSERT_FALSE(o1 != p1);
- base::scoped_nsobject<id> p2([[NSObject alloc] init]);
- ASSERT_TRUE(o1 != p2);
- ASSERT_FALSE(o1 == p2);
- id o2 = p2.get();
- swap(p1, p2);
- ASSERT_EQ(o2, p1.get());
- ASSERT_EQ(o1, p2.get());
-}
-
-} // namespace
diff --git a/base/mac/scoped_nsobject_unittest_arc.mm b/base/mac/scoped_nsobject_unittest_arc.mm
deleted file mode 100644
index 5cbf3f8..0000000
--- a/base/mac/scoped_nsobject_unittest_arc.mm
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2012 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 <vector>
-
-#import <CoreFoundation/CoreFoundation.h>
-
-#include "base/logging.h"
-#import "base/mac/scoped_nsobject.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-template <typename NST>
-CFIndex GetRetainCount(const base::scoped_nsobject<NST>& nst) {
- @autoreleasepool {
- return CFGetRetainCount((__bridge CFTypeRef)nst.get()) - 1;
- }
-}
-
-#if __has_feature(objc_arc_weak)
-TEST(ScopedNSObjectTestARC, DefaultPolicyIsRetain) {
- __weak id o;
- @autoreleasepool {
- base::scoped_nsprotocol<id> p([[NSObject alloc] init]);
- o = p.get();
- DCHECK_EQ(o, p.get());
- }
- DCHECK_EQ(o, nil);
-}
-#endif
-
-TEST(ScopedNSObjectTestARC, ScopedNSObject) {
- base::scoped_nsobject<NSObject> p1([[NSObject alloc] init]);
- @autoreleasepool {
- EXPECT_TRUE(p1.get());
- EXPECT_TRUE(p1.get());
- }
- EXPECT_EQ(1, GetRetainCount(p1));
- EXPECT_EQ(1, GetRetainCount(p1));
- base::scoped_nsobject<NSObject> p2(p1);
- @autoreleasepool {
- EXPECT_EQ(p1.get(), p2.get());
- }
- EXPECT_EQ(2, GetRetainCount(p1));
- p2.reset();
- EXPECT_EQ(nil, p2.get());
- EXPECT_EQ(1, GetRetainCount(p1));
- {
- base::scoped_nsobject<NSObject> p3 = p1;
- @autoreleasepool {
- EXPECT_EQ(p1.get(), p3.get());
- }
- EXPECT_EQ(2, GetRetainCount(p1));
- @autoreleasepool {
- p3 = p1;
- EXPECT_EQ(p1.get(), p3.get());
- }
- EXPECT_EQ(2, GetRetainCount(p1));
- }
- EXPECT_EQ(1, GetRetainCount(p1));
- base::scoped_nsobject<NSObject> p4;
- @autoreleasepool {
- p4 = base::scoped_nsobject<NSObject>(p1.get());
- }
- EXPECT_EQ(2, GetRetainCount(p1));
- @autoreleasepool {
- EXPECT_TRUE(p1 == p1.get());
- EXPECT_TRUE(p1 == p1);
- EXPECT_FALSE(p1 != p1);
- EXPECT_FALSE(p1 != p1.get());
- }
- base::scoped_nsobject<NSObject> p5([[NSObject alloc] init]);
- @autoreleasepool {
- EXPECT_TRUE(p1 != p5);
- EXPECT_TRUE(p1 != p5.get());
- EXPECT_FALSE(p1 == p5);
- EXPECT_FALSE(p1 == p5.get());
- }
-
- base::scoped_nsobject<NSObject> p6 = p1;
- EXPECT_EQ(3, GetRetainCount(p6));
- @autoreleasepool {
- p6.autorelease();
- EXPECT_EQ(nil, p6.get());
- }
- EXPECT_EQ(2, GetRetainCount(p1));
-}
-
-TEST(ScopedNSObjectTestARC, ScopedNSObjectInContainer) {
- base::scoped_nsobject<id> p([[NSObject alloc] init]);
- @autoreleasepool {
- EXPECT_TRUE(p.get());
- }
- EXPECT_EQ(1, GetRetainCount(p));
- @autoreleasepool {
- std::vector<base::scoped_nsobject<id>> objects;
- objects.push_back(p);
- EXPECT_EQ(2, GetRetainCount(p));
- @autoreleasepool {
- EXPECT_EQ(p.get(), objects[0].get());
- }
- objects.push_back(base::scoped_nsobject<id>([[NSObject alloc] init]));
- @autoreleasepool {
- EXPECT_TRUE(objects[1].get());
- }
- EXPECT_EQ(1, GetRetainCount(objects[1]));
- }
- EXPECT_EQ(1, GetRetainCount(p));
-}
-
-TEST(ScopedNSObjectTestARC, ScopedNSObjectFreeFunctions) {
- base::scoped_nsobject<id> p1([[NSObject alloc] init]);
- id o1 = p1.get();
- EXPECT_TRUE(o1 == p1);
- EXPECT_FALSE(o1 != p1);
- base::scoped_nsobject<id> p2([[NSObject alloc] init]);
- EXPECT_TRUE(o1 != p2);
- EXPECT_FALSE(o1 == p2);
- id o2 = p2.get();
- swap(p1, p2);
- EXPECT_EQ(o2, p1.get());
- EXPECT_EQ(o1, p2.get());
-}
-
-} // namespace
diff --git a/base/mac/scoped_objc_class_swizzler_unittest.mm b/base/mac/scoped_objc_class_swizzler_unittest.mm
deleted file mode 100644
index 79820a3..0000000
--- a/base/mac/scoped_objc_class_swizzler_unittest.mm
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2014 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.
-
-#import "base/mac/scoped_objc_class_swizzler.h"
-
-#import "base/mac/scoped_nsobject.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-@interface ObjCClassSwizzlerTestOne : NSObject
-+ (NSInteger)function;
-- (NSInteger)method;
-- (NSInteger)modifier;
-@end
-
-@interface ObjCClassSwizzlerTestTwo : NSObject
-+ (NSInteger)function;
-- (NSInteger)method;
-- (NSInteger)modifier;
-@end
-
-@implementation ObjCClassSwizzlerTestOne : NSObject
-
-+ (NSInteger)function {
- return 10;
-}
-
-- (NSInteger)method {
- // Multiply by a modifier to ensure |self| in a swizzled implementation
- // refers to the original object.
- return 1 * [self modifier];
-}
-
-- (NSInteger)modifier {
- return 3;
-}
-
-@end
-
-@implementation ObjCClassSwizzlerTestTwo : NSObject
-
-+ (NSInteger)function {
- return 20;
-}
-
-- (NSInteger)method {
- return 2 * [self modifier];
-}
-
-- (NSInteger)modifier {
- return 7;
-}
-
-@end
-
-@interface ObjCClassSwizzlerTestOne (AlternateCategory)
-- (NSInteger)alternate;
-@end
-
-@implementation ObjCClassSwizzlerTestOne (AlternateCategory)
-- (NSInteger)alternate {
- return 3 * [self modifier];
-}
-@end
-
-@interface ObjCClassSwizzlerTestOneChild : ObjCClassSwizzlerTestOne
-- (NSInteger)childAlternate;
-@end
-
-@implementation ObjCClassSwizzlerTestOneChild
-- (NSInteger)childAlternate {
- return 5 * [self modifier];
-}
-@end
-
-namespace base {
-namespace mac {
-
-TEST(ObjCClassSwizzlerTest, SwizzleInstanceMethods) {
- base::scoped_nsobject<ObjCClassSwizzlerTestOne> object_one(
- [[ObjCClassSwizzlerTestOne alloc] init]);
- base::scoped_nsobject<ObjCClassSwizzlerTestTwo> object_two(
- [[ObjCClassSwizzlerTestTwo alloc] init]);
- EXPECT_EQ(3, [object_one method]);
- EXPECT_EQ(14, [object_two method]);
-
- {
- base::mac::ScopedObjCClassSwizzler swizzler(
- [ObjCClassSwizzlerTestOne class],
- [ObjCClassSwizzlerTestTwo class],
- @selector(method));
- EXPECT_EQ(6, [object_one method]);
- EXPECT_EQ(7, [object_two method]);
-
- IMP original = swizzler.GetOriginalImplementation();
- id expected_result = reinterpret_cast<id>(3);
- EXPECT_EQ(expected_result, original(object_one, @selector(method)));
- }
-
- EXPECT_EQ(3, [object_one method]);
- EXPECT_EQ(14, [object_two method]);
-}
-
-TEST(ObjCClassSwizzlerTest, SwizzleClassMethods) {
- EXPECT_EQ(10, [ObjCClassSwizzlerTestOne function]);
- EXPECT_EQ(20, [ObjCClassSwizzlerTestTwo function]);
-
- {
- base::mac::ScopedObjCClassSwizzler swizzler(
- [ObjCClassSwizzlerTestOne class],
- [ObjCClassSwizzlerTestTwo class],
- @selector(function));
- EXPECT_EQ(20, [ObjCClassSwizzlerTestOne function]);
- EXPECT_EQ(10, [ObjCClassSwizzlerTestTwo function]);
-
- IMP original = swizzler.GetOriginalImplementation();
- id expected_result = reinterpret_cast<id>(10);
- EXPECT_EQ(expected_result,
- original([ObjCClassSwizzlerTestOne class], @selector(function)));
- }
-
- EXPECT_EQ(10, [ObjCClassSwizzlerTestOne function]);
- EXPECT_EQ(20, [ObjCClassSwizzlerTestTwo function]);
-}
-
-TEST(ObjCClassSwizzlerTest, SwizzleViaCategory) {
- base::scoped_nsobject<ObjCClassSwizzlerTestOne> object_one(
- [[ObjCClassSwizzlerTestOne alloc] init]);
- EXPECT_EQ(3, [object_one method]);
-
- {
- base::mac::ScopedObjCClassSwizzler swizzler(
- [ObjCClassSwizzlerTestOne class],
- @selector(method),
- @selector(alternate));
- EXPECT_EQ(9, [object_one method]);
-
- IMP original = swizzler.GetOriginalImplementation();
- id expected_result = reinterpret_cast<id>(3);
- EXPECT_EQ(expected_result, original(object_one, @selector(method)));
- }
-
- EXPECT_EQ(3, [object_one method]);
-}
-
-TEST(ObjCClassSwizzlerTest, SwizzleViaInheritance) {
- base::scoped_nsobject<ObjCClassSwizzlerTestOneChild> child(
- [[ObjCClassSwizzlerTestOneChild alloc] init]);
- EXPECT_EQ(3, [child method]);
-
- {
- base::mac::ScopedObjCClassSwizzler swizzler(
- [ObjCClassSwizzlerTestOneChild class],
- @selector(method),
- @selector(childAlternate));
- EXPECT_EQ(15, [child method]);
-
- IMP original = swizzler.GetOriginalImplementation();
- id expected_result = reinterpret_cast<id>(3);
- EXPECT_EQ(expected_result, original(child, @selector(method)));
- }
-
- EXPECT_EQ(3, [child method]);
-}
-
-} // namespace mac
-} // namespace base
diff --git a/base/mac/scoped_sending_event_unittest.mm b/base/mac/scoped_sending_event_unittest.mm
deleted file mode 100644
index 52f18c6..0000000
--- a/base/mac/scoped_sending_event_unittest.mm
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-
-#import "base/mac/scoped_sending_event.h"
-
-#import <Foundation/Foundation.h>
-
-#include "base/mac/scoped_nsobject.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-@interface ScopedSendingEventTestCrApp : NSApplication <CrAppControlProtocol> {
- @private
- BOOL handlingSendEvent_;
-}
-@property(nonatomic, assign, getter=isHandlingSendEvent) BOOL handlingSendEvent;
-@end
-
-@implementation ScopedSendingEventTestCrApp
-@synthesize handlingSendEvent = handlingSendEvent_;
-@end
-
-namespace {
-
-class ScopedSendingEventTest : public testing::Test {
- public:
- ScopedSendingEventTest() : app_([[ScopedSendingEventTestCrApp alloc] init]) {
- NSApp = app_.get();
- }
- ~ScopedSendingEventTest() override { NSApp = nil; }
-
- private:
- base::scoped_nsobject<ScopedSendingEventTestCrApp> app_;
-};
-
-// Sets the flag within scope, resets when leaving scope.
-TEST_F(ScopedSendingEventTest, SetHandlingSendEvent) {
- id<CrAppProtocol> app = NSApp;
- EXPECT_FALSE([app isHandlingSendEvent]);
- {
- base::mac::ScopedSendingEvent is_handling_send_event;
- EXPECT_TRUE([app isHandlingSendEvent]);
- }
- EXPECT_FALSE([app isHandlingSendEvent]);
-}
-
-// Nested call restores previous value rather than resetting flag.
-TEST_F(ScopedSendingEventTest, NestedSetHandlingSendEvent) {
- id<CrAppProtocol> app = NSApp;
- EXPECT_FALSE([app isHandlingSendEvent]);
- {
- base::mac::ScopedSendingEvent is_handling_send_event;
- EXPECT_TRUE([app isHandlingSendEvent]);
- {
- base::mac::ScopedSendingEvent nested_is_handling_send_event;
- EXPECT_TRUE([app isHandlingSendEvent]);
- }
- EXPECT_TRUE([app isHandlingSendEvent]);
- }
- EXPECT_FALSE([app isHandlingSendEvent]);
-}
-
-} // namespace
diff --git a/base/process/launch.cc b/base/process/launch.cc
deleted file mode 100644
index dbb8447..0000000
--- a/base/process/launch.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2013 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 "base/process/launch.h"
-#include "build_config.h"
-
-namespace base {
-
-LaunchOptions::LaunchOptions() = default;
-
-LaunchOptions::LaunchOptions(const LaunchOptions& other) = default;
-
-LaunchOptions::~LaunchOptions() = default;
-
-LaunchOptions LaunchOptionsForTest() {
- LaunchOptions options;
-#if defined(OS_LINUX)
- // To prevent accidental privilege sharing to an untrusted child, processes
- // are started with PR_SET_NO_NEW_PRIVS. Do not set that here, since this
- // new child will be used for testing only.
- options.allow_new_privs = true;
-#endif
- return options;
-}
-
-} // namespace base
diff --git a/base/process/launch.h b/base/process/launch.h
deleted file mode 100644
index eb53c0f..0000000
--- a/base/process/launch.h
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2013 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.
-
-// This file contains functions for launching subprocesses.
-
-#ifndef BASE_PROCESS_LAUNCH_H_
-#define BASE_PROCESS_LAUNCH_H_
-
-#include <stddef.h>
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/environment.h"
-#include "base/macros.h"
-#include "base/process/process.h"
-#include "base/process/process_handle.h"
-#include "base/strings/string_piece.h"
-#include "build_config.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#endif
-
-#if defined(OS_POSIX)
-#include "base/posix/file_descriptor_shuffle.h"
-#endif
-
-namespace base {
-
-class CommandLine;
-
-#if defined(OS_WIN)
-typedef std::vector<HANDLE> HandlesToInheritVector;
-#elif defined(OS_POSIX)
-typedef std::vector<std::pair<int, int>> FileHandleMappingVector;
-#endif // defined(OS_WIN)
-
-// Options for launching a subprocess that are passed to LaunchProcess().
-// The default constructor constructs the object with default options.
-struct BASE_EXPORT LaunchOptions {
-#if defined(OS_POSIX)
- // Delegate to be run in between fork and exec in the subprocess (see
- // pre_exec_delegate below)
- class BASE_EXPORT PreExecDelegate {
- public:
- PreExecDelegate() = default;
- virtual ~PreExecDelegate() = default;
-
- // Since this is to be run between fork and exec, and fork may have happened
- // while multiple threads were running, this function needs to be async
- // safe.
- virtual void RunAsyncSafe() = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PreExecDelegate);
- };
-#endif // defined(OS_POSIX)
-
- LaunchOptions();
- LaunchOptions(const LaunchOptions&);
- ~LaunchOptions();
-
- // If true, wait for the process to complete.
- bool wait = false;
-
- // If not empty, change to this directory before executing the new process.
- base::FilePath current_directory;
-
-#if defined(OS_WIN)
- bool start_hidden = false;
-
- // Windows can inherit handles when it launches child processes.
- // See https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873
- // for a good overview of Windows handle inheritance.
- //
- // Implementation note: it might be nice to implement in terms of
- // base::Optional<>, but then the natural default state (vector not present)
- // would be "all inheritable handles" while we want "no inheritance."
- enum class Inherit {
- // Only those handles in |handles_to_inherit| vector are inherited. If the
- // vector is empty, no handles are inherited. The handles in the vector must
- // all be inheritable.
- kSpecific,
-
- // All handles in the current process which are inheritable are inherited.
- // In production code this flag should be used only when running
- // short-lived, trusted binaries, because open handles from other libraries
- // and subsystems will leak to the child process, causing errors such as
- // open socket hangs. There are also race conditions that can cause handle
- // over-sharing.
- //
- // |handles_to_inherit| must be null.
- //
- // DEPRECATED. THIS SHOULD NOT BE USED. Explicitly map all handles that
- // need to be shared in new code.
- // TODO(brettw) bug 748258: remove this.
- kAll
- };
- Inherit inherit_mode = Inherit::kSpecific;
- HandlesToInheritVector handles_to_inherit;
-
- // If non-null, runs as if the user represented by the token had launched it.
- // Whether the application is visible on the interactive desktop depends on
- // the token belonging to an interactive logon session.
- //
- // To avoid hard to diagnose problems, when specified this loads the
- // environment variables associated with the user and if this operation fails
- // the entire call fails as well.
- UserTokenHandle as_user = nullptr;
-
- // If true, use an empty string for the desktop name.
- bool empty_desktop_name = false;
-
- // If non-null, launches the application in that job object. The process will
- // be terminated immediately and LaunchProcess() will fail if assignment to
- // the job object fails.
- HANDLE job_handle = nullptr;
-
- // Handles for the redirection of stdin, stdout and stderr. The caller should
- // either set all three of them or none (i.e. there is no way to redirect
- // stderr without redirecting stdin).
- //
- // The handles must be inheritable. Pseudo handles are used when stdout and
- // stderr redirect to the console. In that case, GetFileType() will return
- // FILE_TYPE_CHAR and they're automatically inherited by child processes. See
- // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682075.aspx
- // Otherwise, the caller must ensure that the |inherit_mode| and/or
- // |handles_to_inherit| set so that the handles are inherited.
- HANDLE stdin_handle = nullptr;
- HANDLE stdout_handle = nullptr;
- HANDLE stderr_handle = nullptr;
-
- // If set to true, ensures that the child process is launched with the
- // CREATE_BREAKAWAY_FROM_JOB flag which allows it to breakout of the parent
- // job if any.
- bool force_breakaway_from_job_ = false;
-
- // If set to true, permission to bring windows to the foreground is passed to
- // the launched process if the current process has such permission.
- bool grant_foreground_privilege = false;
-#elif defined(OS_POSIX)
- // Set/unset environment variables. These are applied on top of the parent
- // process environment. Empty (the default) means to inherit the same
- // environment. See AlterEnvironment().
- EnvironmentMap environ;
-
- // Clear the environment for the new process before processing changes from
- // |environ|.
- bool clear_environ = false;
-
- // Remap file descriptors according to the mapping of src_fd->dest_fd to
- // propagate FDs into the child process.
- FileHandleMappingVector fds_to_remap;
-#endif // defined(OS_WIN)
-
-#if defined(OS_LINUX)
- // If non-zero, start the process using clone(), using flags as provided.
- // Unlike in clone, clone_flags may not contain a custom termination signal
- // that is sent to the parent when the child dies. The termination signal will
- // always be set to SIGCHLD.
- int clone_flags = 0;
-
- // By default, child processes will have the PR_SET_NO_NEW_PRIVS bit set. If
- // true, then this bit will not be set in the new child process.
- bool allow_new_privs = false;
-
- // Sets parent process death signal to SIGKILL.
- bool kill_on_parent_death = false;
-#endif // defined(OS_LINUX)
-
-#if defined(OS_POSIX)
- // If not empty, launch the specified executable instead of
- // cmdline.GetProgram(). This is useful when it is necessary to pass a custom
- // argv[0].
- base::FilePath real_path;
-
- // If non-null, a delegate to be run immediately prior to executing the new
- // program in the child process.
- //
- // WARNING: If LaunchProcess is called in the presence of multiple threads,
- // code running in this delegate essentially needs to be async-signal safe
- // (see man 7 signal for a list of allowed functions).
- PreExecDelegate* pre_exec_delegate = nullptr;
-
- // Each element is an RLIMIT_* constant that should be raised to its
- // rlim_max. This pointer is owned by the caller and must live through
- // the call to LaunchProcess().
- const std::vector<int>* maximize_rlimits = nullptr;
-
- // If true, start the process in a new process group, instead of
- // inheriting the parent's process group. The pgid of the child process
- // will be the same as its pid.
- bool new_process_group = false;
-#endif // defined(OS_POSIX)
-};
-
-// Launch a process via the command line |cmdline|.
-// See the documentation of LaunchOptions for details on |options|.
-//
-// Returns a valid Process upon success.
-//
-// Unix-specific notes:
-// - All file descriptors open in the parent process will be closed in the
-// child process except for any preserved by options::fds_to_remap, and
-// stdin, stdout, and stderr. If not remapped by options::fds_to_remap,
-// stdin is reopened as /dev/null, and the child is allowed to inherit its
-// parent's stdout and stderr.
-// - If the first argument on the command line does not contain a slash,
-// PATH will be searched. (See man execvp.)
-BASE_EXPORT Process LaunchProcess(const CommandLine& cmdline,
- const LaunchOptions& options);
-
-#if defined(OS_WIN)
-// Windows-specific LaunchProcess that takes the command line as a
-// string. Useful for situations where you need to control the
-// command line arguments directly, but prefer the CommandLine version
-// if launching Chrome itself.
-//
-// The first command line argument should be the path to the process,
-// and don't forget to quote it.
-//
-// Example (including literal quotes)
-// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
-BASE_EXPORT Process LaunchProcess(const string16& cmdline,
- const LaunchOptions& options);
-
-// Launches a process with elevated privileges. This does not behave exactly
-// like LaunchProcess as it uses ShellExecuteEx instead of CreateProcess to
-// create the process. This means the process will have elevated privileges
-// and thus some common operations like OpenProcess will fail. Currently the
-// only supported LaunchOptions are |start_hidden| and |wait|.
-BASE_EXPORT Process LaunchElevatedProcess(const CommandLine& cmdline,
- const LaunchOptions& options);
-
-#elif defined(OS_POSIX)
-// A POSIX-specific version of LaunchProcess that takes an argv array
-// instead of a CommandLine. Useful for situations where you need to
-// control the command line arguments directly, but prefer the
-// CommandLine version if launching Chrome itself.
-BASE_EXPORT Process LaunchProcess(const std::vector<std::string>& argv,
- const LaunchOptions& options);
-
-// Close all file descriptors, except those which are a destination in the
-// given multimap. Only call this function in a child process where you know
-// that there aren't any other threads.
-BASE_EXPORT void CloseSuperfluousFds(const InjectiveMultimap& saved_map);
-#endif // defined(OS_WIN)
-
-#if defined(OS_WIN)
-// Set |job_object|'s JOBOBJECT_EXTENDED_LIMIT_INFORMATION
-// BasicLimitInformation.LimitFlags to |limit_flags|.
-BASE_EXPORT bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags);
-
-// Output multi-process printf, cout, cerr, etc to the cmd.exe console that ran
-// chrome. This is not thread-safe: only call from main thread.
-BASE_EXPORT void RouteStdioToConsole(bool create_console_if_not_found);
-#endif // defined(OS_WIN)
-
-// Executes the application specified by |cl| and wait for it to exit. Stores
-// the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
-// on success (application launched and exited cleanly, with exit code
-// indicating success).
-BASE_EXPORT bool GetAppOutput(const CommandLine& cl, std::string* output);
-
-// Like GetAppOutput, but also includes stderr.
-BASE_EXPORT bool GetAppOutputAndError(const CommandLine& cl,
- std::string* output);
-
-// A version of |GetAppOutput()| which also returns the exit code of the
-// executed command. Returns true if the application runs and exits cleanly. If
-// this is the case the exit code of the application is available in
-// |*exit_code|.
-BASE_EXPORT bool GetAppOutputWithExitCode(const CommandLine& cl,
- std::string* output, int* exit_code);
-
-#if defined(OS_WIN)
-// A Windows-specific version of GetAppOutput that takes a command line string
-// instead of a CommandLine object. Useful for situations where you need to
-// control the command line arguments directly.
-BASE_EXPORT bool GetAppOutput(const StringPiece16& cl, std::string* output);
-#elif defined(OS_POSIX)
-// A POSIX-specific version of GetAppOutput that takes an argv array
-// instead of a CommandLine. Useful for situations where you need to
-// control the command line arguments directly.
-BASE_EXPORT bool GetAppOutput(const std::vector<std::string>& argv,
- std::string* output);
-
-// Like the above POSIX-specific version of GetAppOutput, but also includes
-// stderr.
-BASE_EXPORT bool GetAppOutputAndError(const std::vector<std::string>& argv,
- std::string* output);
-#endif // defined(OS_WIN)
-
-// If supported on the platform, and the user has sufficent rights, increase
-// the current process's scheduling priority to a high priority.
-BASE_EXPORT void RaiseProcessToHighPriority();
-
-#if defined(OS_MACOSX)
-// An implementation of LaunchProcess() that uses posix_spawn() instead of
-// fork()+exec(). This does not support the |pre_exec_delegate| and
-// |current_directory| options.
-Process LaunchProcessPosixSpawn(const std::vector<std::string>& argv,
- const LaunchOptions& options);
-
-// Restore the default exception handler, setting it to Apple Crash Reporter
-// (ReportCrash). When forking and execing a new process, the child will
-// inherit the parent's exception ports, which may be set to the Breakpad
-// instance running inside the parent. The parent's Breakpad instance should
-// not handle the child's exceptions. Calling RestoreDefaultExceptionHandler
-// in the child after forking will restore the standard exception handler.
-// See http://crbug.com/20371/ for more details.
-void RestoreDefaultExceptionHandler();
-#endif // defined(OS_MACOSX)
-
-// Creates a LaunchOptions object suitable for launching processes in a test
-// binary. This should not be called in production/released code.
-BASE_EXPORT LaunchOptions LaunchOptionsForTest();
-
-#if defined(OS_LINUX) || defined(OS_NACL_NONSFI)
-// A wrapper for clone with fork-like behavior, meaning that it returns the
-// child's pid in the parent and 0 in the child. |flags|, |ptid|, and |ctid| are
-// as in the clone system call (the CLONE_VM flag is not supported).
-//
-// This function uses the libc clone wrapper (which updates libc's pid cache)
-// internally, so callers may expect things like getpid() to work correctly
-// after in both the child and parent.
-//
-// As with fork(), callers should be extremely careful when calling this while
-// multiple threads are running, since at the time the fork happened, the
-// threads could have been in any state (potentially holding locks, etc.).
-// Callers should most likely call execve() in the child soon after calling
-// this.
-//
-// It is unsafe to use any pthread APIs after ForkWithFlags().
-// However, performing an exec() will lift this restriction.
-BASE_EXPORT pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid);
-#endif
-
-} // namespace base
-
-#endif // BASE_PROCESS_LAUNCH_H_
diff --git a/base/process/launch_mac.cc b/base/process/launch_mac.cc
deleted file mode 100644
index d9a24cc..0000000
--- a/base/process/launch_mac.cc
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright (c) 2012 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 "base/process/launch.h"
-
-#include <crt_externs.h>
-#include <mach/mach.h>
-#include <spawn.h>
-#include <string.h>
-#include <sys/wait.h>
-
-#include "base/logging.h"
-#include "base/posix/eintr_wrapper.h"
-
-namespace base {
-
-namespace {
-
-// DPSXCHECK is a Debug Posix Spawn Check macro. The posix_spawn* family of
-// functions return an errno value, as opposed to setting errno directly. This
-// macro emulates a DPCHECK().
-#define DPSXCHECK(expr) \
- do { \
- int rv = (expr); \
- DCHECK_EQ(rv, 0) << #expr << ": -" << rv << " " << strerror(rv); \
- } while (0)
-
-class PosixSpawnAttr {
- public:
- PosixSpawnAttr() { DPSXCHECK(posix_spawnattr_init(&attr_)); }
-
- ~PosixSpawnAttr() { DPSXCHECK(posix_spawnattr_destroy(&attr_)); }
-
- posix_spawnattr_t* get() { return &attr_; }
-
- private:
- posix_spawnattr_t attr_;
-};
-
-class PosixSpawnFileActions {
- public:
- PosixSpawnFileActions() {
- DPSXCHECK(posix_spawn_file_actions_init(&file_actions_));
- }
-
- ~PosixSpawnFileActions() {
- DPSXCHECK(posix_spawn_file_actions_destroy(&file_actions_));
- }
-
- void Open(int filedes, const char* path, int mode) {
- DPSXCHECK(posix_spawn_file_actions_addopen(&file_actions_, filedes, path,
- mode, 0));
- }
-
- void Dup2(int filedes, int newfiledes) {
- DPSXCHECK(
- posix_spawn_file_actions_adddup2(&file_actions_, filedes, newfiledes));
- }
-
- void Inherit(int filedes) {
- DPSXCHECK(posix_spawn_file_actions_addinherit_np(&file_actions_, filedes));
- }
-
- const posix_spawn_file_actions_t* get() const { return &file_actions_; }
-
- private:
- posix_spawn_file_actions_t file_actions_;
-
- DISALLOW_COPY_AND_ASSIGN(PosixSpawnFileActions);
-};
-
-} // namespace
-
-void RestoreDefaultExceptionHandler() {
- // This function is tailored to remove the Breakpad exception handler.
- // exception_mask matches s_exception_mask in
- // third_party/breakpad/breakpad/src/client/mac/handler/exception_handler.cc
- const exception_mask_t exception_mask = EXC_MASK_BAD_ACCESS |
- EXC_MASK_BAD_INSTRUCTION |
- EXC_MASK_ARITHMETIC |
- EXC_MASK_BREAKPOINT;
-
- // Setting the exception port to MACH_PORT_NULL may not be entirely
- // kosher to restore the default exception handler, but in practice,
- // it results in the exception port being set to Apple Crash Reporter,
- // the desired behavior.
- task_set_exception_ports(mach_task_self(), exception_mask, MACH_PORT_NULL,
- EXCEPTION_DEFAULT, THREAD_STATE_NONE);
-}
-
-Process LaunchProcessPosixSpawn(const std::vector<std::string>& argv,
- const LaunchOptions& options) {
- DCHECK(!options.pre_exec_delegate)
- << "LaunchProcessPosixSpawn does not support PreExecDelegate";
- DCHECK(options.current_directory.empty())
- << "LaunchProcessPosixSpawn does not support current_directory";
-
- PosixSpawnAttr attr;
-
- short flags = POSIX_SPAWN_CLOEXEC_DEFAULT;
- if (options.new_process_group) {
- flags |= POSIX_SPAWN_SETPGROUP;
- DPSXCHECK(posix_spawnattr_setpgroup(attr.get(), 0));
- }
- DPSXCHECK(posix_spawnattr_setflags(attr.get(), flags));
-
- PosixSpawnFileActions file_actions;
-
- // Process file descriptors for the child. By default, LaunchProcess will
- // open stdin to /dev/null and inherit stdout and stderr.
- bool inherit_stdout = true, inherit_stderr = true;
- bool null_stdin = true;
- for (const auto& dup2_pair : options.fds_to_remap) {
- if (dup2_pair.second == STDIN_FILENO) {
- null_stdin = false;
- } else if (dup2_pair.second == STDOUT_FILENO) {
- inherit_stdout = false;
- } else if (dup2_pair.second == STDERR_FILENO) {
- inherit_stderr = false;
- }
-
- if (dup2_pair.first == dup2_pair.second) {
- file_actions.Inherit(dup2_pair.second);
- } else {
- file_actions.Dup2(dup2_pair.first, dup2_pair.second);
- }
- }
-
- if (null_stdin) {
- file_actions.Open(STDIN_FILENO, "/dev/null", O_RDONLY);
- }
- if (inherit_stdout) {
- file_actions.Inherit(STDOUT_FILENO);
- }
- if (inherit_stderr) {
- file_actions.Inherit(STDERR_FILENO);
- }
-
- std::vector<char*> argv_cstr;
- argv_cstr.reserve(argv.size() + 1);
- for (const auto& arg : argv)
- argv_cstr.push_back(const_cast<char*>(arg.c_str()));
- argv_cstr.push_back(nullptr);
-
- std::unique_ptr<char* []> owned_environ;
- char** new_environ = options.clear_environ ? nullptr : *_NSGetEnviron();
- if (!options.environ.empty()) {
- owned_environ = AlterEnvironment(new_environ, options.environ);
- new_environ = owned_environ.get();
- }
-
- const char* executable_path = !options.real_path.empty()
- ? options.real_path.value().c_str()
- : argv_cstr[0];
-
- // Use posix_spawnp as some callers expect to have PATH consulted.
- pid_t pid;
- int rv = posix_spawnp(&pid, executable_path, file_actions.get(), attr.get(),
- &argv_cstr[0], new_environ);
-
- if (rv != 0) {
- DLOG(ERROR) << "posix_spawnp(" << executable_path << "): -" << rv << " "
- << strerror(rv);
- return Process();
- }
-
- if (options.wait) {
- pid_t ret = HANDLE_EINTR(waitpid(pid, nullptr, 0));
- DPCHECK(ret > 0);
- }
-
- return Process(pid);
-}
-
-} // namespace base
diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc
deleted file mode 100644
index 2369802..0000000
--- a/base/process/launch_posix.cc
+++ /dev/null
@@ -1,717 +0,0 @@
-// Copyright (c) 2012 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 "base/process/launch.h"
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sched.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/resource.h>
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <iterator>
-#include <limits>
-#include <memory>
-#include <set>
-
-#include "base/command_line.h"
-#include "base/compiler_specific.h"
-#include "base/files/dir_reader_posix.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/process/process.h"
-#include "base/process/process_metrics.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/platform_thread.h"
-#include "base/time/time.h"
-#include "build_config.h"
-
-#if defined(OS_LINUX) || defined(OS_AIX)
-#include <sys/prctl.h>
-#endif
-
-#if defined(OS_MACOSX)
-#include <crt_externs.h>
-#include <sys/event.h>
-
-#include "base/feature_list.h"
-#else
-extern char** environ;
-#endif
-
-namespace base {
-
-// Friend and derived class of ScopedAllowBaseSyncPrimitives which allows
-// GetAppOutputInternal() to join a process. GetAppOutputInternal() can't itself
-// be a friend of ScopedAllowBaseSyncPrimitives because it is in the anonymous
-// namespace.
-class GetAppOutputScopedAllowBaseSyncPrimitives
- : public base::ScopedAllowBaseSyncPrimitives {};
-
-#if !defined(OS_NACL_NONSFI)
-
-namespace {
-
-#if defined(OS_MACOSX)
-const Feature kMacLaunchProcessPosixSpawn{"MacLaunchProcessPosixSpawn",
- FEATURE_ENABLED_BY_DEFAULT};
-#endif
-
-// Get the process's "environment" (i.e. the thing that setenv/getenv
-// work with).
-char** GetEnvironment() {
-#if defined(OS_MACOSX)
- return *_NSGetEnviron();
-#else
- return environ;
-#endif
-}
-
-// Set the process's "environment" (i.e. the thing that setenv/getenv
-// work with).
-void SetEnvironment(char** env) {
-#if defined(OS_MACOSX)
- *_NSGetEnviron() = env;
-#else
- environ = env;
-#endif
-}
-
-// Set the calling thread's signal mask to new_sigmask and return
-// the previous signal mask.
-sigset_t SetSignalMask(const sigset_t& new_sigmask) {
- sigset_t old_sigmask;
- RAW_CHECK(pthread_sigmask(SIG_SETMASK, &new_sigmask, &old_sigmask) == 0);
- return old_sigmask;
-}
-
-#if (!defined(OS_LINUX) && !defined(OS_AIX)) || \
- (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
-void ResetChildSignalHandlersToDefaults() {
- // The previous signal handlers are likely to be meaningless in the child's
- // context so we reset them to the defaults for now. http://crbug.com/44953
- // These signal handlers are set up at least in browser_main_posix.cc:
- // BrowserMainPartsPosix::PreEarlyInitialization and stack_trace_posix.cc:
- // EnableInProcessStackDumping.
- signal(SIGHUP, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGILL, SIG_DFL);
- signal(SIGABRT, SIG_DFL);
- signal(SIGFPE, SIG_DFL);
- signal(SIGBUS, SIG_DFL);
- signal(SIGSEGV, SIG_DFL);
- signal(SIGSYS, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-}
-
-#else
-
-// TODO(jln): remove the Linux special case once kernels are fixed.
-
-// Internally the kernel makes sigset_t an array of long large enough to have
-// one bit per signal.
-typedef uint64_t kernel_sigset_t;
-
-// This is what struct sigaction looks like to the kernel at least on X86 and
-// ARM. MIPS, for instance, is very different.
-struct kernel_sigaction {
- void* k_sa_handler; // For this usage it only needs to be a generic pointer.
- unsigned long k_sa_flags;
- void* k_sa_restorer; // For this usage it only needs to be a generic pointer.
- kernel_sigset_t k_sa_mask;
-};
-
-// glibc's sigaction() will prevent access to sa_restorer, so we need to roll
-// our own.
-int sys_rt_sigaction(int sig, const struct kernel_sigaction* act,
- struct kernel_sigaction* oact) {
- return syscall(SYS_rt_sigaction, sig, act, oact, sizeof(kernel_sigset_t));
-}
-
-// This function is intended to be used in between fork() and execve() and will
-// reset all signal handlers to the default.
-// The motivation for going through all of them is that sa_restorer can leak
-// from parents and help defeat ASLR on buggy kernels. We reset it to null.
-// See crbug.com/177956.
-void ResetChildSignalHandlersToDefaults(void) {
- for (int signum = 1; ; ++signum) {
- struct kernel_sigaction act = {nullptr};
- int sigaction_get_ret = sys_rt_sigaction(signum, nullptr, &act);
- if (sigaction_get_ret && errno == EINVAL) {
-#if !defined(NDEBUG)
- // Linux supports 32 real-time signals from 33 to 64.
- // If the number of signals in the Linux kernel changes, someone should
- // look at this code.
- const int kNumberOfSignals = 64;
- RAW_CHECK(signum == kNumberOfSignals + 1);
-#endif // !defined(NDEBUG)
- break;
- }
- // All other failures are fatal.
- if (sigaction_get_ret) {
- RAW_LOG(FATAL, "sigaction (get) failed.");
- }
-
- // The kernel won't allow to re-set SIGKILL or SIGSTOP.
- if (signum != SIGSTOP && signum != SIGKILL) {
- act.k_sa_handler = reinterpret_cast<void*>(SIG_DFL);
- act.k_sa_restorer = nullptr;
- if (sys_rt_sigaction(signum, &act, nullptr)) {
- RAW_LOG(FATAL, "sigaction (set) failed.");
- }
- }
-#if !defined(NDEBUG)
- // Now ask the kernel again and check that no restorer will leak.
- if (sys_rt_sigaction(signum, nullptr, &act) || act.k_sa_restorer) {
- RAW_LOG(FATAL, "Cound not fix sa_restorer.");
- }
-#endif // !defined(NDEBUG)
- }
-}
-#endif // !defined(OS_LINUX) ||
- // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
-} // anonymous namespace
-
-// Functor for |ScopedDIR| (below).
-struct ScopedDIRClose {
- inline void operator()(DIR* x) const {
- if (x)
- closedir(x);
- }
-};
-
-// Automatically closes |DIR*|s.
-typedef std::unique_ptr<DIR, ScopedDIRClose> ScopedDIR;
-
-#if defined(OS_LINUX) || defined(OS_AIX)
-static const char kFDDir[] = "/proc/self/fd";
-#elif defined(OS_MACOSX)
-static const char kFDDir[] = "/dev/fd";
-#endif
-
-void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
- // DANGER: no calls to malloc or locks are allowed from now on:
- // http://crbug.com/36678
-
- // Get the maximum number of FDs possible.
- size_t max_fds = GetMaxFds();
-
- DirReaderPosix fd_dir(kFDDir);
- if (!fd_dir.IsValid()) {
- // Fallback case: Try every possible fd.
- for (size_t i = 0; i < max_fds; ++i) {
- const int fd = static_cast<int>(i);
- if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
- continue;
- // Cannot use STL iterators here, since debug iterators use locks.
- size_t j;
- for (j = 0; j < saved_mapping.size(); j++) {
- if (fd == saved_mapping[j].dest)
- break;
- }
- if (j < saved_mapping.size())
- continue;
-
- // Since we're just trying to close anything we can find,
- // ignore any error return values of close().
- close(fd);
- }
- return;
- }
-
- const int dir_fd = fd_dir.fd();
-
- for ( ; fd_dir.Next(); ) {
- // Skip . and .. entries.
- if (fd_dir.name()[0] == '.')
- continue;
-
- char *endptr;
- errno = 0;
- const long int fd = strtol(fd_dir.name(), &endptr, 10);
- if (fd_dir.name()[0] == 0 || *endptr || fd < 0 || errno)
- continue;
- if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
- continue;
- // Cannot use STL iterators here, since debug iterators use locks.
- size_t i;
- for (i = 0; i < saved_mapping.size(); i++) {
- if (fd == saved_mapping[i].dest)
- break;
- }
- if (i < saved_mapping.size())
- continue;
- if (fd == dir_fd)
- continue;
-
- int ret = IGNORE_EINTR(close(fd));
- DPCHECK(ret == 0);
- }
-}
-
-Process LaunchProcess(const CommandLine& cmdline,
- const LaunchOptions& options) {
- return LaunchProcess(cmdline.argv(), options);
-}
-
-Process LaunchProcess(const std::vector<std::string>& argv,
- const LaunchOptions& options) {
- TRACE_EVENT0("base", "LaunchProcess");
-#if defined(OS_MACOSX)
- if (FeatureList::IsEnabled(kMacLaunchProcessPosixSpawn)) {
- // TODO(rsesek): Do this unconditionally. There is one user for each of
- // these two options. https://crbug.com/179923.
- if (!options.pre_exec_delegate && options.current_directory.empty())
- return LaunchProcessPosixSpawn(argv, options);
- }
-#endif
-
- InjectiveMultimap fd_shuffle1;
- InjectiveMultimap fd_shuffle2;
- fd_shuffle1.reserve(options.fds_to_remap.size());
- fd_shuffle2.reserve(options.fds_to_remap.size());
-
- std::vector<char*> argv_cstr;
- argv_cstr.reserve(argv.size() + 1);
- for (const auto& arg : argv)
- argv_cstr.push_back(const_cast<char*>(arg.c_str()));
- argv_cstr.push_back(nullptr);
-
- std::unique_ptr<char* []> new_environ;
- char* const empty_environ = nullptr;
- char* const* old_environ = GetEnvironment();
- if (options.clear_environ)
- old_environ = &empty_environ;
- if (!options.environ.empty())
- new_environ = AlterEnvironment(old_environ, options.environ);
-
- sigset_t full_sigset;
- sigfillset(&full_sigset);
- const sigset_t orig_sigmask = SetSignalMask(full_sigset);
-
- const char* current_directory = nullptr;
- if (!options.current_directory.empty()) {
- current_directory = options.current_directory.value().c_str();
- }
-
- pid_t pid;
- base::TimeTicks before_fork = TimeTicks::Now();
-#if defined(OS_LINUX) || defined(OS_AIX)
- if (options.clone_flags) {
- // Signal handling in this function assumes the creation of a new
- // process, so we check that a thread is not being created by mistake
- // and that signal handling follows the process-creation rules.
- RAW_CHECK(
- !(options.clone_flags & (CLONE_SIGHAND | CLONE_THREAD | CLONE_VM)));
-
- // We specify a null ptid and ctid.
- RAW_CHECK(
- !(options.clone_flags &
- (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | CLONE_PARENT_SETTID)));
-
- // Since we use waitpid, we do not support custom termination signals in the
- // clone flags.
- RAW_CHECK((options.clone_flags & 0xff) == 0);
-
- pid = ForkWithFlags(options.clone_flags | SIGCHLD, nullptr, nullptr);
- } else
-#endif
- {
- pid = fork();
- }
-
- // Always restore the original signal mask in the parent.
- if (pid != 0) {
- base::TimeTicks after_fork = TimeTicks::Now();
- SetSignalMask(orig_sigmask);
-
- base::TimeDelta fork_time = after_fork - before_fork;
- UMA_HISTOGRAM_TIMES("MPArch.ForkTime", fork_time);
- }
-
- if (pid < 0) {
- DPLOG(ERROR) << "fork";
- return Process();
- } else if (pid == 0) {
- // Child process
-
- // DANGER: no calls to malloc or locks are allowed from now on:
- // http://crbug.com/36678
-
- // DANGER: fork() rule: in the child, if you don't end up doing exec*(),
- // you call _exit() instead of exit(). This is because _exit() does not
- // call any previously-registered (in the parent) exit handlers, which
- // might do things like block waiting for threads that don't even exist
- // in the child.
-
- // If a child process uses the readline library, the process block forever.
- // In BSD like OSes including OS X it is safe to assign /dev/null as stdin.
- // See http://crbug.com/56596.
- base::ScopedFD null_fd(HANDLE_EINTR(open("/dev/null", O_RDONLY)));
- if (!null_fd.is_valid()) {
- RAW_LOG(ERROR, "Failed to open /dev/null");
- _exit(127);
- }
-
- int new_fd = HANDLE_EINTR(dup2(null_fd.get(), STDIN_FILENO));
- if (new_fd != STDIN_FILENO) {
- RAW_LOG(ERROR, "Failed to dup /dev/null for stdin");
- _exit(127);
- }
-
- if (options.new_process_group) {
- // Instead of inheriting the process group ID of the parent, the child
- // starts off a new process group with pgid equal to its process ID.
- if (setpgid(0, 0) < 0) {
- RAW_LOG(ERROR, "setpgid failed");
- _exit(127);
- }
- }
-
- if (options.maximize_rlimits) {
- // Some resource limits need to be maximal in this child.
- for (size_t i = 0; i < options.maximize_rlimits->size(); ++i) {
- const int resource = (*options.maximize_rlimits)[i];
- struct rlimit limit;
- if (getrlimit(resource, &limit) < 0) {
- RAW_LOG(WARNING, "getrlimit failed");
- } else if (limit.rlim_cur < limit.rlim_max) {
- limit.rlim_cur = limit.rlim_max;
- if (setrlimit(resource, &limit) < 0) {
- RAW_LOG(WARNING, "setrlimit failed");
- }
- }
- }
- }
-
-#if defined(OS_MACOSX)
- RestoreDefaultExceptionHandler();
-#endif // defined(OS_MACOSX)
-
- ResetChildSignalHandlersToDefaults();
- SetSignalMask(orig_sigmask);
-
-#if 0
- // When debugging it can be helpful to check that we really aren't making
- // any hidden calls to malloc.
- void *malloc_thunk =
- reinterpret_cast<void*>(reinterpret_cast<intptr_t>(malloc) & ~4095);
- mprotect(malloc_thunk, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
- memset(reinterpret_cast<void*>(malloc), 0xff, 8);
-#endif // 0
-
- // Cannot use STL iterators here, since debug iterators use locks.
- for (size_t i = 0; i < options.fds_to_remap.size(); ++i) {
- const FileHandleMappingVector::value_type& value =
- options.fds_to_remap[i];
- fd_shuffle1.push_back(InjectionArc(value.first, value.second, false));
- fd_shuffle2.push_back(InjectionArc(value.first, value.second, false));
- }
-
- if (!options.environ.empty() || options.clear_environ)
- SetEnvironment(new_environ.get());
-
- // fd_shuffle1 is mutated by this call because it cannot malloc.
- if (!ShuffleFileDescriptors(&fd_shuffle1))
- _exit(127);
-
- CloseSuperfluousFds(fd_shuffle2);
-
- // Set NO_NEW_PRIVS by default. Since NO_NEW_PRIVS only exists in kernel
- // 3.5+, do not check the return value of prctl here.
-#if defined(OS_LINUX) || defined(OS_AIX)
-#ifndef PR_SET_NO_NEW_PRIVS
-#define PR_SET_NO_NEW_PRIVS 38
-#endif
- if (!options.allow_new_privs) {
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) && errno != EINVAL) {
- // Only log if the error is not EINVAL (i.e. not supported).
- RAW_LOG(FATAL, "prctl(PR_SET_NO_NEW_PRIVS) failed");
- }
- }
-
- if (options.kill_on_parent_death) {
- if (prctl(PR_SET_PDEATHSIG, SIGKILL) != 0) {
- RAW_LOG(ERROR, "prctl(PR_SET_PDEATHSIG) failed");
- _exit(127);
- }
- }
-#endif
-
- if (current_directory != nullptr) {
- RAW_CHECK(chdir(current_directory) == 0);
- }
-
- if (options.pre_exec_delegate != nullptr) {
- options.pre_exec_delegate->RunAsyncSafe();
- }
-
- const char* executable_path = !options.real_path.empty() ?
- options.real_path.value().c_str() : argv_cstr[0];
-
- execvp(executable_path, argv_cstr.data());
-
- RAW_LOG(ERROR, "LaunchProcess: failed to execvp:");
- RAW_LOG(ERROR, argv_cstr[0]);
- _exit(127);
- } else {
- // Parent process
- if (options.wait) {
- pid_t ret = HANDLE_EINTR(waitpid(pid, nullptr, 0));
- DPCHECK(ret > 0);
- }
- }
-
- return Process(pid);
-}
-
-void RaiseProcessToHighPriority() {
- // On POSIX, we don't actually do anything here. We could try to nice() or
- // setpriority() or sched_getscheduler, but these all require extra rights.
-}
-
-// Executes the application specified by |argv| and wait for it to exit. Stores
-// the output (stdout) in |output|. If |do_search_path| is set, it searches the
-// path for the application; in that case, |envp| must be null, and it will use
-// the current environment. If |do_search_path| is false, |argv[0]| should fully
-// specify the path of the application, and |envp| will be used as the
-// environment. If |include_stderr| is true, includes stderr otherwise redirects
-// it to /dev/null.
-// The return value of the function indicates success or failure. In the case of
-// success, the application exit code will be returned in |*exit_code|, which
-// should be checked to determine if the application ran successfully.
-static bool GetAppOutputInternal(
- const std::vector<std::string>& argv,
- char* const envp[],
- bool include_stderr,
- std::string* output,
- bool do_search_path,
- int* exit_code) {
- // exit_code must be supplied so calling function can determine success.
- DCHECK(exit_code);
- *exit_code = EXIT_FAILURE;
-
- // Declare and call reserve() here before calling fork() because the child
- // process cannot allocate memory.
- std::vector<char*> argv_cstr;
- argv_cstr.reserve(argv.size() + 1);
- InjectiveMultimap fd_shuffle1;
- InjectiveMultimap fd_shuffle2;
- fd_shuffle1.reserve(3);
- fd_shuffle2.reserve(3);
-
- // Either |do_search_path| should be false or |envp| should be null, but not
- // both.
- DCHECK(!do_search_path ^ !envp);
-
- int pipe_fd[2];
- if (pipe(pipe_fd) < 0)
- return false;
-
- pid_t pid = fork();
- switch (pid) {
- case -1: {
- // error
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- return false;
- }
- case 0: {
- // child
- //
- // DANGER: no calls to malloc or locks are allowed from now on:
- // http://crbug.com/36678
-
-#if defined(OS_MACOSX)
- RestoreDefaultExceptionHandler();
-#endif
-
- // Obscure fork() rule: in the child, if you don't end up doing exec*(),
- // you call _exit() instead of exit(). This is because _exit() does not
- // call any previously-registered (in the parent) exit handlers, which
- // might do things like block waiting for threads that don't even exist
- // in the child.
- int dev_null = open("/dev/null", O_WRONLY);
- if (dev_null < 0)
- _exit(127);
-
- fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
- fd_shuffle1.push_back(InjectionArc(include_stderr ? pipe_fd[1] : dev_null,
- STDERR_FILENO, true));
- fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
- // Adding another element here? Remeber to increase the argument to
- // reserve(), above.
-
- for (size_t i = 0; i < fd_shuffle1.size(); ++i)
- fd_shuffle2.push_back(fd_shuffle1[i]);
-
- if (!ShuffleFileDescriptors(&fd_shuffle1))
- _exit(127);
-
- CloseSuperfluousFds(fd_shuffle2);
-
- for (const auto& arg : argv)
- argv_cstr.push_back(const_cast<char*>(arg.c_str()));
- argv_cstr.push_back(nullptr);
-
- if (do_search_path)
- execvp(argv_cstr[0], argv_cstr.data());
- else
- execve(argv_cstr[0], argv_cstr.data(), envp);
- _exit(127);
- }
- default: {
- // parent
- //
- // Close our writing end of pipe now. Otherwise later read would not
- // be able to detect end of child's output (in theory we could still
- // write to the pipe).
- close(pipe_fd[1]);
-
- output->clear();
-
- while (true) {
- char buffer[256];
- ssize_t bytes_read =
- HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
- if (bytes_read <= 0)
- break;
- output->append(buffer, bytes_read);
- }
- close(pipe_fd[0]);
-
- // Always wait for exit code (even if we know we'll declare
- // GOT_MAX_OUTPUT).
- Process process(pid);
- // A process launched with GetAppOutput*() usually doesn't wait on the
- // process that launched it and thus chances of deadlock are low.
- GetAppOutputScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
- return process.WaitForExit(exit_code);
- }
- }
-}
-
-bool GetAppOutput(const CommandLine& cl, std::string* output) {
- return GetAppOutput(cl.argv(), output);
-}
-
-bool GetAppOutput(const std::vector<std::string>& argv, std::string* output) {
- // Run |execve()| with the current environment.
- int exit_code;
- bool result =
- GetAppOutputInternal(argv, nullptr, false, output, true, &exit_code);
- return result && exit_code == EXIT_SUCCESS;
-}
-
-bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
- // Run |execve()| with the current environment.
- int exit_code;
- bool result =
- GetAppOutputInternal(cl.argv(), nullptr, true, output, true, &exit_code);
- return result && exit_code == EXIT_SUCCESS;
-}
-
-bool GetAppOutputAndError(const std::vector<std::string>& argv,
- std::string* output) {
- int exit_code;
- bool result =
- GetAppOutputInternal(argv, nullptr, true, output, true, &exit_code);
- return result && exit_code == EXIT_SUCCESS;
-}
-
-bool GetAppOutputWithExitCode(const CommandLine& cl,
- std::string* output,
- int* exit_code) {
- // Run |execve()| with the current environment.
- return GetAppOutputInternal(cl.argv(), nullptr, false, output, true,
- exit_code);
-}
-
-#endif // !defined(OS_NACL_NONSFI)
-
-#if defined(OS_LINUX) || defined(OS_NACL_NONSFI) || defined(OS_AIX)
-namespace {
-
-// This function runs on the stack specified on the clone call. It uses longjmp
-// to switch back to the original stack so the child can return from sys_clone.
-int CloneHelper(void* arg) {
- jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
- longjmp(*env_ptr, 1);
-
- // Should not be reached.
- RAW_CHECK(false);
- return 1;
-}
-
-// This function is noinline to ensure that stack_buf is below the stack pointer
-// that is saved when setjmp is called below. This is needed because when
-// compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
-// upwards. See crbug.com/442912 for more details.
-#if defined(ADDRESS_SANITIZER)
-// Disable AddressSanitizer instrumentation for this function to make sure
-// |stack_buf| is allocated on thread stack instead of ASan's fake stack.
-// Under ASan longjmp() will attempt to clean up the area between the old and
-// new stack pointers and print a warning that may confuse the user.
-__attribute__((no_sanitize_address))
-#endif
-NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
- pid_t* ptid,
- pid_t* ctid,
- jmp_buf* env) {
- // We use the libc clone wrapper instead of making the syscall
- // directly because making the syscall may fail to update the libc's
- // internal pid cache. The libc interface unfortunately requires
- // specifying a new stack, so we use setjmp/longjmp to emulate
- // fork-like behavior.
- alignas(16) char stack_buf[PTHREAD_STACK_MIN];
-#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
- defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_S390_FAMILY) || \
- defined(ARCH_CPU_PPC64_FAMILY)
- // The stack grows downward.
- void* stack = stack_buf + sizeof(stack_buf);
-#else
-#error "Unsupported architecture"
-#endif
- return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
-}
-
-} // anonymous namespace
-
-pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) {
- const bool clone_tls_used = flags & CLONE_SETTLS;
- const bool invalid_ctid =
- (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
- const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;
-
- // We do not support CLONE_VM.
- const bool clone_vm_used = flags & CLONE_VM;
-
- if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
- RAW_LOG(FATAL, "Invalid usage of ForkWithFlags");
- }
-
- jmp_buf env;
- if (setjmp(env) == 0) {
- return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
- }
-
- return 0;
-}
-#endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI)
-
-} // namespace base
diff --git a/base/process/launch_unittest_win.cc b/base/process/launch_unittest_win.cc
deleted file mode 100644
index 1b060c5..0000000
--- a/base/process/launch_unittest_win.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2017 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 "base/process/launch.h"
-
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-
-TEST(LaunchWinTest, GetAppOutputWithExitCodeShouldReturnExitCode) {
- CommandLine cl(FilePath(FILE_PATH_LITERAL("cmd")));
- cl.AppendArg("/c");
- cl.AppendArg("this-is-not-an-application");
- std::string output;
- int exit_code;
- ASSERT_TRUE(GetAppOutputWithExitCode(cl, &output, &exit_code));
- ASSERT_TRUE(output.empty());
- ASSERT_EQ(1, exit_code);
-}
-
-} // namespace
diff --git a/base/process/launch_win.cc b/base/process/launch_win.cc
deleted file mode 100644
index f24b6dd..0000000
--- a/base/process/launch_win.cc
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright (c) 2012 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 "base/process/launch.h"
-
-#include <fcntl.h>
-#include <io.h>
-#include <shellapi.h>
-#include <windows.h>
-#include <userenv.h>
-#include <psapi.h>
-
-#include <ios>
-#include <limits>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/process/kill.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/win/scoped_handle.h"
-#include "base/win/scoped_process_information.h"
-#include "base/win/startup_information.h"
-#include "base/win/windows_version.h"
-
-namespace base {
-
-namespace {
-
-bool GetAppOutputInternal(const StringPiece16& cl,
- bool include_stderr,
- std::string* output,
- int* exit_code) {
- HANDLE out_read = nullptr;
- HANDLE out_write = nullptr;
-
- SECURITY_ATTRIBUTES sa_attr;
- // Set the bInheritHandle flag so pipe handles are inherited.
- sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa_attr.bInheritHandle = TRUE;
- sa_attr.lpSecurityDescriptor = nullptr;
-
- // Create the pipe for the child process's STDOUT.
- if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) {
- NOTREACHED() << "Failed to create pipe";
- return false;
- }
-
- // Ensure we don't leak the handles.
- win::ScopedHandle scoped_out_read(out_read);
- win::ScopedHandle scoped_out_write(out_write);
-
- // Ensure the read handles to the pipes are not inherited.
- if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
- NOTREACHED() << "Failed to disabled pipe inheritance";
- return false;
- }
-
- FilePath::StringType writable_command_line_string;
- writable_command_line_string.assign(cl.data(), cl.size());
-
- STARTUPINFO start_info = {};
-
- start_info.cb = sizeof(STARTUPINFO);
- start_info.hStdOutput = out_write;
- // Keep the normal stdin.
- start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
- if (include_stderr) {
- start_info.hStdError = out_write;
- } else {
- start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
- }
- start_info.dwFlags |= STARTF_USESTDHANDLES;
-
- // Create the child process.
- PROCESS_INFORMATION temp_process_info = {};
- if (!CreateProcess(nullptr, &writable_command_line_string[0], nullptr,
- nullptr,
- TRUE, // Handles are inherited.
- 0, nullptr, nullptr, &start_info, &temp_process_info)) {
- NOTREACHED() << "Failed to start process";
- return false;
- }
-
- base::win::ScopedProcessInformation proc_info(temp_process_info);
-
- // Close our writing end of pipe now. Otherwise later read would not be able
- // to detect end of child's output.
- scoped_out_write.Close();
-
- // Read output from the child process's pipe for STDOUT
- const int kBufferSize = 1024;
- char buffer[kBufferSize];
-
- for (;;) {
- DWORD bytes_read = 0;
- BOOL success =
- ::ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr);
- if (!success || bytes_read == 0)
- break;
- output->append(buffer, bytes_read);
- }
-
- // Let's wait for the process to finish.
- WaitForSingleObject(proc_info.process_handle(), INFINITE);
-
- base::TerminationStatus status = GetTerminationStatus(
- proc_info.process_handle(), exit_code);
- return status != base::TERMINATION_STATUS_PROCESS_CRASHED &&
- status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION;
-}
-
-} // namespace
-
-void RouteStdioToConsole(bool create_console_if_not_found) {
- // Don't change anything if stdout or stderr already point to a
- // valid stream.
- //
- // If we are running under Buildbot or under Cygwin's default
- // terminal (mintty), stderr and stderr will be pipe handles. In
- // that case, we don't want to open CONOUT$, because its output
- // likely does not go anywhere.
- //
- // We don't use GetStdHandle() to check stdout/stderr here because
- // it can return dangling IDs of handles that were never inherited
- // by this process. These IDs could have been reused by the time
- // this function is called. The CRT checks the validity of
- // stdout/stderr on startup (before the handle IDs can be reused).
- // _fileno(stdout) will return -2 (_NO_CONSOLE_FILENO) if stdout was
- // invalid.
- if (_fileno(stdout) >= 0 || _fileno(stderr) >= 0) {
- // _fileno was broken for SUBSYSTEM:WINDOWS from VS2010 to VS2012/2013.
- // http://crbug.com/358267. Confirm that the underlying HANDLE is valid
- // before aborting.
-
- intptr_t stdout_handle = _get_osfhandle(_fileno(stdout));
- intptr_t stderr_handle = _get_osfhandle(_fileno(stderr));
- if (stdout_handle >= 0 || stderr_handle >= 0)
- return;
- }
-
- if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
- unsigned int result = GetLastError();
- // Was probably already attached.
- if (result == ERROR_ACCESS_DENIED)
- return;
- // Don't bother creating a new console for each child process if the
- // parent process is invalid (eg: crashed).
- if (result == ERROR_GEN_FAILURE)
- return;
- if (create_console_if_not_found) {
- // Make a new console if attaching to parent fails with any other error.
- // It should be ERROR_INVALID_HANDLE at this point, which means the
- // browser was likely not started from a console.
- AllocConsole();
- } else {
- return;
- }
- }
-
- // Arbitrary byte count to use when buffering output lines. More
- // means potential waste, less means more risk of interleaved
- // log-lines in output.
- enum { kOutputBufferSize = 64 * 1024 };
-
- if (freopen("CONOUT$", "w", stdout)) {
- setvbuf(stdout, nullptr, _IOLBF, kOutputBufferSize);
- // Overwrite FD 1 for the benefit of any code that uses this FD
- // directly. This is safe because the CRT allocates FDs 0, 1 and
- // 2 at startup even if they don't have valid underlying Windows
- // handles. This means we won't be overwriting an FD created by
- // _open() after startup.
- _dup2(_fileno(stdout), 1);
- }
- if (freopen("CONOUT$", "w", stderr)) {
- setvbuf(stderr, nullptr, _IOLBF, kOutputBufferSize);
- _dup2(_fileno(stderr), 2);
- }
-
- // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog.
- std::ios::sync_with_stdio();
-}
-
-Process LaunchProcess(const CommandLine& cmdline,
- const LaunchOptions& options) {
- return LaunchProcess(cmdline.GetCommandLineString(), options);
-}
-
-Process LaunchProcess(const string16& cmdline,
- const LaunchOptions& options) {
- win::StartupInformation startup_info_wrapper;
- STARTUPINFO* startup_info = startup_info_wrapper.startup_info();
-
- bool inherit_handles = options.inherit_mode == LaunchOptions::Inherit::kAll;
- DWORD flags = 0;
- if (!options.handles_to_inherit.empty()) {
- DCHECK_EQ(options.inherit_mode, LaunchOptions::Inherit::kSpecific);
-
- if (options.handles_to_inherit.size() >
- std::numeric_limits<DWORD>::max() / sizeof(HANDLE)) {
- DLOG(ERROR) << "Too many handles to inherit.";
- return Process();
- }
-
- // Ensure the handles can be inherited.
- for (HANDLE handle : options.handles_to_inherit) {
- BOOL result = SetHandleInformation(handle, HANDLE_FLAG_INHERIT,
- HANDLE_FLAG_INHERIT);
- PCHECK(result);
- }
-
- if (!startup_info_wrapper.InitializeProcThreadAttributeList(1)) {
- DPLOG(ERROR);
- return Process();
- }
-
- if (!startup_info_wrapper.UpdateProcThreadAttribute(
- PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
- const_cast<HANDLE*>(&options.handles_to_inherit[0]),
- static_cast<DWORD>(options.handles_to_inherit.size() *
- sizeof(HANDLE)))) {
- DPLOG(ERROR);
- return Process();
- }
-
- inherit_handles = true;
- flags |= EXTENDED_STARTUPINFO_PRESENT;
- }
-
- if (options.empty_desktop_name)
- startup_info->lpDesktop = const_cast<wchar_t*>(L"");
- startup_info->dwFlags = STARTF_USESHOWWINDOW;
- startup_info->wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOWNORMAL;
-
- if (options.stdin_handle || options.stdout_handle || options.stderr_handle) {
- DCHECK(inherit_handles);
- DCHECK(options.stdin_handle);
- DCHECK(options.stdout_handle);
- DCHECK(options.stderr_handle);
- startup_info->dwFlags |= STARTF_USESTDHANDLES;
- startup_info->hStdInput = options.stdin_handle;
- startup_info->hStdOutput = options.stdout_handle;
- startup_info->hStdError = options.stderr_handle;
- }
-
- const bool launch_suspended =
- options.job_handle || options.grant_foreground_privilege;
-
- if (launch_suspended)
- flags |= CREATE_SUSPENDED;
-
- if (options.job_handle) {
- // If this code is run under a debugger, the launched process is
- // automatically associated with a job object created by the debugger.
- // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this on Windows
- // releases that do not support nested jobs.
- if (win::GetVersion() < win::VERSION_WIN8)
- flags |= CREATE_BREAKAWAY_FROM_JOB;
- }
-
- if (options.force_breakaway_from_job_)
- flags |= CREATE_BREAKAWAY_FROM_JOB;
-
- PROCESS_INFORMATION temp_process_info = {};
-
- LPCTSTR current_directory = options.current_directory.empty()
- ? nullptr
- : options.current_directory.value().c_str();
-
- string16 writable_cmdline(cmdline);
- if (options.as_user) {
- flags |= CREATE_UNICODE_ENVIRONMENT;
- void* enviroment_block = nullptr;
-
- if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) {
- DPLOG(ERROR);
- return Process();
- }
-
- BOOL launched = CreateProcessAsUser(
- options.as_user, nullptr, &writable_cmdline[0], nullptr, nullptr,
- inherit_handles, flags, enviroment_block, current_directory,
- startup_info, &temp_process_info);
- DestroyEnvironmentBlock(enviroment_block);
- if (!launched) {
- DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline)
- << std::endl;
- return Process();
- }
- } else {
- if (!CreateProcess(nullptr, &writable_cmdline[0], nullptr, nullptr,
- inherit_handles, flags, nullptr, current_directory,
- startup_info, &temp_process_info)) {
- DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline)
- << std::endl;
- return Process();
- }
- }
- base::win::ScopedProcessInformation process_info(temp_process_info);
-
- if (options.job_handle &&
- !AssignProcessToJobObject(options.job_handle,
- process_info.process_handle())) {
- DPLOG(ERROR) << "Could not AssignProcessToObject";
- Process scoped_process(process_info.TakeProcessHandle());
- scoped_process.Terminate(win::kProcessKilledExitCode, true);
- return Process();
- }
-
- if (options.grant_foreground_privilege &&
- !AllowSetForegroundWindow(GetProcId(process_info.process_handle()))) {
- DPLOG(ERROR) << "Failed to grant foreground privilege to launched process";
- }
-
- if (launch_suspended)
- ResumeThread(process_info.thread_handle());
-
- if (options.wait)
- WaitForSingleObject(process_info.process_handle(), INFINITE);
-
- return Process(process_info.TakeProcessHandle());
-}
-
-Process LaunchElevatedProcess(const CommandLine& cmdline,
- const LaunchOptions& options) {
- const string16 file = cmdline.GetProgram().value();
- const string16 arguments = cmdline.GetArgumentsString();
-
- SHELLEXECUTEINFO shex_info = {};
- shex_info.cbSize = sizeof(shex_info);
- shex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
- shex_info.hwnd = GetActiveWindow();
- shex_info.lpVerb = L"runas";
- shex_info.lpFile = file.c_str();
- shex_info.lpParameters = arguments.c_str();
- shex_info.lpDirectory = nullptr;
- shex_info.nShow = options.start_hidden ? SW_HIDE : SW_SHOWNORMAL;
- shex_info.hInstApp = nullptr;
-
- if (!ShellExecuteEx(&shex_info)) {
- DPLOG(ERROR);
- return Process();
- }
-
- if (options.wait)
- WaitForSingleObject(shex_info.hProcess, INFINITE);
-
- return Process(shex_info.hProcess);
-}
-
-bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) {
- JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {};
- limit_info.BasicLimitInformation.LimitFlags = limit_flags;
- return 0 != SetInformationJobObject(
- job_object,
- JobObjectExtendedLimitInformation,
- &limit_info,
- sizeof(limit_info));
-}
-
-bool GetAppOutput(const CommandLine& cl, std::string* output) {
- return GetAppOutput(cl.GetCommandLineString(), output);
-}
-
-bool GetAppOutputAndError(const CommandLine& cl, std::string* output) {
- int exit_code;
- return GetAppOutputInternal(
- cl.GetCommandLineString(), true, output, &exit_code);
-}
-
-bool GetAppOutputWithExitCode(const CommandLine& cl,
- std::string* output,
- int* exit_code) {
- return GetAppOutputInternal(
- cl.GetCommandLineString(), false, output, exit_code);
-}
-
-bool GetAppOutput(const StringPiece16& cl, std::string* output) {
- int exit_code;
- return GetAppOutputInternal(cl, false, output, &exit_code);
-}
-
-void RaiseProcessToHighPriority() {
- SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
-}
-
-} // namespace base
diff --git a/base/process/memory_unittest_mac.h b/base/process/memory_unittest_mac.h
deleted file mode 100644
index 4d82a73..0000000
--- a/base/process/memory_unittest_mac.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2010 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.
-
-// This file contains helpers for the process_util_unittest to allow it to fully
-// test the Mac code.
-
-#ifndef BASE_PROCESS_MEMORY_UNITTEST_MAC_H_
-#define BASE_PROCESS_MEMORY_UNITTEST_MAC_H_
-
-#include <stddef.h>
-#include <sys/types.h>
-
-#include "build_config.h"
-
-namespace base {
-
-// Allocates memory via system allocators. Alas, they take a _signed_ size for
-// allocation.
-void* AllocateViaCFAllocatorSystemDefault(ssize_t size);
-void* AllocateViaCFAllocatorMalloc(ssize_t size);
-void* AllocateViaCFAllocatorMallocZone(ssize_t size);
-
-#if !defined(ARCH_CPU_64_BITS)
-// See process_util_unittest_mac.mm for an explanation of why this function
-// isn't implemented for the 64-bit environment.
-
-// Allocates a huge Objective C object.
-void* AllocatePsychoticallyBigObjCObject();
-
-#endif // !ARCH_CPU_64_BITS
-
-} // namespace base
-
-#endif // BASE_PROCESS_MEMORY_UNITTEST_MAC_H_
diff --git a/base/process/memory_unittest_mac.mm b/base/process/memory_unittest_mac.mm
deleted file mode 100644
index 7ec7afd..0000000
--- a/base/process/memory_unittest_mac.mm
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2010 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 "base/process/memory_unittest_mac.h"
-#include "build_config.h"
-
-#import <Foundation/Foundation.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-#if !defined(ARCH_CPU_64_BITS)
-
-// In the 64-bit environment, the Objective-C 2.0 Runtime Reference states
-// that sizeof(anInstance) is constrained to 32 bits. That's not necessarily
-// "psychotically big" and in fact a 64-bit program is expected to be able to
-// successfully allocate an object that large, likely reserving a good deal of
-// swap space. The only way to test the behavior of memory exhaustion for
-// Objective-C allocation in this environment would be to loop over allocation
-// of these large objects, but that would slowly consume all available memory
-// and cause swap file proliferation. That's bad, so this behavior isn't
-// tested in the 64-bit environment.
-
-@interface PsychoticallyBigObjCObject : NSObject
-{
- // In the 32-bit environment, the compiler limits Objective-C objects to
- // < 2GB in size.
- int justUnder2Gigs_[(2U * 1024 * 1024 * 1024 - 1) / sizeof(int)];
-}
-
-@end
-
-@implementation PsychoticallyBigObjCObject
-
-@end
-
-namespace base {
-
-void* AllocatePsychoticallyBigObjCObject() {
- return [[PsychoticallyBigObjCObject alloc] init];
-}
-
-} // namespace base
-
-#endif // ARCH_CPU_64_BITS
-
-namespace base {
-
-void* AllocateViaCFAllocatorSystemDefault(ssize_t size) {
- return CFAllocatorAllocate(kCFAllocatorSystemDefault, size, 0);
-}
-
-void* AllocateViaCFAllocatorMalloc(ssize_t size) {
- return CFAllocatorAllocate(kCFAllocatorMalloc, size, 0);
-}
-
-void* AllocateViaCFAllocatorMallocZone(ssize_t size) {
- return CFAllocatorAllocate(kCFAllocatorMallocZone, size, 0);
-}
-
-} // namespace base
diff --git a/base/strings/sys_string_conversions_mac_unittest.mm b/base/strings/sys_string_conversions_mac_unittest.mm
deleted file mode 100644
index 4750a9a..0000000
--- a/base/strings/sys_string_conversions_mac_unittest.mm
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 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.
-
-#import <Foundation/Foundation.h>
-
-#include "base/strings/string16.h"
-#include "base/strings/sys_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-
-TEST(SysStrings, ConversionsFromNSString) {
- EXPECT_STREQ("Hello, world!", SysNSStringToUTF8(@"Hello, world!").c_str());
-
- // Conversions should be able to handle a NULL value without crashing.
- EXPECT_STREQ("", SysNSStringToUTF8(nil).c_str());
- EXPECT_EQ(string16(), SysNSStringToUTF16(nil));
-}
-
-} // namespace base
diff --git a/build/gen.py b/build/gen.py
index 45c3e33..d72f39b 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -551,7 +551,6 @@
'base/files/file_util_win.cc',
'base/files/file_win.cc',
'base/process/kill_win.cc',
- 'base/process/launch_win.cc',
'base/process/memory_win.cc',
'base/process/process_handle_win.cc',
'base/process/process_info_win.cc',
diff --git a/tools/gn/command_args.cc b/tools/gn/command_args.cc
index b3c6862..e7721ad 100644
--- a/tools/gn/command_args.cc
+++ b/tools/gn/command_args.cc
@@ -13,7 +13,6 @@
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
-#include "base/process/launch.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "build_config.h"
diff --git a/tools/gn/exec_process.cc b/tools/gn/exec_process.cc
index 1009cec..092178d 100644
--- a/tools/gn/exec_process.cc
+++ b/tools/gn/exec_process.cc
@@ -12,7 +12,6 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/process/kill.h"
-#include "base/process/launch.h"
#include "base/process/process.h"
#include "build_config.h"
diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc
index 8a66259..20b3a6f 100644
--- a/tools/gn/setup.cc
+++ b/tools/gn/setup.cc
@@ -16,7 +16,7 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
-#include "base/process/launch.h"
+#include "base/process/kill.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
@@ -39,6 +39,7 @@
#if defined(OS_WIN)
#include <windows.h>
+#include "base/win/scoped_process_information.h"
#endif
const char kDotfile_Help[] =
@@ -189,6 +190,83 @@
#if defined(OS_WIN)
+bool GetAppOutput(const base::StringPiece16& cl, std::string* output) {
+ HANDLE out_read = nullptr;
+ HANDLE out_write = nullptr;
+
+ SECURITY_ATTRIBUTES sa_attr;
+ // Set the bInheritHandle flag so pipe handles are inherited.
+ sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa_attr.bInheritHandle = TRUE;
+ sa_attr.lpSecurityDescriptor = nullptr;
+
+ // Create the pipe for the child process's STDOUT.
+ if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) {
+ NOTREACHED() << "Failed to create pipe";
+ return false;
+ }
+
+ // Ensure we don't leak the handles.
+ base::win::ScopedHandle scoped_out_read(out_read);
+ base::win::ScopedHandle scoped_out_write(out_write);
+
+ // Ensure the read handles to the pipes are not inherited.
+ if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
+ NOTREACHED() << "Failed to disabled pipe inheritance";
+ return false;
+ }
+
+ base::FilePath::StringType writable_command_line_string;
+ writable_command_line_string.assign(cl.data(), cl.size());
+
+ STARTUPINFO start_info = {};
+
+ start_info.cb = sizeof(STARTUPINFO);
+ start_info.hStdOutput = out_write;
+ // Keep the normal stdin/stderr.
+ start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ start_info.dwFlags |= STARTF_USESTDHANDLES;
+
+ // Create the child process.
+ PROCESS_INFORMATION temp_process_info = {};
+ if (!CreateProcess(nullptr, &writable_command_line_string[0], nullptr,
+ nullptr,
+ TRUE, // Handles are inherited.
+ 0, nullptr, nullptr, &start_info, &temp_process_info)) {
+ NOTREACHED() << "Failed to start process";
+ return false;
+ }
+
+ base::win::ScopedProcessInformation proc_info(temp_process_info);
+
+ // Close our writing end of pipe now. Otherwise later read would not be able
+ // to detect end of child's output.
+ scoped_out_write.Close();
+
+ // Read output from the child process's pipe for STDOUT
+ const int kBufferSize = 1024;
+ char buffer[kBufferSize];
+
+ for (;;) {
+ DWORD bytes_read = 0;
+ BOOL success =
+ ::ReadFile(out_read, buffer, kBufferSize, &bytes_read, nullptr);
+ if (!success || bytes_read == 0)
+ break;
+ output->append(buffer, bytes_read);
+ }
+
+ // Let's wait for the process to finish.
+ WaitForSingleObject(proc_info.process_handle(), INFINITE);
+
+ int exit_code;
+ base::TerminationStatus status =
+ base::GetTerminationStatus(proc_info.process_handle(), &exit_code);
+ return status != base::TERMINATION_STATUS_PROCESS_CRASHED &&
+ status != base::TERMINATION_STATUS_ABNORMAL_TERMINATION;
+}
+
// Given the path to a batch file that runs Python, extracts the name of the
// executable actually implementing Python. Generally people write a batch file
// to put something named "python" on the path, which then just redirects to
@@ -205,7 +283,7 @@
command.append(L"\" -c \"import sys; print sys.executable\"\"");
std::string python_path;
- if (base::GetAppOutput(command, &python_path)) {
+ if (GetAppOutput(command, &python_path)) {
base::TrimWhitespaceASCII(python_path, base::TRIM_ALL, &python_path);
// Python uses the system multibyte code page for sys.executable.