Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "update_engine/subprocess.h" | 5 #include "update_engine/subprocess.h" |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <unistd.h> | |
| 9 #include <vector> | 10 #include <vector> |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/scoped_ptr.h" | 12 #include "base/scoped_ptr.h" |
| 12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 13 | 14 |
| 14 using std::string; | 15 using std::string; |
| 15 using std::vector; | 16 using std::vector; |
| 16 | 17 |
| 17 namespace chromeos_update_engine { | 18 namespace chromeos_update_engine { |
| 18 | 19 |
| 19 void Subprocess::GChildExitedCallback(GPid pid, gint status, gpointer data) { | 20 void Subprocess::GChildExitedCallback(GPid pid, gint status, gpointer data) { |
| 20 COMPILE_ASSERT(sizeof(guint) == sizeof(uint32_t), | 21 COMPILE_ASSERT(sizeof(guint) == sizeof(uint32_t), |
| 21 guint_uint32_size_mismatch); | 22 guint_uint32_size_mismatch); |
| 22 guint* tag = reinterpret_cast<guint*>(data); | 23 guint* tag = reinterpret_cast<guint*>(data); |
| 23 const SubprocessCallbackRecord& record = Get().callback_records_[*tag]; | 24 const SubprocessCallbackRecord& record = Get().callback_records_[*tag]; |
| 24 if (record.callback) | 25 if (record.callback) |
| 25 record.callback(status, record.callback_data); | 26 record.callback(status, record.callback_data); |
| 26 g_spawn_close_pid(pid); | 27 g_spawn_close_pid(pid); |
| 27 Get().callback_records_.erase(*tag); | 28 Get().callback_records_.erase(*tag); |
| 28 delete tag; | 29 delete tag; |
| 29 } | 30 } |
| 30 | 31 |
| 32 void Subprocess::GRedirectStderrToStdout(gpointer user_data) { | |
| 33 dup2(1, 2); | |
| 34 } | |
| 35 | |
| 31 namespace { | 36 namespace { |
| 32 void FreeArgv(char** argv) { | 37 void FreeArgv(char** argv) { |
| 33 for (int i = 0; argv[i]; i++) { | 38 for (int i = 0; argv[i]; i++) { |
| 34 free(argv[i]); | 39 free(argv[i]); |
| 35 argv[i] = NULL; | 40 argv[i] = NULL; |
| 36 } | 41 } |
| 37 } | 42 } |
| 38 | 43 |
| 39 // Note: Caller responsible for free()ing the returned value! | 44 // Note: Caller responsible for free()ing the returned value! |
| 40 char** ArgPointer() { | 45 char** ArgPointer() { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 scoped_array<char*> argv(new char*[cmd.size() + 1]); | 122 scoped_array<char*> argv(new char*[cmd.size() + 1]); |
| 118 for (unsigned int i = 0; i < cmd.size(); i++) { | 123 for (unsigned int i = 0; i < cmd.size(); i++) { |
| 119 argv[i] = strdup(cmd[i].c_str()); | 124 argv[i] = strdup(cmd[i].c_str()); |
| 120 } | 125 } |
| 121 argv[cmd.size()] = NULL; | 126 argv[cmd.size()] = NULL; |
| 122 | 127 |
| 123 char** argp = ArgPointer(); | 128 char** argp = ArgPointer(); |
| 124 ScopedFreeArgPointer argp_free(argp); | 129 ScopedFreeArgPointer argp_free(argp); |
| 125 | 130 |
| 126 char* child_stdout; | 131 char* child_stdout; |
| 127 char* child_stderr; | |
| 128 | 132 |
| 129 bool success = g_spawn_sync(NULL, // working directory | 133 bool success = g_spawn_sync(NULL, // working directory |
| 130 argv.get(), | 134 argv.get(), |
| 131 argp, | 135 argp, |
| 132 static_cast<GSpawnFlags>(NULL), // flags | 136 G_SPAWN_STDERR_TO_DEV_NULL, // flags |
| 133 NULL, // child setup function | 137 GRedirectStderrToStdout, // child setup function |
| 134 NULL, // data for child setup function | 138 NULL, // data for child setup function |
| 135 &child_stdout, | 139 &child_stdout, |
| 136 &child_stderr, | 140 NULL, |
| 137 return_code, | 141 return_code, |
| 138 &err); | 142 &err); |
| 139 FreeArgv(argv.get()); | 143 FreeArgv(argv.get()); |
| 140 if (err) | 144 if (err) |
| 141 LOG(INFO) << "err is: " << err->code << ", " << err->message; | 145 LOG(INFO) << "err is: " << err->code << ", " << err->message; |
| 142 if (child_stdout && strlen(child_stdout)) | 146 if (child_stdout && strlen(child_stdout)) |
| 143 LOG(INFO) << "Subprocess stdout:" << child_stdout; | 147 LOG(INFO) << "Subprocess output:\n" << child_stdout; |
|
Kenneth Waters
2010/09/17 20:08:28
Do we need to call "g_free(child_stdout)" here ?
adlr
2010/09/17 20:16:27
ask valgrind?
| |
| 144 if (child_stderr && strlen(child_stderr)) | |
| 145 LOG(INFO) << "Subprocess stderr:" << child_stderr; | |
| 146 return success; | 148 return success; |
| 147 } | 149 } |
| 148 | 150 |
| 149 Subprocess* Subprocess::subprocess_singleton_ = NULL; | 151 Subprocess* Subprocess::subprocess_singleton_ = NULL; |
| 150 | 152 |
| 151 } // namespace chromeos_update_engine | 153 } // namespace chromeos_update_engine |
| OLD | NEW |