1// Copyright (c) 2016, 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 "platform/globals.h"
6#if defined(HOST_OS_FUCHSIA)
7
8#include "bin/platform.h"
9
10#include <string.h>
11#include <sys/utsname.h>
12#include <unistd.h>
13#include <zircon/process.h>
14#include <zircon/status.h>
15#include <zircon/syscalls.h>
16
17#include "bin/console.h"
18#include "bin/dartutils.h"
19#include "bin/fdutils.h"
20#include "bin/file.h"
21
22namespace dart {
23namespace bin {
24
25const char* Platform::executable_name_ = NULL;
26char* Platform::resolved_executable_name_ = NULL;
27int Platform::script_index_ = 1;
28char** Platform::argv_ = NULL;
29
30bool Platform::Initialize() {
31 return true;
32}
33
34int Platform::NumberOfProcessors() {
35 return sysconf(_SC_NPROCESSORS_CONF);
36}
37
38const char* Platform::OperatingSystem() {
39 return "fuchsia";
40}
41
42const char* Platform::OperatingSystemVersion() {
43 struct utsname info;
44 int ret = uname(&info);
45 if (ret != 0) {
46 return NULL;
47 }
48 const char* kFormat = "%s %s %s";
49 int len =
50 snprintf(NULL, 0, kFormat, info.sysname, info.release, info.version);
51 if (len <= 0) {
52 return NULL;
53 }
54 char* result = DartUtils::ScopedCString(len + 1);
55 ASSERT(result != NULL);
56 len = snprintf(result, len + 1, kFormat, info.sysname, info.release,
57 info.version);
58 if (len <= 0) {
59 return NULL;
60 }
61 return result;
62}
63
64const char* Platform::LibraryPrefix() {
65 return "lib";
66}
67
68const char* Platform::LibraryExtension() {
69 return "so";
70}
71
72const char* Platform::LocaleName() {
73 char* lang = getenv("LANG");
74 if (lang == NULL) {
75 return "en_US";
76 }
77 return lang;
78}
79
80bool Platform::LocalHostname(char* buffer, intptr_t buffer_length) {
81 return gethostname(buffer, buffer_length) == 0;
82}
83
84char** Platform::Environment(intptr_t* count) {
85 // Using environ directly is only safe as long as we do not
86 // provide access to modifying environment variables.
87 intptr_t i = 0;
88 char** tmp = environ;
89 while (*(tmp++) != NULL) {
90 i++;
91 }
92 *count = i;
93 char** result;
94 result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
95 for (intptr_t current = 0; current < i; current++) {
96 result[current] = environ[current];
97 }
98 return result;
99}
100
101const char* Platform::GetExecutableName() {
102 if (executable_name_ != NULL) {
103 return executable_name_;
104 }
105 char* name = DartUtils::ScopedCString(ZX_MAX_NAME_LEN);
106 zx_status_t status = zx_object_get_property(zx_process_self(), ZX_PROP_NAME,
107 name, ZX_MAX_NAME_LEN);
108 if (status != ZX_OK) {
109 return NULL;
110 }
111 return name;
112}
113
114const char* Platform::ResolveExecutablePath() {
115 const char* executable_name = Platform::GetExecutableName();
116 if (executable_name == NULL) {
117 return NULL;
118 }
119 if ((executable_name[0] == '/') && File::Exists(NULL, executable_name)) {
120 return File::GetCanonicalPath(NULL, executable_name);
121 }
122 if (strchr(executable_name, '/') != NULL) {
123 const char* result = File::GetCanonicalPath(NULL, executable_name);
124 if (File::Exists(NULL, result)) {
125 return result;
126 }
127 } else {
128 const char* path = getenv("PATH");
129 if (path == NULL) {
130 // If PATH isn't set, make some guesses about where we should look.
131 path = "/system/bin:/system/apps:/boot/bin";
132 }
133 char* pathcopy = DartUtils::ScopedCopyCString(path);
134 char* result = DartUtils::ScopedCString(PATH_MAX + 1);
135 char* save = NULL;
136 while ((pathcopy = strtok_r(pathcopy, ":", &save)) != NULL) {
137 snprintf(result, PATH_MAX, "%s/%s", pathcopy, executable_name);
138 result[PATH_MAX] = '\0';
139 if (File::Exists(NULL, result)) {
140 return File::GetCanonicalPath(NULL, result);
141 }
142 pathcopy = NULL;
143 }
144 }
145 // Couldn't find it. This causes null to be returned for
146 // Platform.resovledExecutable.
147 return NULL;
148}
149
150intptr_t Platform::ResolveExecutablePathInto(char* result, size_t result_size) {
151 return -1;
152}
153
154void Platform::Exit(int exit_code) {
155 Console::RestoreConfig();
156 Dart_PrepareToAbort();
157 exit(exit_code);
158}
159
160void Platform::SetCoreDumpResourceLimit(int value) {
161 // Not supported.
162}
163
164} // namespace bin
165} // namespace dart
166
167#endif // defined(HOST_OS_FUCHSIA)
168