blob: 977ec04a0eb133e4c8590ea962d63037ec4d5e28 [file] [log] [blame]
Elly Jonese7cb5b32011-12-01 14:18:32 -05001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ping_tool.h"
6
7#include <map>
8#include <string>
9
10#include <dbus-c++/dbus.h>
11#include <signal.h>
12
13#include "process_with_id.h"
14
15namespace debugd {
16
17const char* kErrorNoSuchProcess =
18 "org.chromium.debugd.error.NoSuchProcess";
19const char* kPing = "/bin/ping";
20
21PingTool::PingTool() { }
22PingTool::~PingTool() { }
23
24std::string PingTool::Start(const DBus::FileDescriptor& outfd,
25 const std::string& destination,
26 const std::map<std::string, DBus::Variant>&
27 options,
28 DBus::Error& error) {
29 ProcessWithId* p = new ProcessWithId();
30 if (!p->Init() || processes_.count(p->id()) == 1)
31 return "";
32 p->AddArg(kPing);
33 if (options.count("count") == 1) {
34 // If we try to convert a non-int value to an int here, dbus-c++ will toss
35 // a C++ exception, which the dbus-c++ main loop will convert into a dbus
36 // exception and return it to our caller.
37 p->AddIntOption("-c", options.find("count")->second);
38 } else {
39 p->AddIntOption("-c", 4);
40 }
41 if (options.count("interval") == 1) {
42 p->AddIntOption("-i", options.find("interval")->second);
43 }
44 if (options.count("numeric") == 1) {
45 p->AddArg("-n");
46 }
47 if (options.count("packetsize") == 1) {
48 p->AddIntOption("-s", options.find("packetsize")->second);
49 }
50 if (options.count("waittime") == 1) {
51 p->AddIntOption("-W", options.find("waittime")->second);
52 }
53 p->AddArg(destination);
54 p->BindFd(outfd.get(), STDOUT_FILENO);
55 p->BindFd(outfd.get(), STDERR_FILENO);
56 processes_[p->id()] = p;
57 LOG(INFO) << "ping: running process id: " << p->id();
58 p->Start();
59 return p->id();
60}
61
62void PingTool::Stop(const std::string& handle, DBus::Error& error) {
63 if (processes_.count(handle) != 1) {
64 error.set(kErrorNoSuchProcess, handle.c_str());
65 return;
66 }
67 ProcessWithId* p = processes_[handle];
68 p->Kill(SIGKILL, 0); // no timeout
69 p->Wait();
70 processes_.erase(handle);
71 delete p;
72}
73
74}; // namespace debugd