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" |
11 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
| 12 #include "base/string_util.h" |
12 | 13 |
13 using std::string; | 14 using std::string; |
14 using std::vector; | 15 using std::vector; |
15 | 16 |
16 namespace chromeos_update_engine { | 17 namespace chromeos_update_engine { |
17 | 18 |
18 void Subprocess::GChildExitedCallback(GPid pid, gint status, gpointer data) { | 19 void Subprocess::GChildExitedCallback(GPid pid, gint status, gpointer data) { |
19 COMPILE_ASSERT(sizeof(guint) == sizeof(uint32), | 20 COMPILE_ASSERT(sizeof(guint) == sizeof(uint32), |
20 guint_uint32_size_mismatch); | 21 guint_uint32_size_mismatch); |
21 guint *tag = reinterpret_cast<guint*>(data); | 22 guint* tag = reinterpret_cast<guint*>(data); |
22 const SubprocessCallbackRecord& record = Get().callback_records_[*tag]; | 23 const SubprocessCallbackRecord& record = Get().callback_records_[*tag]; |
23 if (record.callback) | 24 if (record.callback) |
24 record.callback(status, record.callback_data); | 25 record.callback(status, record.callback_data); |
25 g_spawn_close_pid(pid); | 26 g_spawn_close_pid(pid); |
26 Get().callback_records_.erase(*tag); | 27 Get().callback_records_.erase(*tag); |
27 delete tag; | 28 delete tag; |
28 } | 29 } |
29 | 30 |
30 namespace { | 31 namespace { |
31 void FreeArgv(char** argv) { | 32 void FreeArgv(char** argv) { |
32 for (int i = 0; argv[i]; i++) { | 33 for (int i = 0; argv[i]; i++) { |
33 free(argv[i]); | 34 free(argv[i]); |
34 argv[i] = NULL; | 35 argv[i] = NULL; |
35 } | 36 } |
36 } | 37 } |
37 } // namespace {} | 38 } // namespace {} |
38 | 39 |
39 uint32 Subprocess::Exec(const std::vector<std::string>& cmd, | 40 uint32 Subprocess::Exec(const std::vector<std::string>& cmd, |
40 ExecCallback callback, | 41 ExecCallback callback, |
41 void *p) { | 42 void* p) { |
42 GPid child_pid; | 43 GPid child_pid; |
43 GError *err; | 44 GError* err; |
44 scoped_array<char *> argv(new char*[cmd.size() + 1]); | 45 scoped_array<char*> argv(new char*[cmd.size() + 1]); |
45 for (unsigned int i = 0; i < cmd.size(); i++) { | 46 for (unsigned int i = 0; i < cmd.size(); i++) { |
46 argv[i] = strdup(cmd[i].c_str()); | 47 argv[i] = strdup(cmd[i].c_str()); |
47 } | 48 } |
48 argv[cmd.size()] = NULL; | 49 argv[cmd.size()] = NULL; |
49 char *argp[1]; | 50 |
50 argp[0] = NULL; | 51 scoped_array<char*> argp(new char*[2]); |
| 52 argp[0] = argp[1] = NULL; |
| 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 } |
51 | 58 |
52 SubprocessCallbackRecord callback_record; | 59 SubprocessCallbackRecord callback_record; |
53 callback_record.callback = callback; | 60 callback_record.callback = callback; |
54 callback_record.callback_data = p; | 61 callback_record.callback_data = p; |
55 | 62 |
56 bool success = g_spawn_async(NULL, // working directory | 63 bool success = g_spawn_async(NULL, // working directory |
57 argv.get(), | 64 argv.get(), |
58 argp, | 65 argp.get(), |
59 G_SPAWN_DO_NOT_REAP_CHILD, // flags | 66 G_SPAWN_DO_NOT_REAP_CHILD, // flags |
60 NULL, // child setup function | 67 NULL, // child setup function |
61 NULL, // child setup data pointer | 68 NULL, // child setup data pointer |
62 &child_pid, | 69 &child_pid, |
63 &err); | 70 &err); |
64 FreeArgv(argv.get()); | 71 FreeArgv(argv.get()); |
65 if (!success) { | 72 if (!success) { |
66 LOG(ERROR) << "g_spawn_async failed"; | 73 LOG(ERROR) << "g_spawn_async failed"; |
67 return 0; | 74 return 0; |
68 } | 75 } |
69 guint *tag = new guint; | 76 guint* tag = new guint; |
70 *tag = g_child_watch_add(child_pid, GChildExitedCallback, tag); | 77 *tag = g_child_watch_add(child_pid, GChildExitedCallback, tag); |
71 callback_records_[*tag] = callback_record; | 78 callback_records_[*tag] = callback_record; |
72 return *tag; | 79 return *tag; |
73 } | 80 } |
74 | 81 |
75 void Subprocess::CancelExec(uint32 tag) { | 82 void Subprocess::CancelExec(uint32 tag) { |
76 if (callback_records_[tag].callback) { | 83 if (callback_records_[tag].callback) { |
77 callback_records_[tag].callback = NULL; | 84 callback_records_[tag].callback = NULL; |
78 } | 85 } |
79 } | 86 } |
80 | 87 |
81 bool Subprocess::SynchronousExec(const std::vector<std::string>& cmd, | 88 bool Subprocess::SynchronousExec(const std::vector<std::string>& cmd, |
82 int* return_code) { | 89 int* return_code) { |
83 GError *err = NULL; | 90 GError* err = NULL; |
84 scoped_array<char *> argv(new char*[cmd.size() + 1]); | 91 scoped_array<char*> argv(new char*[cmd.size() + 1]); |
85 for (unsigned int i = 0; i < cmd.size(); i++) { | 92 for (unsigned int i = 0; i < cmd.size(); i++) { |
86 argv[i] = strdup(cmd[i].c_str()); | 93 argv[i] = strdup(cmd[i].c_str()); |
87 } | 94 } |
88 argv[cmd.size()] = NULL; | 95 argv[cmd.size()] = NULL; |
89 char *argp[1]; | 96 char* argp[1]; |
90 argp[0] = NULL; | 97 argp[0] = NULL; |
91 | 98 |
92 bool success = g_spawn_sync(NULL, // working directory | 99 bool success = g_spawn_sync(NULL, // working directory |
93 argv.get(), | 100 argv.get(), |
94 argp, | 101 argp, |
95 static_cast<GSpawnFlags>(NULL), // flags | 102 static_cast<GSpawnFlags>(NULL), // flags |
96 NULL, // child setup function | 103 NULL, // child setup function |
97 NULL, // data for child setup function | 104 NULL, // data for child setup function |
98 NULL, // return location for stdout | 105 NULL, // return location for stdout |
99 NULL, // return location for stderr | 106 NULL, // return location for stderr |
100 return_code, | 107 return_code, |
101 &err); | 108 &err); |
102 FreeArgv(argv.get()); | 109 FreeArgv(argv.get()); |
103 if (err) | 110 if (err) |
104 LOG(INFO) << "err is: " << err->code << ", " << err->message; | 111 LOG(INFO) << "err is: " << err->code << ", " << err->message; |
105 return success; | 112 return success; |
106 } | 113 } |
107 | 114 |
108 Subprocess* Subprocess::subprocess_singleton_ = NULL; | 115 Subprocess* Subprocess::subprocess_singleton_ = NULL; |
109 | 116 |
110 } // namespace chromeos_update_engine | 117 } // namespace chromeos_update_engine |
OLD | NEW |