add check_exited, exit on waitpid errors
This commit is contained in:
+10
-6
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "basicTypes.h"
|
||||
#include <optional>
|
||||
|
||||
struct Proc
|
||||
{
|
||||
@@ -10,20 +11,23 @@ struct Proc
|
||||
fd_t err;
|
||||
};
|
||||
|
||||
struct RetProc: public Proc /* returned process */
|
||||
/* process that has finished for any reason */
|
||||
struct DeadProc: public Proc
|
||||
{
|
||||
RetProc(Proc, int status); /* status as returned by waitpid */
|
||||
DeadProc(Proc, int status); /* status as returned by waitpid */
|
||||
bool normal_exit;
|
||||
U8 returned; /* return code */
|
||||
U8 exit_status; /* only use if normal_exit */
|
||||
|
||||
/* A returned process evaluates to true if it exited normaly and
|
||||
* returned 0 */
|
||||
explicit operator bool();
|
||||
|
||||
};
|
||||
|
||||
// Wait for a running proccess to finish
|
||||
RetProc wait(Proc);
|
||||
/* Wait for a running proccess to finish */
|
||||
DeadProc wait(Proc);
|
||||
|
||||
/* Check if the Proc has exited and return it's DeadProc if it has */
|
||||
std::optional<DeadProc> check_exited(Proc);
|
||||
|
||||
enum Redirect: U32
|
||||
{
|
||||
|
||||
+34
-7
@@ -6,22 +6,49 @@
|
||||
#include "childProcess.hpp"
|
||||
|
||||
|
||||
inline RetProc::RetProc(Proc origin, int status)
|
||||
inline DeadProc::DeadProc(Proc origin, int status)
|
||||
: Proc(origin)
|
||||
, normal_exit(WIFEXITED(status))
|
||||
, returned(WEXITSTATUS(status))
|
||||
, exit_status(WEXITSTATUS(status))
|
||||
{}
|
||||
|
||||
inline RetProc::operator bool()
|
||||
inline DeadProc::operator bool()
|
||||
{
|
||||
return normal_exit && returned == 0;
|
||||
return normal_exit && exit_status == 0;
|
||||
}
|
||||
|
||||
inline RetProc wait(Proc p)
|
||||
inline DeadProc wait(Proc p)
|
||||
{
|
||||
int status;
|
||||
waitpid(p.pid, &status, 0);
|
||||
return RetProc(p, status);
|
||||
if( waitpid(p.pid, &status, 0) == -1 )
|
||||
{
|
||||
std::cerr << "waitpid encountered an error: " << strerror(errno) << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
return DeadProc(p, status);
|
||||
}
|
||||
|
||||
inline std::optional<DeadProc> check_exited(Proc p)
|
||||
{
|
||||
std::optional<DeadProc> result;
|
||||
|
||||
int status;
|
||||
pid_t rc = waitpid(p.pid, &status, WNOHANG);
|
||||
if(rc == 0) // still running
|
||||
{
|
||||
result = std::nullopt;
|
||||
}
|
||||
else if(rc == -1) // waitpid error
|
||||
{
|
||||
std::cerr << "waitpid encountered an error: " << strerror(errno) << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
else // finished
|
||||
{
|
||||
result = DeadProc(p, status);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace _cppipe
|
||||
|
||||
+8
-8
@@ -26,7 +26,7 @@ public:
|
||||
/* Execute the command, if arguments are not given use stdin,out,err
|
||||
else use the given file desciptors. this can also be used
|
||||
to redirect err to out by giving err=1 like in shell */
|
||||
RetProc operator()(fd_t in=0, fd_t out=1, fd_t err=2);
|
||||
DeadProc operator()(fd_t in=0, fd_t out=1, fd_t err=2);
|
||||
|
||||
/* Run the command, don't wait to return like shell's & */
|
||||
Proc detach(fd_t in=0, fd_t out=1, fd_t err=2);
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
PendingCmd& operator=(const PendingCmd&) = delete;
|
||||
|
||||
/* Run the command */
|
||||
RetProc operator()();
|
||||
DeadProc operator()();
|
||||
|
||||
/* Run the command async
|
||||
shell: cmd &
|
||||
@@ -90,12 +90,12 @@ void exec(const Cmd&); /* todo: take Pending? */
|
||||
cd;
|
||||
*/
|
||||
PendingCmd operator,(const PendingCmd&, const Cmd&);
|
||||
PendingCmd operator,(RetProc, const Cmd&);
|
||||
PendingCmd operator,(DeadProc, const Cmd&);
|
||||
/* Forbiden funcion to prevent wrong sequencing such as:
|
||||
echo, echo && echo
|
||||
here the 2nd and 3rd echos would be ran before 1st
|
||||
due to the C++ operator precedence*/
|
||||
PendingCmd operator,(const PendingCmd&, RetProc) = delete;
|
||||
PendingCmd operator,(const PendingCmd&, DeadProc) = delete;
|
||||
|
||||
|
||||
/* Shell pipe operator | - execute two commands, second takes input
|
||||
@@ -103,15 +103,15 @@ PendingCmd operator,(const PendingCmd&, RetProc) = delete;
|
||||
PendingCmd operator|(const PendingCmd&, const Cmd&);
|
||||
|
||||
/* Shell operator && - run the second command only if first returns 0 (no errors)*/
|
||||
RetProc operator&&(const PendingCmd&, const Cmd&);
|
||||
RetProc operator&&(RetProc, const Cmd&);
|
||||
DeadProc operator&&(const PendingCmd&, const Cmd&);
|
||||
DeadProc operator&&(DeadProc, const Cmd&);
|
||||
|
||||
/* Shell operator || - run second only if first returns != 0
|
||||
Operator precedence is different from shell, C precendence is && > ||
|
||||
so mixing || and && may not compile, but shouldn't cause other issues,
|
||||
use () to resolve these cases */
|
||||
RetProc operator||(const PendingCmd&, const Cmd&);
|
||||
RetProc operator||(RetProc, const Cmd&);
|
||||
DeadProc operator||(const PendingCmd&, const Cmd&);
|
||||
DeadProc operator||(DeadProc, const Cmd&);
|
||||
|
||||
/* Shell operator > - redirect output to file
|
||||
shell: cmd > file 2>&1
|
||||
|
||||
+9
-9
@@ -28,7 +28,7 @@ namespace _cppipe
|
||||
}
|
||||
}
|
||||
|
||||
inline RetProc Cmd::operator()(fd_t in, fd_t out, fd_t err)
|
||||
inline DeadProc Cmd::operator()(fd_t in, fd_t out, fd_t err)
|
||||
{
|
||||
Proc p = createProcess(argv.data(), in, out, err);
|
||||
|
||||
@@ -93,7 +93,7 @@ inline PendingCmd::~PendingCmd()
|
||||
/* close(err); */
|
||||
}
|
||||
|
||||
inline RetProc PendingCmd::operator()()
|
||||
inline DeadProc PendingCmd::operator()()
|
||||
{
|
||||
assert(!execed_ && "Executed command twice");
|
||||
execed_ = true;
|
||||
@@ -161,7 +161,7 @@ inline PendingCmd operator,(const PendingCmd& cfirst, const Cmd& second)
|
||||
return PendingCmd(second);
|
||||
}
|
||||
|
||||
inline PendingCmd operator,(RetProc, const Cmd& second)
|
||||
inline PendingCmd operator,(DeadProc, const Cmd& second)
|
||||
{
|
||||
return PendingCmd(second);
|
||||
}
|
||||
@@ -174,11 +174,11 @@ inline PendingCmd operator|(const PendingCmd& cfirst, const Cmd& second)
|
||||
}
|
||||
|
||||
|
||||
inline RetProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
|
||||
inline DeadProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
|
||||
{
|
||||
auto& first = const_cast<PendingCmd&>(cfirst);
|
||||
auto& second = const_cast<Cmd&>(csecond);
|
||||
RetProc firstProc = first();
|
||||
DeadProc firstProc = first();
|
||||
|
||||
if(firstProc)
|
||||
return second();
|
||||
@@ -186,7 +186,7 @@ inline RetProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
|
||||
return firstProc;
|
||||
}
|
||||
|
||||
inline RetProc operator&&(RetProc p, const Cmd& ccmd)
|
||||
inline DeadProc operator&&(DeadProc p, const Cmd& ccmd)
|
||||
{
|
||||
auto& cmd = const_cast<Cmd&>(ccmd);
|
||||
if(p)
|
||||
@@ -195,11 +195,11 @@ inline RetProc operator&&(RetProc p, const Cmd& ccmd)
|
||||
return p;
|
||||
}
|
||||
|
||||
inline RetProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
|
||||
inline DeadProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
|
||||
{
|
||||
auto& first = const_cast<PendingCmd&>(cfirst);
|
||||
auto& second = const_cast<Cmd&>(csecond);
|
||||
RetProc firstProc = first();
|
||||
DeadProc firstProc = first();
|
||||
|
||||
if(!firstProc)
|
||||
return second();
|
||||
@@ -207,7 +207,7 @@ inline RetProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
|
||||
return firstProc;
|
||||
}
|
||||
|
||||
inline RetProc operator||(RetProc p, const Cmd& ccmd)
|
||||
inline DeadProc operator||(DeadProc p, const Cmd& ccmd)
|
||||
{
|
||||
auto& cmd = const_cast<Cmd&>(ccmd);
|
||||
if(!p)
|
||||
|
||||
Reference in New Issue
Block a user