| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -116,9 +116,10 @@ class ProcessWrap : public HandleWrap { | |||
| 116 | 116 | return Just(stream); | |
| 117 | 117 | } | |
| 118 | 118 | ||
| 119 | - static Maybe<void> ParseStdioOptions(Environment* env, | ||
| 120 | - Local<Object> js_options, | ||
| 121 | - uv_process_options_t* options) { | ||
| 119 | + static Maybe<void> ParseStdioOptions( | ||
| 120 | + Environment* env, | ||
| 121 | + Local<Object> js_options, | ||
| 122 | + std::vector<uv_stdio_container_t>* options_stdio) { | ||
| 122 | 123 | Local<Context> context = env->context(); | |
| 123 | 124 | Local<String> stdio_key = env->stdio_string(); | |
| 124 | 125 | Local<Value> stdios_val; | |
@@ -132,8 +133,7 @@ class ProcessWrap : public HandleWrap { | |||
| 132 | 133 | Local<Array> stdios = stdios_val.As<Array>(); | |
| 133 | 134 | ||
| 134 | 135 | uint32_t len = stdios->Length(); | |
| 135 | - options->stdio = new uv_stdio_container_t[len]; | ||
| 136 | - options->stdio_count = len; | ||
| 136 | + options_stdio->resize(len); | ||
| 137 | 137 | ||
| 138 | 138 | for (uint32_t i = 0; i < len; i++) { | |
| 139 | 139 | Local<Value> val; | |
@@ -147,23 +147,23 @@ class ProcessWrap : public HandleWrap { | |||
| 147 | 147 | } | |
| 148 | 148 | ||
| 149 | 149 | if (type->StrictEquals(env->ignore_string())) { | |
| 150 | - options->stdio[i].flags = UV_IGNORE; | ||
| 150 | + (*options_stdio)[i].flags = UV_IGNORE; | ||
| 151 | 151 | } else if (type->StrictEquals(env->pipe_string())) { | |
| 152 | - options->stdio[i].flags = static_cast<uv_stdio_flags>( | ||
| 152 | + (*options_stdio)[i].flags = static_cast<uv_stdio_flags>( | ||
| 153 | 153 | UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE); | |
| 154 | - if (!StreamForWrap(env, stdio).To(&options->stdio[i].data.stream)) { | ||
| 154 | + if (!StreamForWrap(env, stdio).To(&(*options_stdio)[i].data.stream)) { | ||
| 155 | 155 | return Nothing<void>(); | |
| 156 | 156 | } | |
| 157 | 157 | } else if (type->StrictEquals(env->overlapped_string())) { | |
| 158 | - options->stdio[i].flags = static_cast<uv_stdio_flags>( | ||
| 159 | - UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE | | ||
| 160 | - UV_OVERLAPPED_PIPE); | ||
| 161 | - if (!StreamForWrap(env, stdio).To(&options->stdio[i].data.stream)) { | ||
| 158 | + (*options_stdio)[i].flags = | ||
| 159 | + static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_READABLE_PIPE | | ||
| 160 | + UV_WRITABLE_PIPE | UV_OVERLAPPED_PIPE); | ||
| 161 | + if (!StreamForWrap(env, stdio).To(&(*options_stdio)[i].data.stream)) { | ||
| 162 | 162 | return Nothing<void>(); | |
| 163 | 163 | } | |
| 164 | 164 | } else if (type->StrictEquals(env->wrap_string())) { | |
| 165 | - options->stdio[i].flags = UV_INHERIT_STREAM; | ||
| 166 | - if (!StreamForWrap(env, stdio).To(&options->stdio[i].data.stream)) { | ||
| 165 | + (*options_stdio)[i].flags = UV_INHERIT_STREAM; | ||
| 166 | + if (!StreamForWrap(env, stdio).To(&(*options_stdio)[i].data.stream)) { | ||
| 167 | 167 | return Nothing<void>(); | |
| 168 | 168 | } | |
| 169 | 169 | } else { | |
@@ -174,8 +174,8 @@ class ProcessWrap : public HandleWrap { | |||
| 174 | 174 | } | |
| 175 | 175 | CHECK(fd_value->IsNumber()); | |
| 176 | 176 | int fd = FromV8Value<int>(fd_value); | |
| 177 | - options->stdio[i].flags = UV_INHERIT_FD; | ||
| 178 | - options->stdio[i].data.fd = fd; | ||
| 177 | + (*options_stdio)[i].flags = UV_INHERIT_FD; | ||
| 178 | + (*options_stdio)[i].data.fd = fd; | ||
| 179 | 179 | } | |
| 180 | 180 | } | |
| 181 | 181 | return JustVoid(); | |
@@ -199,8 +199,6 @@ class ProcessWrap : public HandleWrap { | |||
| 199 | 199 | ||
| 200 | 200 | options.exit_cb = OnExit; | |
| 201 | 201 | ||
| 202 | - // TODO(bnoordhuis) is this possible to do without mallocing ? | ||
| 203 | - | ||
| 204 | 202 | // options.file | |
| 205 | 203 | Local<Value> file_v; | |
| 206 | 204 | if (!js_options->Get(context, env->file_string()).ToLocal(&file_v)) { | |
@@ -251,23 +249,26 @@ class ProcessWrap : public HandleWrap { | |||
| 251 | 249 | if (!js_options->Get(context, env->args_string()).ToLocal(&argv_v)) { | |
| 252 | 250 | return; | |
| 253 | 251 | } | |
| 254 | - if (!argv_v.IsEmpty() && argv_v->IsArray()) { | ||
| 252 | + std::vector<char*> options_args; | ||
| 253 | + std::vector<std::string> args_vals; | ||
| 254 | + if (argv_v->IsArray()) { | ||
| 255 | 255 | Local<Array> js_argv = argv_v.As<Array>(); | |
| 256 | 256 | int argc = js_argv->Length(); | |
| 257 | 257 | CHECK_LT(argc, INT_MAX); // Check for overflow. | |
| 258 | - | ||
| 259 | - // Heap allocate to detect errors. +1 is for nullptr. | ||
| 260 | - options.args = new char*[argc + 1]; | ||
| 258 | + args_vals.reserve(argc); | ||
| 259 | + options_args.resize(argc + 1); | ||
| 261 | 260 | for (int i = 0; i < argc; i++) { | |
| 262 | 261 | Local<Value> val; | |
| 263 | 262 | if (!js_argv->Get(context, i).ToLocal(&val)) { | |
| 264 | 263 | return; | |
| 265 | 264 | } | |
| 266 | 265 | node::Utf8Value arg(env->isolate(), val); | |
| 267 | - options.args[i] = strdup(*arg); | ||
| 268 | - CHECK_NOT_NULL(options.args[i]); | ||
| 266 | + args_vals.emplace_back(arg.ToString()); | ||
| 267 | + options_args[i] = const_cast<char*>(args_vals.back().c_str()); | ||
| 268 | + CHECK_NOT_NULL(options_args[i]); | ||
| 269 | 269 | } | |
| 270 | - options.args[argc] = nullptr; | ||
| 270 | + options_args[argc] = nullptr; | ||
| 271 | + options.args = options_args.data(); | ||
| 271 | 272 | } | |
| 272 | 273 | ||
| 273 | 274 | // options.cwd | |
@@ -286,27 +287,35 @@ class ProcessWrap : public HandleWrap { | |||
| 286 | 287 | if (!js_options->Get(context, env->env_pairs_string()).ToLocal(&env_v)) { | |
| 287 | 288 | return; | |
| 288 | 289 | } | |
| 289 | - if (!env_v.IsEmpty() && env_v->IsArray()) { | ||
| 290 | + std::vector<char*> options_env; | ||
| 291 | + std::vector<std::string> env_vals; | ||
| 292 | + if (env_v->IsArray()) { | ||
| 290 | 293 | Local<Array> env_opt = env_v.As<Array>(); | |
| 291 | 294 | int envc = env_opt->Length(); | |
| 292 | 295 | CHECK_LT(envc, INT_MAX); // Check for overflow. | |
| 293 | - options.env = new char*[envc + 1]; // Heap allocated to detect errors. | ||
| 296 | + env_vals.reserve(envc); | ||
| 297 | + options_env.resize(envc + 1); | ||
| 294 | 298 | for (int i = 0; i < envc; i++) { | |
| 295 | 299 | Local<Value> val; | |
| 296 | 300 | if (!env_opt->Get(context, i).ToLocal(&val)) { | |
| 297 | 301 | return; | |
| 298 | 302 | } | |
| 299 | 303 | node::Utf8Value pair(env->isolate(), val); | |
| 300 | - options.env[i] = strdup(*pair); | ||
| 301 | - CHECK_NOT_NULL(options.env[i]); | ||
| 304 | + env_vals.emplace_back(pair.ToString()); | ||
| 305 | + options_env[i] = const_cast<char*>(env_vals.back().c_str()); | ||
| 306 | + CHECK_NOT_NULL(options_env[i]); | ||
| 302 | 307 | } | |
| 303 | - options.env[envc] = nullptr; | ||
| 308 | + options_env[envc] = nullptr; | ||
| 309 | + options.env = options_env.data(); | ||
| 304 | 310 | } | |
| 305 | 311 | ||
| 306 | 312 | // options.stdio | |
| 307 | - if (ParseStdioOptions(env, js_options, &options).IsNothing()) { | ||
| 313 | + std::vector<uv_stdio_container_t> options_stdio; | ||
| 314 | + if (ParseStdioOptions(env, js_options, &options_stdio).IsNothing()) { | ||
| 308 | 315 | return; | |
| 309 | 316 | } | |
| 317 | + options.stdio = options_stdio.data(); | ||
| 318 | + options.stdio_count = options_stdio.size(); | ||
| 310 | 319 | ||
| 311 | 320 | // options.windowsHide | |
| 312 | 321 | Local<Value> hide_v; | |
@@ -361,18 +370,6 @@ class ProcessWrap : public HandleWrap { | |||
| 361 | 370 | } | |
| 362 | 371 | } | |
| 363 | 372 | ||
| 364 | - if (options.args) { | ||
| 365 | - for (int i = 0; options.args[i]; i++) free(options.args[i]); | ||
| 366 | - delete [] options.args; | ||
| 367 | - } | ||
| 368 | - | ||
| 369 | - if (options.env) { | ||
| 370 | - for (int i = 0; options.env[i]; i++) free(options.env[i]); | ||
| 371 | - delete [] options.env; | ||
| 372 | - } | ||
| 373 | - | ||
| 374 | - delete[] options.stdio; | ||
| 375 | - | ||
| 376 | 373 | args.GetReturnValue().Set(err); | |
| 377 | 374 | } | |
| 378 | 375 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -403,7 +403,6 @@ void SyncProcessRunner::Spawn(const FunctionCallbackInfo<Value>& args) { | |||
| 403 | 403 | args.GetReturnValue().Set(result); | |
| 404 | 404 | } | |
| 405 | 405 | ||
| 406 | - | ||
| 407 | 406 | SyncProcessRunner::SyncProcessRunner(Environment* env) | |
| 408 | 407 | : max_buffer_(0), | |
| 409 | 408 | timeout_(0), | |
@@ -412,14 +411,9 @@ SyncProcessRunner::SyncProcessRunner(Environment* env) | |||
| 412 | 411 | uv_loop_(nullptr), | |
| 413 | 412 | ||
| 414 | 413 | stdio_count_(0), | |
| 415 | - uv_stdio_containers_(nullptr), | ||
| 416 | 414 | stdio_pipes_initialized_(false), | |
| 417 | 415 | ||
| 418 | 416 | uv_process_options_(), | |
| 419 | - file_buffer_(nullptr), | ||
| 420 | - args_buffer_(nullptr), | ||
| 421 | - env_buffer_(nullptr), | ||
| 422 | - cwd_buffer_(nullptr), | ||
| 423 | 417 | ||
| 424 | 418 | uv_process_(), | |
| 425 | 419 | killed_(false), | |
@@ -436,19 +430,12 @@ SyncProcessRunner::SyncProcessRunner(Environment* env) | |||
| 436 | 430 | ||
| 437 | 431 | lifecycle_(kUninitialized), | |
| 438 | 432 | ||
| 439 | - env_(env) { | ||
| 440 | - } | ||
| 441 | - | ||
| 433 | + env_(env) {} | ||
| 442 | 434 | ||
| 443 | 435 | SyncProcessRunner::~SyncProcessRunner() { | |
| 444 | 436 | CHECK_EQ(lifecycle_, kHandlesClosed); | |
| 445 | 437 | ||
| 446 | 438 | stdio_pipes_.clear(); | |
| 447 | - delete[] file_buffer_; | ||
| 448 | - delete[] args_buffer_; | ||
| 449 | - delete[] cwd_buffer_; | ||
| 450 | - delete[] env_buffer_; | ||
| 451 | - delete[] uv_stdio_containers_; | ||
| 452 | 439 | } | |
| 453 | 440 | ||
| 454 | 441 | ||
@@ -808,12 +795,14 @@ Maybe<int> SyncProcessRunner::ParseOptions(Local<Value> js_value) { | |||
| 808 | 795 | Local<Object> js_options = js_value.As<Object>(); | |
| 809 | 796 | ||
| 810 | 797 | Local<Value> js_file; | |
| 798 | + const char* file_buffer; | ||
| 811 | 799 | if (!js_options->Get(context, env()->file_string()).ToLocal(&js_file) || | |
| 812 | - !CopyJsString(js_file, &file_buffer_).To(&r)) { | ||
| 800 | + !CopyJsString(js_file, &file_buffer).To(&r)) { | ||
| 813 | 801 | return Nothing<int>(); | |
| 814 | 802 | } | |
| 815 | 803 | if (r < 0) return Just(r); | |
| 816 | - uv_process_options_.file = file_buffer_; | ||
| 804 | + file_buffer_.reset(file_buffer); | ||
| 805 | + uv_process_options_.file = file_buffer_.get(); | ||
| 817 | 806 | ||
| 818 | 807 | // Undocumented feature of Win32 CreateProcess API allows spawning | |
| 819 | 808 | // batch files directly but is potentially insecure because arguments | |
@@ -825,23 +814,27 @@ Maybe<int> SyncProcessRunner::ParseOptions(Local<Value> js_value) { | |||
| 825 | 814 | #endif | |
| 826 | 815 | ||
| 827 | 816 | Local<Value> js_args; | |
| 817 | + char* args_buffer; | ||
| 828 | 818 | if (!js_options->Get(context, env()->args_string()).ToLocal(&js_args) || | |
| 829 | - !CopyJsStringArray(js_args, &args_buffer_).To(&r)) { | ||
| 819 | + !CopyJsStringArray(js_args, &args_buffer).To(&r)) { | ||
| 830 | 820 | return Nothing<int>(); | |
| 831 | 821 | } | |
| 832 | 822 | if (r < 0) return Just(r); | |
| 833 | - uv_process_options_.args = reinterpret_cast<char**>(args_buffer_); | ||
| 823 | + args_buffer_.reset(args_buffer); | ||
| 824 | + uv_process_options_.args = reinterpret_cast<char**>(args_buffer_.get()); | ||
| 834 | 825 | ||
| 835 | 826 | Local<Value> js_cwd; | |
| 836 | 827 | if (!js_options->Get(context, env()->cwd_string()).ToLocal(&js_cwd)) { | |
| 837 | 828 | return Nothing<int>(); | |
| 838 | 829 | } | |
| 839 | 830 | if (!js_cwd->IsNullOrUndefined()) { | |
| 840 | - if (!CopyJsString(js_cwd, &cwd_buffer_).To(&r)) { | ||
| 831 | + const char* cwd_buffer; | ||
| 832 | + if (!CopyJsString(js_cwd, &cwd_buffer).To(&r)) { | ||
| 841 | 833 | return Nothing<int>(); | |
| 842 | 834 | } | |
| 843 | 835 | if (r < 0) return Just(r); | |
| 844 | - uv_process_options_.cwd = cwd_buffer_; | ||
| 836 | + cwd_buffer_.reset(cwd_buffer); | ||
| 837 | + uv_process_options_.cwd = cwd_buffer_.get(); | ||
| 845 | 838 | } | |
| 846 | 839 | ||
| 847 | 840 | Local<Value> js_env_pairs; | |
@@ -850,12 +843,13 @@ Maybe<int> SyncProcessRunner::ParseOptions(Local<Value> js_value) { | |||
| 850 | 843 | return Nothing<int>(); | |
| 851 | 844 | } | |
| 852 | 845 | if (!js_env_pairs->IsNullOrUndefined()) { | |
| 853 | - if (!CopyJsStringArray(js_env_pairs, &env_buffer_).To(&r)) { | ||
| 846 | + char* env_buffer; | ||
| 847 | + if (!CopyJsStringArray(js_env_pairs, &env_buffer).To(&r)) { | ||
| 854 | 848 | return Nothing<int>(); | |
| 855 | 849 | } | |
| 856 | 850 | if (r < 0) return Just(r); | |
| 857 | - | ||
| 858 | - uv_process_options_.env = reinterpret_cast<char**>(env_buffer_); | ||
| 851 | + env_buffer_.reset(env_buffer); | ||
| 852 | + uv_process_options_.env = reinterpret_cast<char**>(env_buffer_.get()); | ||
| 859 | 853 | } | |
| 860 | 854 | Local<Value> js_uid; | |
| 861 | 855 | if (!js_options->Get(context, env()->uid_string()).ToLocal(&js_uid)) { | |
@@ -982,7 +976,7 @@ Maybe<int> SyncProcessRunner::ParseStdioOptions(Local<Value> js_value) { | |||
| 982 | 976 | js_stdio_options = js_value.As<Array>(); | |
| 983 | 977 | ||
| 984 | 978 | stdio_count_ = js_stdio_options->Length(); | |
| 985 | - uv_stdio_containers_ = new uv_stdio_container_t[stdio_count_]; | ||
| 979 | + uv_stdio_containers_.resize(stdio_count_); | ||
| 986 | 980 | ||
| 987 | 981 | stdio_pipes_.clear(); | |
| 988 | 982 | stdio_pipes_.resize(stdio_count_); | |
@@ -1007,7 +1001,7 @@ Maybe<int> SyncProcessRunner::ParseStdioOptions(Local<Value> js_value) { | |||
| 1007 | 1001 | } | |
| 1008 | 1002 | } | |
| 1009 | 1003 | ||
| 1010 | - uv_process_options_.stdio = uv_stdio_containers_; | ||
| 1004 | + uv_process_options_.stdio = uv_stdio_containers_.data(); | ||
| 1011 | 1005 | uv_process_options_.stdio_count = stdio_count_; | |
| 1012 | 1006 | ||
| 1013 | 1007 | return Just<int>(0); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -205,15 +205,15 @@ class SyncProcessRunner { | |||
| 205 | 205 | uv_loop_t* uv_loop_; | |
| 206 | 206 | ||
| 207 | 207 | uint32_t stdio_count_; | |
| 208 | - uv_stdio_container_t* uv_stdio_containers_; | ||
| 208 | + std::vector<uv_stdio_container_t> uv_stdio_containers_; | ||
| 209 | 209 | std::vector<std::unique_ptr<SyncProcessStdioPipe>> stdio_pipes_; | |
| 210 | 210 | bool stdio_pipes_initialized_; | |
| 211 | 211 | ||
| 212 | 212 | uv_process_options_t uv_process_options_; | |
| 213 | - const char* file_buffer_; | ||
| 214 | - char* args_buffer_; | ||
| 215 | - char* env_buffer_; | ||
| 216 | - const char* cwd_buffer_; | ||
| 213 | + std::unique_ptr<const char[]> file_buffer_; | ||
| 214 | + std::unique_ptr<char[]> args_buffer_; | ||
| 215 | + std::unique_ptr<char[]> env_buffer_; | ||
| 216 | + std::unique_ptr<const char[]> cwd_buffer_; | ||
| 217 | 217 | ||
| 218 | 218 | uv_process_t uv_process_; | |
| 219 | 219 | bool killed_; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments