diff options
author | adlr@google.com <adlr@google.com@06c00378-0e64-4dae-be16-12b19f9950a1> | 2009-12-04 20:57:17 +0000 |
---|---|---|
committer | adlr@google.com <adlr@google.com@06c00378-0e64-4dae-be16-12b19f9950a1> | 2009-12-04 20:57:17 +0000 |
commit | 3defe6acb3609e70e851a6eff062577d25a2af9d (patch) | |
tree | 341e979027fde117dd8906483db7a5c703a2e1cf /subprocess.cc | |
parent | c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9 (diff) |
Missed new files in last commit
Review URL: http://codereview.chromium.org/465067
git-svn-id: svn://chrome-svn/chromeos/trunk@336 06c00378-0e64-4dae-be16-12b19f9950a1
Diffstat (limited to 'subprocess.cc')
-rw-r--r-- | subprocess.cc | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/subprocess.cc b/subprocess.cc new file mode 100644 index 00000000..299d7588 --- /dev/null +++ b/subprocess.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "update_engine/subprocess.h" +#include <stdlib.h> +#include <string.h> +#include <string> +#include <vector> +#include "chromeos/obsolete_logging.h" +#include "base/scoped_ptr.h" + +using std::string; +using std::vector; + +namespace chromeos_update_engine { + +void Subprocess::GChildExitedCallback(GPid pid, gint status, gpointer data) { + COMPILE_ASSERT(sizeof(guint) == sizeof(uint32), + guint_uint32_size_mismatch); + guint *tag = reinterpret_cast<guint*>(data); + const SubprocessCallbackRecord& record = Get().callback_records_[*tag]; + if (record.callback) + record.callback(status, record.callback_data); + g_spawn_close_pid(pid); + Get().callback_records_.erase(*tag); + delete tag; +} + +namespace { +void FreeArgv(char** argv) { + for (int i = 0; argv[i]; i++) { + free(argv[i]); + argv[i] = NULL; + } +} +} // namespace {} + +uint32 Subprocess::Exec(const std::vector<std::string>& cmd, + ExecCallback callback, + void *p) { + GPid child_pid; + GError *err; + scoped_array<char *> argv(new char*[cmd.size() + 1]); + for (unsigned int i = 0; i < cmd.size(); i++) { + argv[i] = strdup(cmd[i].c_str()); + } + argv[cmd.size()] = NULL; + char *argp[1]; + argp[0] = NULL; + + SubprocessCallbackRecord callback_record; + callback_record.callback = callback; + callback_record.callback_data = p; + + bool success = g_spawn_async(NULL, // working directory + argv.get(), + argp, + G_SPAWN_DO_NOT_REAP_CHILD, // flags + NULL, // child setup function + NULL, // child setup data pointer + &child_pid, + &err); + FreeArgv(argv.get()); + if (!success) { + LOG(ERROR) << "g_spawn_async failed"; + return 0; + } + guint *tag = new guint; + *tag = g_child_watch_add(child_pid, GChildExitedCallback, tag); + callback_records_[*tag] = callback_record; + return *tag; +} + +void Subprocess::CancelExec(uint32 tag) { + if (callback_records_[tag].callback) { + callback_records_[tag].callback = NULL; + } +} + +bool Subprocess::SynchronousExec(const std::vector<std::string>& cmd, + int* return_code) { + GError *err; + scoped_array<char *> argv(new char*[cmd.size() + 1]); + for (unsigned int i = 0; i < cmd.size(); i++) { + argv[i] = strdup(cmd[i].c_str()); + } + argv[cmd.size()] = NULL; + char *argp[1]; + argp[0] = NULL; + + bool success = g_spawn_sync(NULL, // working directory + argv.get(), + argp, + static_cast<GSpawnFlags>(NULL), // flags + NULL, // child setup function + NULL, // data for child setup function + NULL, // return location for stdout + NULL, // return location for stderr + return_code, + &err); + FreeArgv(argv.get()); + return success; +} + +Subprocess* Subprocess::subprocess_singleton_ = NULL; + +} // namespace chromeos_update_engine |