adb_utils.cpp revision 7d586073609723cb2f6ed37de0ad1a7996e621ae
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
293d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes#include <base/logging.h>
30e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#include <base/stringprintf.h>
313d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes#include <base/strings.h>
32e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
337d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#include "adb.h"
34e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes#include "adb_trace.h"
3553daee6a2b415caa0ff3e425c7fa613c834bca61Elliott Hughes#include "sysdeps.h"
3653daee6a2b415caa0ff3e425c7fa613c834bca61Elliott Hughes
37787f3442cc7d7b1f07189d77413893e2c2c81447Josh GaoADB_MUTEX_DEFINE(basename_lock);
3822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer LowADB_MUTEX_DEFINE(dirname_lock);
3922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
407d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#if defined(_WIN32)
417d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaoconstexpr char kNullFileName[] = "NUL";
427d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#else
437d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaoconstexpr char kNullFileName[] = "/dev/null";
447d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao#endif
457d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao
467d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gaovoid close_stdin() {
477d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    int fd = unix_open(kNullFileName, O_RDONLY);
487d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    if (fd == -1) {
497d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao        fatal_errno("failed to open %s", kNullFileName);
507d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    }
517d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao
527d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) == -1) {
537d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao        fatal_errno("failed to redirect stdin to %s", kNullFileName);
547d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    }
557d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao    unix_close(fd);
567d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao}
577d586073609723cb2f6ed37de0ad1a7996e621aeJosh Gao
58a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughesbool getcwd(std::string* s) {
59a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  char* cwd = getcwd(nullptr, 0);
60a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  if (cwd != nullptr) *s = cwd;
61a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  free(cwd);
62a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes  return (cwd != nullptr);
63a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes}
64a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes
655830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughesbool directory_exists(const std::string& path) {
665830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  struct stat sb;
675830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  return lstat(path.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode);
685830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes}
695830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
705830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughesstd::string escape_arg(const std::string& s) {
715498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  std::string result = s;
725830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes
7384b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // Escape any ' in the string (before we single-quote the whole thing).
7484b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // The correct way to do this for the shell is to replace ' with '\'' --- that is,
7584b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // close the existing single-quoted string, escape a single single-quote, and start
7684b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // a new single-quoted string. Like the C preprocessor, the shell will concatenate
7784b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  // these pieces into one string.
7884b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes  for (size_t i = 0; i < s.size(); ++i) {
7984b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes    if (s[i] == '\'') {
8084b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes      result.insert(i, "'\\'");
8184b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes      i += 2;
8284b0bf22644b35d6b3d3f7dc96311a484c3519b3Elliott Hughes    }
835830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  }
845498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes
855498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  // Prefix and suffix the whole string with '.
865498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  result.insert(result.begin(), '\'');
875498adefb00cd979137361b98fcbf8d51f72ebebElliott Hughes  result.push_back('\'');
885830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes  return result;
895830577bd82fdb7c39555da20a4cf585b8bb376aElliott Hughes}
90e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
915c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughesstd::string adb_basename(const std::string& path) {
92787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // Copy path because basename may modify the string passed in.
93787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  std::string result(path);
94787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao
95787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // Use lock because basename() may write to a process global and return a
96787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // pointer to that. Note that this locking strategy only works if all other
97787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // callers to dirname in the process also grab this same lock.
98787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  adb_mutex_lock(&basename_lock);
99787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao
100787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // Note that if std::string uses copy-on-write strings, &str[0] will cause
101787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // the copy to be made, so there is no chance of us accidentally writing to
102787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // the storage for 'path'.
103787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  char* name = basename(&result[0]);
104787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao
105787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // In case dirname returned a pointer to a process global, copy that string
106787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  // before leaving the lock.
107787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  result.assign(name);
108787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao
109787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  adb_mutex_unlock(&basename_lock);
110787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao
111787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  return result;
1125c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes}
1135c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes
11422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Lowstd::string adb_dirname(const std::string& path) {
11522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Copy path because dirname may modify the string passed in.
116787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  std::string result(path);
11722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
11822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Use lock because dirname() may write to a process global and return a
11922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // pointer to that. Note that this locking strategy only works if all other
12022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // callers to dirname in the process also grab this same lock.
12122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  adb_mutex_lock(&dirname_lock);
12222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
12322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Note that if std::string uses copy-on-write strings, &str[0] will cause
12422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // the copy to be made, so there is no chance of us accidentally writing to
12522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // the storage for 'path'.
126787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  char* parent = dirname(&result[0]);
12722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
12822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // In case dirname returned a pointer to a process global, copy that string
12922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // before leaving the lock.
130787f3442cc7d7b1f07189d77413893e2c2c81447Josh Gao  result.assign(parent);
13122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
13222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  adb_mutex_unlock(&dirname_lock);
13322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
13422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  return result;
13514216148210fef447aaed46d5f764844a605d3aeAlex Vallée}
13614216148210fef447aaed46d5f764844a605d3aeAlex Vallée
13722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low// Given a relative or absolute filepath, create the parent directory hierarchy
13822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low// as needed. Returns true if the hierarchy is/was setup.
1395c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughesbool mkdirs(const std::string& path) {
14022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // TODO: all the callers do unlink && mkdirs && adb_creat ---
14122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // that's probably the operation we should expose.
14222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
14322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Implementation Notes:
14422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //
14522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Pros:
14622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - Uses dirname, so does not need to deal with OS_PATH_SEPARATOR.
14722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - On Windows, uses mingw dirname which accepts '/' and '\\', drive letters
14822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   (C:\foo), UNC paths (\\server\share\dir\dir\file), and Unicode (when
14922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   combined with our adb_mkdir() which takes UTF-8).
15022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - Is optimistic wrt thinking that a deep directory hierarchy will exist.
15122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   So it does as few stat()s as possible before doing mkdir()s.
15222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // Cons:
15322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // - Recursive, so it uses stack space relative to number of directory
15422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  //   components.
15522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
15645b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  if (directory_exists(path)) {
15722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return true;
15822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
15922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
16022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // If dirname returned the same path as what we passed in, don't go recursive.
16122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // This can happen on Windows when walking up the directory hierarchy and not
16222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // finding anything that already exists (unlike POSIX that will eventually
16322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // find . or /).
16445b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  const std::string parent(adb_dirname(path));
16545b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao
16622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  if (parent == path) {
16722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    errno = ENOENT;
16822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return false;
16922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
17022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
17145b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  // Recursively make parent directories of 'path'.
17222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  if (!mkdirs(parent)) {
17322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return false;
17422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
17522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
17645b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  // Now that the parent directory hierarchy of 'path' has been ensured,
17722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  // create parent itself.
17845b6fc878ab5ba0f76b6bb1947fe04ac6667c2f5Josh Gao  if (adb_mkdir(path, 0775) == -1) {
17922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    // Can't just check for errno == EEXIST because it might be a file that
18022191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    // exists.
18122191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    const int saved_errno = errno;
18222191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    if (directory_exists(parent)) {
18322191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low      return true;
18422191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    }
18522191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    errno = saved_errno;
18622191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low    return false;
18722191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  }
18822191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low
18922191c30a63da7ca951281fffcb1fd59ae40dd54Spencer Low  return true;
1905c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes}
1915c74270f95107952a893584d02b33f9a79f6b3c4Elliott Hughes
192aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cuistd::string dump_hex(const void* data, size_t byte_count) {
193e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    byte_count = std::min(byte_count, size_t(16));
194e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
195e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
196e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
197e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    std::string line;
198e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    for (size_t i = 0; i < byte_count; ++i) {
199e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes        android::base::StringAppendF(&line, "%02x", p[i]);
200e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    }
201e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    line.push_back(' ');
202e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
203e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    for (size_t i = 0; i < byte_count; ++i) {
204363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low        int ch = p[i];
205363af568b8491af1a4256b09b04cfa8a0606d8ccSpencer Low        line.push_back(isprint(ch) ? ch : '.');
206e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes    }
207e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes
208aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui    return line;
209e67f1f87d9b1188ec8617035db7006c37ee7b21eElliott Hughes}
2103d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
2113d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughesbool parse_host_and_port(const std::string& address,
2123d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                         std::string* canonical_address,
2133d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                         std::string* host, int* port,
2143d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                         std::string* error) {
2153d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    host->clear();
2163d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
2173d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    bool ipv6 = true;
2183d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    bool saw_port = false;
2193d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    size_t colons = std::count(address.begin(), address.end(), ':');
2203d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    size_t dots = std::count(address.begin(), address.end(), '.');
2213d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    std::string port_str;
2223d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    if (address[0] == '[') {
2233d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      // [::1]:123
2243d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      if (address.rfind("]:") == std::string::npos) {
2253d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        *error = android::base::StringPrintf("bad IPv6 address '%s'", address.c_str());
2263d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        return false;
2273d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      }
2283d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      *host = address.substr(1, (address.find("]:") - 1));
2293d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      port_str = address.substr(address.rfind("]:") + 2);
2303d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      saw_port = true;
2313d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    } else if (dots == 0 && colons >= 2 && colons <= 7) {
2323d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      // ::1
2333d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      *host = address;
2343d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    } else if (colons <= 1) {
2353d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      // 1.2.3.4 or some.accidental.domain.com
2363d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      ipv6 = false;
2373d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      std::vector<std::string> pieces = android::base::Split(address, ":");
2383d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      *host = pieces[0];
2393d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      if (pieces.size() > 1) {
2403d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        port_str = pieces[1];
2413d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        saw_port = true;
2423d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      }
2433d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    }
2443d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
2453d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    if (host->empty()) {
2463d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      *error = android::base::StringPrintf("no host in '%s'", address.c_str());
2473d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      return false;
2483d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    }
2493d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
2503d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    if (saw_port) {
2513d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      if (sscanf(port_str.c_str(), "%d", port) != 1 || *port <= 0 || *port > 65535) {
2523d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        *error = android::base::StringPrintf("bad port number '%s' in '%s'",
2533d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes                                             port_str.c_str(), address.c_str());
2543d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes        return false;
2553d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes      }
2563d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    }
2573d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes
2583d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    *canonical_address = android::base::StringPrintf(ipv6 ? "[%s]:%d" : "%s:%d", host->c_str(), *port);
2593d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    LOG(DEBUG) << "parsed " << address << " as " << *host << " and " << *port
2603d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes               << " (" << *canonical_address << ")";
2613d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes    return true;
2623d5f60dbba3bc0feabc05457d181547b295bb3b2Elliott Hughes}
263aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes
264aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughesstd::string perror_str(const char* msg) {
265aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes    return android::base::StringPrintf("%s: %s", msg, strerror(errno));
266aa2454919098ee14cd232669f1e7dbb33ed07ccfElliott Hughes}
2676dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui
2686dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#if !defined(_WIN32)
2696dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cuibool set_file_block_mode(int fd, bool block) {
2706dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    int flags = fcntl(fd, F_GETFL, 0);
2716dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    if (flags == -1) {
2726dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        PLOG(ERROR) << "failed to fcntl(F_GETFL) for fd " << fd;
2736dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        return false;
2746dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    }
2756dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    flags = block ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
2766dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    if (fcntl(fd, F_SETFL, flags) != 0) {
2776dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        PLOG(ERROR) << "failed to fcntl(F_SETFL) for fd " << fd << ", flags " << flags;
2786dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui        return false;
2796dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    }
2806dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui    return true;
2816dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui}
2826dfef255b8fa77e3b5c0a69b7f276ea8e25e22cdYabin Cui#endif
283