Path: blob/main/contrib/kyua/utils/process/status.cpp
48199 views
// Copyright 2010 The Kyua Authors.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are5// met:6//7// * Redistributions of source code must retain the above copyright8// notice, this list of conditions and the following disclaimer.9// * Redistributions in binary form must reproduce the above copyright10// notice, this list of conditions and the following disclaimer in the11// documentation and/or other materials provided with the distribution.12// * Neither the name of Google Inc. nor the names of its contributors13// may be used to endorse or promote products derived from this software14// without specific prior written permission.15//16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2728#include "utils/process/status.hpp"2930extern "C" {31#include <sys/wait.h>32}3334#include "utils/format/macros.hpp"35#include "utils/optional.ipp"36#include "utils/sanity.hpp"3738namespace process = utils::process;3940using utils::none;41using utils::optional;4243#if !defined(WCOREDUMP)44# define WCOREDUMP(x) false45#endif464748/// Constructs a new status object based on the status value of waitpid(2).49///50/// \param dead_pid_ The PID of the process this status belonged to.51/// \param stat_loc The status value returnd by waitpid(2).52process::status::status(const int dead_pid_, int stat_loc) :53_dead_pid(dead_pid_),54_exited(WIFEXITED(stat_loc) ?55optional< int >(WEXITSTATUS(stat_loc)) : none),56_signaled(WIFSIGNALED(stat_loc) ?57optional< std::pair< int, bool > >(58std::make_pair(WTERMSIG(stat_loc), WCOREDUMP(stat_loc))) :59none)60{61}626364/// Constructs a new status object based on fake values.65///66/// \param exited_ If not none, specifies the exit status of the program.67/// \param signaled_ If not none, specifies the termination signal and whether68/// the process dumped core or not.69process::status::status(const optional< int >& exited_,70const optional< std::pair< int, bool > >& signaled_) :71_dead_pid(-1),72_exited(exited_),73_signaled(signaled_)74{75}767778/// Constructs a new status object based on a fake exit status.79///80/// \param exitstatus_ The exit code of the process.81///82/// \return A status object with fake data.83process::status84process::status::fake_exited(const int exitstatus_)85{86return status(utils::make_optional(exitstatus_), none);87}888990/// Constructs a new status object based on a fake exit status.91///92/// \param termsig_ The termination signal of the process.93/// \param coredump_ Whether the process dumped core or not.94///95/// \return A status object with fake data.96process::status97process::status::fake_signaled(const int termsig_, const bool coredump_)98{99return status(none, utils::make_optional(std::make_pair(termsig_,100coredump_)));101}102103104/// Returns the PID of the process this status was taken from.105///106/// Please note that the process is already dead and gone from the system. This107/// PID can only be used for informational reasons and not to address the108/// process in any way.109///110/// \return The PID of the original process.111int112process::status::dead_pid(void) const113{114return _dead_pid;115}116117118/// Returns whether the process exited cleanly or not.119///120/// \return True if the process exited cleanly, false otherwise.121bool122process::status::exited(void) const123{124return _exited;125}126127128/// Returns the exit code of the process.129///130/// \pre The process must have exited cleanly (i.e. exited() must be true).131///132/// \return The exit code.133int134process::status::exitstatus(void) const135{136PRE(exited());137return _exited.get();138}139140141/// Returns whether the process terminated due to a signal or not.142///143/// \return True if the process terminated due to a signal, false otherwise.144bool145process::status::signaled(void) const146{147return _signaled;148}149150151/// Returns the signal that terminated the process.152///153/// \pre The process must have terminated by a signal (i.e. signaled() must be154/// true.155///156/// \return The signal number.157int158process::status::termsig(void) const159{160PRE(signaled());161return _signaled.get().first;162}163164165/// Returns whether the process core dumped or not.166///167/// This functionality may be unsupported in some platforms. In such cases,168/// this method returns false unconditionally.169///170/// \pre The process must have terminated by a signal (i.e. signaled() must be171/// true.172///173/// \return True if the process dumped core, false otherwise.174bool175process::status::coredump(void) const176{177PRE(signaled());178return _signaled.get().second;179}180181182/// Injects the object into a stream.183///184/// \param output The stream into which to inject the object.185/// \param status The object to format.186///187/// \return The output stream.188std::ostream&189process::operator<<(std::ostream& output, const status& status)190{191if (status.exited()) {192output << F("status{exitstatus=%s}") % status.exitstatus();193} else {194INV(status.signaled());195output << F("status{termsig=%s, coredump=%s}") % status.termsig() %196status.coredump();197}198return output;199}200201202