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