| 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 |