1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sysdeps.h" 18 19 bool set_tcp_keepalive(borrowed_fd fd, int interval_sec) { 20 int enable = (interval_sec > 0); 21 if (adb_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable))) { 22 return false; 23 } 24 25 if (!enable) { 26 return true; 27 } 28 29 // Idle time before sending the first keepalive is TCP_KEEPIDLE on Linux, TCP_KEEPALIVE on Mac. 30 #if defined(TCP_KEEPIDLE) 31 if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &interval_sec, sizeof(interval_sec))) { 32 return false; 33 } 34 #elif defined(TCP_KEEPALIVE) 35 if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &interval_sec, sizeof(interval_sec))) { 36 return false; 37 } 38 #endif 39 40 // TCP_KEEPINTVL and TCP_KEEPCNT are available on Linux 2.4+ and OS X 10.8+ (Mountain Lion). 41 #if defined(TCP_KEEPINTVL) 42 if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval_sec, sizeof(interval_sec))) { 43 return false; 44 } 45 #endif 46 47 #if defined(TCP_KEEPCNT) 48 // On Windows this value is hardcoded to 10. This is a reasonable value, so we do the same here 49 // to match behavior. See SO_KEEPALIVE documentation at 50 // https://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx. 51 const int keepcnt = 10; 52 if (adb_setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt))) { 53 return false; 54 } 55 #endif 56 57 return true; 58 } 59 60 static __inline__ void disable_close_on_exec(borrowed_fd fd) { 61 const auto oldFlags = fcntl(fd.get(), F_GETFD); 62 const auto newFlags = (oldFlags & ~FD_CLOEXEC); 63 if (newFlags != oldFlags) { 64 fcntl(fd.get(), F_SETFD, newFlags); 65 } 66 } 67 68 Process adb_launch_process(std::string_view executable, std::vector<std::string> args, 69 std::initializer_list<int> fds_to_inherit) { 70 const auto pid = fork(); 71 if (pid != 0) { 72 // parent, includes the case when failed to fork() 73 return Process(pid); 74 } 75 // child 76 std::vector<std::string> copies; 77 copies.reserve(args.size() + 1); 78 copies.emplace_back(executable); 79 copies.insert(copies.end(), std::make_move_iterator(args.begin()), 80 std::make_move_iterator(args.end())); 81 82 std::vector<char*> rawArgs; 83 rawArgs.reserve(copies.size() + 1); 84 for (auto&& str : copies) { 85 rawArgs.push_back(str.data()); 86 } 87 rawArgs.push_back(nullptr); 88 for (auto fd : fds_to_inherit) { 89 disable_close_on_exec(fd); 90 } 91 exit(execv(copies.front().data(), rawArgs.data())); 92 } 93