add check_exited, exit on waitpid errors

This commit is contained in:
vrd
2024-07-10 17:14:35 +03:00
parent f1b7181e15
commit fc42391710
5 changed files with 62 additions and 32 deletions
+10 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+1 -2
View File
@@ -1,6 +1,5 @@
man
tips
openBSD support
tips (sigaction SIGCHILD, SIG_IGN, SIG_DFL)
?
precompiled header cppipe.h