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 |