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 <vector> | 9 #include <vector> |
10 #include "chromeos/obsolete_logging.h" | 10 #include "chromeos/obsolete_logging.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 delete tag; | 28 delete tag; |
29 } | 29 } |
30 | 30 |
31 namespace { | 31 namespace { |
32 void FreeArgv(char** argv) { | 32 void FreeArgv(char** argv) { |
33 for (int i = 0; argv[i]; i++) { | 33 for (int i = 0; argv[i]; i++) { |
34 free(argv[i]); | 34 free(argv[i]); |
35 argv[i] = NULL; | 35 argv[i] = NULL; |
36 } | 36 } |
37 } | 37 } |
| 38 |
| 39 // Note: Caller responsible for free()ing the returned value! |
| 40 char** ArgPointer() { |
| 41 const char* keys[] = {"LD_LIBRARY_PATH", "PATH"}; |
| 42 char** ret = new char*[arraysize(keys) + 1]; |
| 43 int pointer = 0; |
| 44 for (size_t i = 0; i < arraysize(keys); i++) { |
| 45 ret[i] = NULL; |
| 46 if (getenv(keys[i])) { |
| 47 ret[pointer] = strdup(StringPrintf("%s=%s", keys[i], |
| 48 getenv(keys[i])).c_str()); |
| 49 pointer++; |
| 50 } |
| 51 } |
| 52 return ret; |
| 53 } |
| 54 |
| 55 class ScopedFreeArgPointer { |
| 56 public: |
| 57 ScopedFreeArgPointer(char** arr) : arr_(arr) {} |
| 58 ~ScopedFreeArgPointer() { |
| 59 if (!arr_) |
| 60 return; |
| 61 for (int i = 0; arr_[i]; i++) |
| 62 free(arr_[i]); |
| 63 delete[] arr_; |
| 64 } |
| 65 private: |
| 66 char** arr_; |
| 67 DISALLOW_COPY_AND_ASSIGN(ScopedFreeArgPointer); |
| 68 }; |
38 } // namespace {} | 69 } // namespace {} |
39 | 70 |
40 uint32_t Subprocess::Exec(const std::vector<std::string>& cmd, | 71 uint32_t Subprocess::Exec(const std::vector<std::string>& cmd, |
41 ExecCallback callback, | 72 ExecCallback callback, |
42 void* p) { | 73 void* p) { |
43 GPid child_pid; | 74 GPid child_pid; |
44 GError* err; | 75 GError* err; |
45 scoped_array<char*> argv(new char*[cmd.size() + 1]); | 76 scoped_array<char*> argv(new char*[cmd.size() + 1]); |
46 for (unsigned int i = 0; i < cmd.size(); i++) { | 77 for (unsigned int i = 0; i < cmd.size(); i++) { |
47 argv[i] = strdup(cmd[i].c_str()); | 78 argv[i] = strdup(cmd[i].c_str()); |
48 } | 79 } |
49 argv[cmd.size()] = NULL; | 80 argv[cmd.size()] = NULL; |
50 | 81 |
51 scoped_array<char*> argp(new char*[2]); | 82 char** argp = ArgPointer(); |
52 argp[0] = argp[1] = NULL; | 83 ScopedFreeArgPointer argp_free(argp); |
53 const char* kLdLibraryPathKey = "LD_LIBRARY_PATH"; | |
54 if (getenv(kLdLibraryPathKey)) { | |
55 argp[0] = strdup(StringPrintf("%s=%s", kLdLibraryPathKey, | |
56 getenv(kLdLibraryPathKey)).c_str()); | |
57 } | |
58 | 84 |
59 SubprocessCallbackRecord callback_record; | 85 SubprocessCallbackRecord callback_record; |
60 callback_record.callback = callback; | 86 callback_record.callback = callback; |
61 callback_record.callback_data = p; | 87 callback_record.callback_data = p; |
62 | 88 |
63 bool success = g_spawn_async(NULL, // working directory | 89 bool success = g_spawn_async(NULL, // working directory |
64 argv.get(), | 90 argv.get(), |
65 argp.get(), | 91 argp, |
66 G_SPAWN_DO_NOT_REAP_CHILD, // flags | 92 G_SPAWN_DO_NOT_REAP_CHILD, // flags |
67 NULL, // child setup function | 93 NULL, // child setup function |
68 NULL, // child setup data pointer | 94 NULL, // child setup data pointer |
69 &child_pid, | 95 &child_pid, |
70 &err); | 96 &err); |
71 FreeArgv(argv.get()); | 97 FreeArgv(argv.get()); |
72 if (!success) { | 98 if (!success) { |
73 LOG(ERROR) << "g_spawn_async failed"; | 99 LOG(ERROR) << "g_spawn_async failed"; |
74 return 0; | 100 return 0; |
75 } | 101 } |
(...skipping 10 matching lines...) Expand all Loading... |
86 } | 112 } |
87 | 113 |
88 bool Subprocess::SynchronousExec(const std::vector<std::string>& cmd, | 114 bool Subprocess::SynchronousExec(const std::vector<std::string>& cmd, |
89 int* return_code) { | 115 int* return_code) { |
90 GError* err = NULL; | 116 GError* err = NULL; |
91 scoped_array<char*> argv(new char*[cmd.size() + 1]); | 117 scoped_array<char*> argv(new char*[cmd.size() + 1]); |
92 for (unsigned int i = 0; i < cmd.size(); i++) { | 118 for (unsigned int i = 0; i < cmd.size(); i++) { |
93 argv[i] = strdup(cmd[i].c_str()); | 119 argv[i] = strdup(cmd[i].c_str()); |
94 } | 120 } |
95 argv[cmd.size()] = NULL; | 121 argv[cmd.size()] = NULL; |
96 char* argp[1]; | 122 |
97 argp[0] = NULL; | 123 char** argp = ArgPointer(); |
| 124 ScopedFreeArgPointer argp_free(argp); |
| 125 |
| 126 char* child_stdout; |
| 127 char* child_stderr; |
98 | 128 |
99 bool success = g_spawn_sync(NULL, // working directory | 129 bool success = g_spawn_sync(NULL, // working directory |
100 argv.get(), | 130 argv.get(), |
101 argp, | 131 argp, |
102 static_cast<GSpawnFlags>(NULL), // flags | 132 static_cast<GSpawnFlags>(NULL), // flags |
103 NULL, // child setup function | 133 NULL, // child setup function |
104 NULL, // data for child setup function | 134 NULL, // data for child setup function |
105 NULL, // return location for stdout | 135 &child_stdout, |
106 NULL, // return location for stderr | 136 &child_stderr, |
107 return_code, | 137 return_code, |
108 &err); | 138 &err); |
109 FreeArgv(argv.get()); | 139 FreeArgv(argv.get()); |
110 if (err) | 140 if (err) |
111 LOG(INFO) << "err is: " << err->code << ", " << err->message; | 141 LOG(INFO) << "err is: " << err->code << ", " << err->message; |
| 142 if (child_stdout) |
| 143 LOG(INFO) << "Postinst stdout:" << child_stdout; |
| 144 if (child_stderr) |
| 145 LOG(INFO) << "Postinst stderr:" << child_stderr; |
112 return success; | 146 return success; |
113 } | 147 } |
114 | 148 |
115 Subprocess* Subprocess::subprocess_singleton_ = NULL; | 149 Subprocess* Subprocess::subprocess_singleton_ = NULL; |
116 | 150 |
117 } // namespace chromeos_update_engine | 151 } // namespace chromeos_update_engine |
OLD | NEW |