Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
exe_utils.cc
Go to the documentation of this file.
1// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "bin/exe_utils.h"
6
7#include "bin/directory.h"
8#include "bin/file.h"
9#include "bin/platform.h"
10#include "platform/utils.h"
11
12namespace dart {
13namespace bin {
14
15static bool StartsWithPathSeparator(const char* path,
16 const char* sep,
17 intptr_t sep_length) {
18 return (strncmp(path, sep, sep_length) == 0
19#if defined(DART_HOST_OS_WINDOWS)
20 // TODO(aam): GetExecutableName doesn't work reliably on Windows,
21 || *path == '/'
22#endif
23 ); // NOLINT
24}
25
26// Returns the directory portion of a given path.
27//
28// If dir is nullptr, the result must be freed by the caller. Otherwise, the
29// result is copied into dir.
30static char* GetDirectoryFromPath(const char* path, char* dir) {
31 const char* sep = File::PathSeparator();
32 const intptr_t sep_length = strlen(sep);
33 intptr_t path_len = strlen(path);
34
35 for (intptr_t i = path_len - 1; i >= 0; --i) {
36 const char* str = path + i;
37 if (StartsWithPathSeparator(str, sep, sep_length)) {
38 if (dir != nullptr) {
39 strncpy(dir, path, i);
40 dir[i] = '\0';
41 return dir;
42 } else {
43 return Utils::StrNDup(path, i + 1);
44 }
45 }
46 }
47 return nullptr;
48}
49
50// Returns the file portion of a given path. Returned string is either
51// `path` if no path separators are found or `path + separator_loc + sep_length`
52// if a separator is found.
53static const char* GetFileNameFromPath(const char* path) {
54 const char* sep = File::PathSeparator();
55 const intptr_t sep_length = strlen(sep);
56 intptr_t path_len = strlen(path);
57
58 for (intptr_t i = path_len - 1; i >= 0; --i) {
59 const char* str = path + i;
60 if (StartsWithPathSeparator(str, sep, sep_length)) {
61 return str + sep_length;
62 }
63 }
64 // No path separators, assume that path is a file name.
65 return path;
66}
67
69 const char* name = nullptr;
70 const int kTargetSize = PATH_MAX;
71 char target[kTargetSize];
72 intptr_t target_size =
74 if (target_size > 0 && target_size < kTargetSize - 1) {
75 target[target_size] = 0;
76 name = target;
77 }
78 if (name == nullptr) {
80 target_size = strlen(name);
81 ASSERT(target_size < kTargetSize);
82 }
84 char* result;
85 if (File::GetType(namespc, name, false) == File::kIsLink) {
86 char dir_path[kTargetSize];
87 // cwd is currently wherever we launched from, so set the cwd to the
88 // directory of the symlink while we try and resolve it. If we don't
89 // do this, we won't be able to properly resolve relative paths.
90 auto initial_dir_path =
92 // We might run into symlinks of symlinks, so make sure we follow the
93 // links all the way. See https://github.com/dart-lang/sdk/issues/41057 for
94 // an example where this happens with brew on MacOS.
95 do {
97 // Resolve the link without creating Dart scope String.
99 kTargetSize);
100 if (name == nullptr) {
102 }
103 } while (File::GetType(namespc, name, false) == File::kIsLink);
104 target_size = strlen(name);
105
106 char absolute_path[kTargetSize];
107
108 // Get the absolute path after we've resolved all the symlinks and before
109 // we reset the cwd, otherwise path resolution will fail.
110 File::GetCanonicalPath(namespc, name, absolute_path, kTargetSize);
111
112 // Reset cwd to the original value.
113 Directory::SetCurrent(namespc, initial_dir_path.get());
114
115 result = GetDirectoryFromPath(absolute_path, nullptr);
116 } else {
118 }
119 namespc->Release();
121 : result);
122}
123
124#if !defined(DART_HOST_OS_WINDOWS)
125void EXEUtils::LoadDartProfilerSymbols(const char* argv0) {
126 char* path = reinterpret_cast<char*>(malloc(PATH_MAX + 5));
127 if (Platform::ResolveExecutablePathInto(path, PATH_MAX) <= 0) return;
128
129 int len = strlen(path);
130 memcpy(path + len, ".sym", 5); // NOLINT
131 File* file = File::Open(nullptr, path, File::kRead);
132 free(path);
133 if (file == nullptr) return;
134
135 int64_t size = file->Length();
136 MappedMemory* mapping = file->Map(File::kReadOnly, 0, size);
137 Dart_AddSymbols(argv0, mapping->address(), size);
138 mapping->Leak(); // Let us delete the object but keep the mapping.
139 delete mapping;
140 file->Release();
141}
142#endif // !defined(DART_HOST_OS_WINDOWS)
143
144} // namespace bin
145} // namespace dart
static char * StrDup(const char *s)
static CStringUniquePtr CreateCStringUniquePtr(char *str)
Definition utils.cc:257
std::unique_ptr< char, decltype(std::free) * > CStringUniquePtr
Definition utils.h:644
static char * StrNDup(const char *s, intptr_t n)
static bool SetCurrent(Namespace *namespc, const char *path)
Definition directory.cc:562
static char * CurrentNoScope()
static Utils::CStringUniquePtr GetDirectoryPrefixFromExeName()
Definition exe_utils.cc:68
static void LoadDartProfilerSymbols(const char *exepath)
Definition exe_utils.cc:125
static const char * GetCanonicalPath(Namespace *namespc, const char *path, char *dest=nullptr, int dest_size=0)
static const char * PathSeparator()
static File * Open(Namespace *namespc, const char *path, FileOpenMode mode)
static const char * LinkTarget(Namespace *namespc, const char *pathname, char *dest=nullptr, int dest_size=0)
static Type GetType(Namespace *namespc, const char *path, bool follow_links)
void * address() const
Definition file.h:34
static Namespace * Create(intptr_t namespc)
static intptr_t Default()
static const char * GetExecutableName()
static intptr_t ResolveExecutablePathInto(char *result, size_t result_size)
#define ASSERT(E)
GAsyncResult * result
uint32_t * target
static char * GetDirectoryFromPath(const char *path, char *dir)
Definition exe_utils.cc:30
static bool StartsWithPathSeparator(const char *path, const char *sep, intptr_t sep_length)
Definition exe_utils.cc:15
static const char * GetFileNameFromPath(const char *path)
Definition exe_utils.cc:53
const char *const name
void * malloc(size_t size)
Definition allocation.cc:19
DART_EXPORT void Dart_AddSymbols(const char *dso_name, void *buffer, intptr_t buffer_size)
#define PATH_MAX
Definition globals.h:708