| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bin/dartutils.h" | 5 #include "bin/dartutils.h" |
| 6 #include "bin/dbg_connection.h" | 6 #include "bin/dbg_connection.h" |
| 7 #include "bin/eventhandler.h" | 7 #include "bin/eventhandler.h" |
| 8 #include "bin/io_buffer.h" | 8 #include "bin/io_buffer.h" |
| 9 #include "bin/log.h" |
| 9 #include "bin/platform.h" | 10 #include "bin/platform.h" |
| 10 #include "bin/process.h" | 11 #include "bin/process.h" |
| 11 #include "bin/socket.h" | 12 #include "bin/socket.h" |
| 12 #include "bin/utils.h" | 13 #include "bin/utils.h" |
| 13 | 14 |
| 14 #include "include/dart_api.h" | 15 #include "include/dart_api.h" |
| 15 | 16 |
| 16 namespace dart { | 17 namespace dart { |
| 17 namespace bin { | 18 namespace bin { |
| 18 | 19 |
| 20 // Global flag that is used to indicate that the VM should do a clean |
| 21 // shutdown. |
| 22 bool do_vm_shutdown = true; |
| 23 |
| 19 static const int kProcessIdNativeField = 0; | 24 static const int kProcessIdNativeField = 0; |
| 20 | 25 |
| 21 int Process::global_exit_code_ = 0; | 26 int Process::global_exit_code_ = 0; |
| 22 Mutex* Process::global_exit_code_mutex_ = new Mutex(); | 27 Mutex* Process::global_exit_code_mutex_ = new Mutex(); |
| 23 | 28 |
| 24 // Extract an array of C strings from a list of Dart strings. | 29 // Extract an array of C strings from a list of Dart strings. |
| 25 static char** ExtractCStringList(Dart_Handle strings, | 30 static char** ExtractCStringList(Dart_Handle strings, |
| 26 Dart_Handle status_handle, | 31 Dart_Handle status_handle, |
| 27 const char* error_msg, | 32 const char* error_msg, |
| 28 intptr_t* length) { | 33 intptr_t* length) { |
| 29 static const intptr_t kMaxArgumentListLength = 1024 * 1024; | 34 static const intptr_t kMaxArgumentListLength = 1024 * 1024; |
| 30 ASSERT(Dart_IsList(strings)); | 35 ASSERT(Dart_IsList(strings)); |
| 31 intptr_t len = 0; | 36 intptr_t len = 0; |
| 32 Dart_Handle result = Dart_ListLength(strings, &len); | 37 Dart_Handle result = Dart_ListLength(strings, &len); |
| 33 if (Dart_IsError(result)) { | 38 if (Dart_IsError(result)) { |
| 34 Dart_PropagateError(result); | 39 Dart_PropagateError(result); |
| 35 } | 40 } |
| 36 // Protect against user-defined list implementations that can have | 41 // Protect against user-defined list implementations that can have |
| 37 // arbitrary length. | 42 // arbitrary length. |
| 38 if (len < 0 || len > kMaxArgumentListLength) { | 43 if (len < 0 || len > kMaxArgumentListLength) { |
| 39 DartUtils::SetIntegerField(status_handle, "_errorCode", 0); | 44 result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0); |
| 40 DartUtils::SetStringField( | 45 if (Dart_IsError(result)) { |
| 46 Dart_PropagateError(result); |
| 47 } |
| 48 result = DartUtils::SetStringField( |
| 41 status_handle, "_errorMessage", "Max argument list length exceeded"); | 49 status_handle, "_errorMessage", "Max argument list length exceeded"); |
| 50 if (Dart_IsError(result)) { |
| 51 Dart_PropagateError(result); |
| 52 } |
| 42 return NULL; | 53 return NULL; |
| 43 } | 54 } |
| 44 *length = len; | 55 *length = len; |
| 45 char** string_args = new char*[len]; | 56 char** string_args = new char*[len]; |
| 46 for (int i = 0; i < len; i++) { | 57 for (int i = 0; i < len; i++) { |
| 47 Dart_Handle arg = Dart_ListGetAt(strings, i); | 58 Dart_Handle arg = Dart_ListGetAt(strings, i); |
| 48 if (Dart_IsError(arg)) { | 59 if (Dart_IsError(arg)) { |
| 49 delete[] string_args; | 60 delete[] string_args; |
| 50 Dart_PropagateError(arg); | 61 Dart_PropagateError(arg); |
| 51 } | 62 } |
| 52 if (!Dart_IsString(arg)) { | 63 if (!Dart_IsString(arg)) { |
| 53 DartUtils::SetIntegerField(status_handle, "_errorCode", 0); | 64 result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0); |
| 54 DartUtils::SetStringField( | 65 if (Dart_IsError(result)) { |
| 66 Dart_PropagateError(result); |
| 67 } |
| 68 result = DartUtils::SetStringField( |
| 55 status_handle, "_errorMessage", error_msg); | 69 status_handle, "_errorMessage", error_msg); |
| 70 if (Dart_IsError(result)) { |
| 71 Dart_PropagateError(result); |
| 72 } |
| 56 delete[] string_args; | 73 delete[] string_args; |
| 57 return NULL; | 74 return NULL; |
| 58 } | 75 } |
| 59 string_args[i] = const_cast<char *>(DartUtils::GetStringValue(arg)); | 76 string_args[i] = const_cast<char *>(DartUtils::GetStringValue(arg)); |
| 60 } | 77 } |
| 61 return string_args; | 78 return string_args; |
| 62 } | 79 } |
| 63 | 80 |
| 64 void FUNCTION_NAME(Process_Start)(Dart_NativeArguments args) { | 81 void FUNCTION_NAME(Process_Start)(Dart_NativeArguments args) { |
| 65 Dart_Handle process = Dart_GetNativeArgument(args, 0); | 82 Dart_Handle process = Dart_GetNativeArgument(args, 0); |
| 66 intptr_t process_stdin; | 83 intptr_t process_stdin; |
| 67 intptr_t process_stdout; | 84 intptr_t process_stdout; |
| 68 intptr_t process_stderr; | 85 intptr_t process_stderr; |
| 69 intptr_t exit_event; | 86 intptr_t exit_event; |
| 87 Dart_Handle result; |
| 70 Dart_Handle status_handle = Dart_GetNativeArgument(args, 10); | 88 Dart_Handle status_handle = Dart_GetNativeArgument(args, 10); |
| 71 Dart_Handle path_handle = Dart_GetNativeArgument(args, 1); | 89 Dart_Handle path_handle = Dart_GetNativeArgument(args, 1); |
| 72 // The Dart code verifies that the path implements the String | 90 // The Dart code verifies that the path implements the String |
| 73 // interface. However, only builtin Strings are handled by | 91 // interface. However, only builtin Strings are handled by |
| 74 // GetStringValue. | 92 // GetStringValue. |
| 75 if (!Dart_IsString(path_handle)) { | 93 if (!Dart_IsString(path_handle)) { |
| 76 DartUtils::SetIntegerField(status_handle, "_errorCode", 0); | 94 result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0); |
| 77 DartUtils::SetStringField( | 95 if (Dart_IsError(result)) { |
| 96 Dart_PropagateError(result); |
| 97 } |
| 98 result = DartUtils::SetStringField( |
| 78 status_handle, "_errorMessage", "Path must be a builtin string"); | 99 status_handle, "_errorMessage", "Path must be a builtin string"); |
| 100 if (Dart_IsError(result)) { |
| 101 Dart_PropagateError(result); |
| 102 } |
| 79 Dart_SetReturnValue(args, Dart_NewBoolean(false)); | 103 Dart_SetReturnValue(args, Dart_NewBoolean(false)); |
| 80 return; | 104 return; |
| 81 } | 105 } |
| 82 const char* path = DartUtils::GetStringValue(path_handle); | 106 const char* path = DartUtils::GetStringValue(path_handle); |
| 83 Dart_Handle arguments = Dart_GetNativeArgument(args, 2); | 107 Dart_Handle arguments = Dart_GetNativeArgument(args, 2); |
| 84 intptr_t args_length = 0; | 108 intptr_t args_length = 0; |
| 85 char** string_args = | 109 char** string_args = |
| 86 ExtractCStringList(arguments, | 110 ExtractCStringList(arguments, |
| 87 status_handle, | 111 status_handle, |
| 88 "Arguments must be builtin strings", | 112 "Arguments must be builtin strings", |
| 89 &args_length); | 113 &args_length); |
| 90 if (string_args == NULL) { | 114 if (string_args == NULL) { |
| 91 Dart_SetReturnValue(args, Dart_NewBoolean(false)); | 115 Dart_SetReturnValue(args, Dart_NewBoolean(false)); |
| 92 return; | 116 return; |
| 93 } | 117 } |
| 94 Dart_Handle working_directory_handle = Dart_GetNativeArgument(args, 3); | 118 Dart_Handle working_directory_handle = Dart_GetNativeArgument(args, 3); |
| 95 // Defaults to the current working directoy. | 119 // Defaults to the current working directoy. |
| 96 const char* working_directory = NULL; | 120 const char* working_directory = NULL; |
| 97 if (Dart_IsString(working_directory_handle)) { | 121 if (Dart_IsString(working_directory_handle)) { |
| 98 working_directory = DartUtils::GetStringValue(working_directory_handle); | 122 working_directory = DartUtils::GetStringValue(working_directory_handle); |
| 99 } else if (!Dart_IsNull(working_directory_handle)) { | 123 } else if (!Dart_IsNull(working_directory_handle)) { |
| 100 delete[] string_args; | 124 delete[] string_args; |
| 101 DartUtils::SetIntegerField(status_handle, "_errorCode", 0); | 125 result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0); |
| 102 DartUtils::SetStringField( | 126 if (Dart_IsError(result)) { |
| 127 Dart_PropagateError(result); |
| 128 } |
| 129 result = DartUtils::SetStringField( |
| 103 status_handle, "_errorMessage", | 130 status_handle, "_errorMessage", |
| 104 "WorkingDirectory must be a builtin string"); | 131 "WorkingDirectory must be a builtin string"); |
| 132 if (Dart_IsError(result)) { |
| 133 Dart_PropagateError(result); |
| 134 } |
| 105 Dart_SetReturnValue(args, Dart_NewBoolean(false)); | 135 Dart_SetReturnValue(args, Dart_NewBoolean(false)); |
| 106 return; | 136 return; |
| 107 } | 137 } |
| 108 Dart_Handle environment = Dart_GetNativeArgument(args, 4); | 138 Dart_Handle environment = Dart_GetNativeArgument(args, 4); |
| 109 intptr_t environment_length = 0; | 139 intptr_t environment_length = 0; |
| 110 char** string_environment = NULL; | 140 char** string_environment = NULL; |
| 111 if (!Dart_IsNull(environment)) { | 141 if (!Dart_IsNull(environment)) { |
| 112 string_environment = | 142 string_environment = |
| 113 ExtractCStringList(environment, | 143 ExtractCStringList(environment, |
| 114 status_handle, | 144 status_handle, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 if (mode != kDetached) { | 176 if (mode != kDetached) { |
| 147 Socket::SetSocketIdNativeField(stdin_handle, process_stdin); | 177 Socket::SetSocketIdNativeField(stdin_handle, process_stdin); |
| 148 Socket::SetSocketIdNativeField(stdout_handle, process_stdout); | 178 Socket::SetSocketIdNativeField(stdout_handle, process_stdout); |
| 149 Socket::SetSocketIdNativeField(stderr_handle, process_stderr); | 179 Socket::SetSocketIdNativeField(stderr_handle, process_stderr); |
| 150 } | 180 } |
| 151 if (mode == kNormal) { | 181 if (mode == kNormal) { |
| 152 Socket::SetSocketIdNativeField(exit_handle, exit_event); | 182 Socket::SetSocketIdNativeField(exit_handle, exit_event); |
| 153 } | 183 } |
| 154 Process::SetProcessIdNativeField(process, pid); | 184 Process::SetProcessIdNativeField(process, pid); |
| 155 } else { | 185 } else { |
| 156 DartUtils::SetIntegerField( | 186 result = DartUtils::SetIntegerField( |
| 157 status_handle, "_errorCode", error_code); | 187 status_handle, "_errorCode", error_code); |
| 158 DartUtils::SetStringField( | 188 if (Dart_IsError(result)) { |
| 189 Dart_PropagateError(result); |
| 190 } |
| 191 result = DartUtils::SetStringField( |
| 159 status_handle, | 192 status_handle, |
| 160 "_errorMessage", | 193 "_errorMessage", |
| 161 os_error_message != NULL ? os_error_message | 194 os_error_message != NULL ? os_error_message |
| 162 : "Cannot get error message"); | 195 : "Cannot get error message"); |
| 196 if (Dart_IsError(result)) { |
| 197 Dart_PropagateError(result); |
| 198 } |
| 163 } | 199 } |
| 164 delete[] string_args; | 200 delete[] string_args; |
| 165 delete[] string_environment; | 201 delete[] string_environment; |
| 166 free(os_error_message); | 202 free(os_error_message); |
| 167 Dart_SetReturnValue(args, Dart_NewBoolean(error_code == 0)); | 203 Dart_SetReturnValue(args, Dart_NewBoolean(error_code == 0)); |
| 168 } | 204 } |
| 169 | 205 |
| 170 | 206 |
| 171 void FUNCTION_NAME(Process_Wait)(Dart_NativeArguments args) { | 207 void FUNCTION_NAME(Process_Wait)(Dart_NativeArguments args) { |
| 172 Dart_Handle process = Dart_GetNativeArgument(args, 0); | 208 Dart_Handle process = Dart_GetNativeArgument(args, 0); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 intptr_t signal = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); | 247 intptr_t signal = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1)); |
| 212 bool success = Process::Kill(pid, signal); | 248 bool success = Process::Kill(pid, signal); |
| 213 Dart_SetReturnValue(args, Dart_NewBoolean(success)); | 249 Dart_SetReturnValue(args, Dart_NewBoolean(success)); |
| 214 } | 250 } |
| 215 | 251 |
| 216 | 252 |
| 217 void FUNCTION_NAME(Process_Exit)(Dart_NativeArguments args) { | 253 void FUNCTION_NAME(Process_Exit)(Dart_NativeArguments args) { |
| 218 int64_t status = 0; | 254 int64_t status = 0; |
| 219 // Ignore result if passing invalid argument and just exit 0. | 255 // Ignore result if passing invalid argument and just exit 0. |
| 220 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status); | 256 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status); |
| 221 Dart_ExitIsolate(); | 257 Dart_ShutdownIsolate(); |
| 222 Dart_Cleanup(); | 258 Process::TerminateExitCodeHandler(); |
| 223 DebuggerConnectionHandler::StopHandler(); | 259 char* error = Dart_Cleanup(); |
| 224 // TODO(zra): Stop the EventHandler once thread shutdown is enabled. | 260 if (error != NULL) { |
| 225 // EventHandler::Stop(); | 261 Log::PrintErr("VM cleanup failed: %s\n", error); |
| 262 free(error); |
| 263 } |
| 264 if (do_vm_shutdown) { |
| 265 DebuggerConnectionHandler::StopHandler(); |
| 266 EventHandler::Stop(); |
| 267 } |
| 226 exit(static_cast<int>(status)); | 268 exit(static_cast<int>(status)); |
| 227 } | 269 } |
| 228 | 270 |
| 229 | 271 |
| 230 void FUNCTION_NAME(Process_SetExitCode)(Dart_NativeArguments args) { | 272 void FUNCTION_NAME(Process_SetExitCode)(Dart_NativeArguments args) { |
| 231 int64_t status = 0; | 273 int64_t status = 0; |
| 232 // Ignore result if passing invalid argument and just set exit code to 0. | 274 // Ignore result if passing invalid argument and just set exit code to 0. |
| 233 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status); | 275 DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 0), &status); |
| 234 Process::SetGlobalExitCode(status); | 276 Process::SetGlobalExitCode(status); |
| 235 } | 277 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 free(const_cast<char*>(system_string)); | 383 free(const_cast<char*>(system_string)); |
| 342 Dart_PropagateError(result); | 384 Dart_PropagateError(result); |
| 343 } | 385 } |
| 344 memmove(buffer, system_string, system_len); | 386 memmove(buffer, system_string, system_len); |
| 345 free(const_cast<char*>(system_string)); | 387 free(const_cast<char*>(system_string)); |
| 346 Dart_SetReturnValue(args, external_array); | 388 Dart_SetReturnValue(args, external_array); |
| 347 } | 389 } |
| 348 | 390 |
| 349 } // namespace bin | 391 } // namespace bin |
| 350 } // namespace dart | 392 } // namespace dart |
| OLD | NEW |