adb_utils.cpp revision a9e2b99a7fdd31bcd6d852c6db26fe592236a24f
15830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes/* 25830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * Copyright (C) 2015 The Android Open Source Project 35830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * 45830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 55830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * you may not use this file except in compliance with the License. 65830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * You may obtain a copy of the License at 75830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * 85830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 95830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * 105830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * Unless required by applicable law or agreed to in writing, software 115830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 125830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * See the License for the specific language governing permissions and 145830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes * limitations under the License. 155830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes */ 165830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes 17aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui#define TRACE_TAG ADB 18e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 195830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include "adb_utils.h" 205830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes 2122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low#include <libgen.h> 22a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes#include <stdlib.h> 235830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include <sys/stat.h> 245830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include <sys/types.h> 255830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes#include <unistd.h> 265830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes 27e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#include <algorithm> 28e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 294f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/logging.h> 304f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h> 314f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/strings.h> 32e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 337d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#include "adb.h" 34e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#include "adb_trace.h" 3553daee6a2b415caa0ff3e425c7fa613c834bca61Elliott Hughes#include "sysdeps.h" 3653daee6a2b415caa0ff3e425c7fa613c834bca61Elliott Hughes 37a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#ifdef _WIN32 38a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi# ifndef WIN32_LEAN_AND_MEAN 39a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi# define WIN32_LEAN_AND_MEAN 40a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi# endif 41a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi# include "windows.h" 42a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi# include "shlobj.h" 43a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#endif 44a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi 45787f3442cc7d7b1f07189d77413893e2c2c81447Josh GaoADB_MUTEX_DEFINE(basename_lock); 4622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer LowADB_MUTEX_DEFINE(dirname_lock); 4722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 487d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#if defined(_WIN32) 497d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaoconstexpr char kNullFileName[] = "NUL"; 507d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#else 517d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaoconstexpr char kNullFileName[] = "/dev/null"; 527d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#endif 537d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao 547d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaovoid close_stdin() { 557d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao int fd = unix_open(kNullFileName, O_RDONLY); 567d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao if (fd == -1) { 577d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao fatal_errno("failed to open %s", kNullFileName); 587d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao } 597d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao 607d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) == -1) { 617d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao fatal_errno("failed to redirect stdin to %s", kNullFileName); 627d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao } 637d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao unix_close(fd); 647d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao} 657d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao 66a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughesbool getcwd(std::string* s) { 67a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes char* cwd = getcwd(nullptr, 0); 68a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes if (cwd != nullptr) *s = cwd; 69a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes free(cwd); 70a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes return (cwd != nullptr); 71a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes} 72a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes 735830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughesbool directory_exists(const std::string& path) { 745830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes struct stat sb; 755830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes return lstat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode); 765830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes} 775830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes 785830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughesstd::string escape_arg(const std::string& s) { 795498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes std::string result = s; 805830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes 8184b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes // Escape any ' in the string (before we single-quote the whole thing). 8284b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes // The correct way to do this for the shell is to replace ' with '\'' --- that is, 8384b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes // close the existing single-quoted string, escape a single single-quote, and start 8484b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes // a new single-quoted string. Like the C preprocessor, the shell will concatenate 8584b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes // these pieces into one string. 8684b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes for (size_t i = 0; i < s.size(); ++i) { 8784b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes if (s[i] == '\'') { 8884b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes result.insert(i, "'\\'"); 8984b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes i += 2; 9084b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes } 915830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes } 925498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes 935498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes // Prefix and suffix the whole string with '. 945498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes result.insert(result.begin(), '\''); 955498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes result.push_back('\''); 965830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes return result; 975830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes} 98e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 995c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughesstd::string adb_basename(const std::string& path) { 100787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // Copy path because basename may modify the string passed in. 101787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao std::string result(path); 102787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao 103787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // Use lock because basename() may write to a process global and return a 104787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // pointer to that. Note that this locking strategy only works if all other 105787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // callers to dirname in the process also grab this same lock. 106787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao adb_mutex_lock(&basename_lock); 107787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao 108787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // Note that if std::string uses copy-on-write strings, &str[0] will cause 109787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // the copy to be made, so there is no chance of us accidentally writing to 110787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // the storage for 'path'. 111787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao char* name = basename(&result[0]); 112787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao 113787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // In case dirname returned a pointer to a process global, copy that string 114787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao // before leaving the lock. 115787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao result.assign(name); 116787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao 117787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao adb_mutex_unlock(&basename_lock); 118787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao 119787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao return result; 1205c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes} 1215c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes 12222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Lowstd::string adb_dirname(const std::string& path) { 12322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // Copy path because dirname may modify the string passed in. 124787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao std::string result(path); 12522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 12622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // Use lock because dirname() may write to a process global and return a 12722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // pointer to that. Note that this locking strategy only works if all other 12822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // callers to dirname in the process also grab this same lock. 12922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low adb_mutex_lock(&dirname_lock); 13022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 13122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // Note that if std::string uses copy-on-write strings, &str[0] will cause 13222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // the copy to be made, so there is no chance of us accidentally writing to 13322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // the storage for 'path'. 134787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao char* parent = dirname(&result[0]); 13522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 13622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // In case dirname returned a pointer to a process global, copy that string 13722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // before leaving the lock. 138787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao result.assign(parent); 13922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 14022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low adb_mutex_unlock(&dirname_lock); 14122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 14222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return result; 14314216148210fef447aaed46d5f764844a605d3aeAlex Vallée} 14414216148210fef447aaed46d5f764844a605d3aeAlex Vallée 145a1071c6924654de89e077f50f47271bc3e08c569Spencer Low// Given a relative or absolute filepath, create the directory hierarchy 14622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low// as needed. Returns true if the hierarchy is/was setup. 1475c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughesbool mkdirs(const std::string& path) { 14822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // TODO: all the callers do unlink && mkdirs && adb_creat --- 14922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // that's probably the operation we should expose. 15022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 15122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // Implementation Notes: 15222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // 15322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // Pros: 15422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // - Uses dirname, so does not need to deal with OS_PATH_SEPARATOR. 15522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // - On Windows, uses mingw dirname which accepts '/' and '\\', drive letters 15622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // (C:\foo), UNC paths (\\server\share\dir\dir\file), and Unicode (when 15722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // combined with our adb_mkdir() which takes UTF-8). 15822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // - Is optimistic wrt thinking that a deep directory hierarchy will exist. 15922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // So it does as few stat()s as possible before doing mkdir()s. 16022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // Cons: 16122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // - Recursive, so it uses stack space relative to number of directory 16222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // components. 16322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 16474e0fe73c02531e2aa3c4b9f72527bb7a1731158Josh Gao // If path points to a symlink to a directory, that's fine. 16574e0fe73c02531e2aa3c4b9f72527bb7a1731158Josh Gao struct stat sb; 16674e0fe73c02531e2aa3c4b9f72527bb7a1731158Josh Gao if (stat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) { 16722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return true; 16822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low } 16922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 170a1071c6924654de89e077f50f47271bc3e08c569Spencer Low const std::string parent(adb_dirname(path)); 171a1071c6924654de89e077f50f47271bc3e08c569Spencer Low 17222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // If dirname returned the same path as what we passed in, don't go recursive. 17322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // This can happen on Windows when walking up the directory hierarchy and not 17422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // finding anything that already exists (unlike POSIX that will eventually 17522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low // find . or /). 17622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low if (parent == path) { 17722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low errno = ENOENT; 17822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return false; 17922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low } 18022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 18145b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao // Recursively make parent directories of 'path'. 18222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low if (!mkdirs(parent)) { 18322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return false; 18422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low } 18522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 18645b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao // Now that the parent directory hierarchy of 'path' has been ensured, 187a1071c6924654de89e077f50f47271bc3e08c569Spencer Low // create path itself. 18845b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao if (adb_mkdir(path, 0775) == -1) { 18922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low const int saved_errno = errno; 190a1071c6924654de89e077f50f47271bc3e08c569Spencer Low // If someone else created the directory, that is ok. 191a1071c6924654de89e077f50f47271bc3e08c569Spencer Low if (directory_exists(path)) { 19222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return true; 19322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low } 194a1071c6924654de89e077f50f47271bc3e08c569Spencer Low // There might be a pre-existing file at 'path', or there might have been some other error. 19522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low errno = saved_errno; 19622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return false; 19722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low } 19822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low 19922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low return true; 2005c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes} 2015c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes 202aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cuistd::string dump_hex(const void* data, size_t byte_count) { 203e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes byte_count = std::min(byte_count, size_t(16)); 204e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 205e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes const uint8_t* p = reinterpret_cast<const uint8_t*>(data); 206e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 207e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes std::string line; 208e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes for (size_t i = 0; i < byte_count; ++i) { 209e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes android::base::StringAppendF(&line, "%02x", p[i]); 210e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes } 211e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes line.push_back(' '); 212e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 213e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes for (size_t i = 0; i < byte_count; ++i) { 214363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low int ch = p[i]; 215363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low line.push_back(isprint(ch) ? ch : '.'); 216e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes } 217e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes 218aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui return line; 219e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes} 2203d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes 221aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughesstd::string perror_str(const char* msg) { 222aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes return android::base::StringPrintf("%s: %s", msg, strerror(errno)); 223aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes} 2246dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui 2256dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#if !defined(_WIN32) 226addab3d84dccd01cae9ca7b8a4b274b935f18fd4Josh Gao// Windows version provided in sysdeps_win32.cpp 2276dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cuibool set_file_block_mode(int fd, bool block) { 2286dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui int flags = fcntl(fd, F_GETFL, 0); 2296dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui if (flags == -1) { 2306dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd; 2316dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui return false; 2326dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui } 2336dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); 2346dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui if (fcntl(fd, F_SETFL, flags) != 0) { 2356dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd << ", flags " << flags; 2366dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui return false; 2376dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui } 2386dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui return true; 2396dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui} 2406dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#endif 241a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi 242a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyistd::string adb_get_homedir_path(bool check_env_first) { 243a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#ifdef _WIN32 244a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi if (check_env_first) { 245a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi if (const char* const home = getenv("ANDROID_SDK_HOME")) { 246a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi return home; 247a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi } 248a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi } 249a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi 250a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi WCHAR path[MAX_PATH]; 251a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path); 252a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi if (FAILED(hr)) { 253a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi D("SHGetFolderPathW failed: %s", android::base::SystemErrorCodeToString(hr).c_str()); 254a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi return {}; 255a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi } 256a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi std::string home_str; 257a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi if (!android::base::WideToUTF8(path, &home_str)) { 258a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi return {}; 259a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi } 260a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi return home_str; 261a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#else 262a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi if (const char* const home = getenv("HOME")) { 263a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi return home; 264a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi } 265a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi return {}; 266a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi#endif 267a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi} 268a9e2b99a7fdd31bcd6d852c6db26fe592236a24fYurii Zubrytskyi 269