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 #pragma once
#include "basicTypes.h" #include "basicTypes.h"
#include <optional>
struct Proc struct Proc
{ {
@@ -10,20 +11,23 @@ struct Proc
fd_t err; 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; 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 /* A returned process evaluates to true if it exited normaly and
* returned 0 */ * returned 0 */
explicit operator bool(); explicit operator bool();
}; };
// Wait for a running proccess to finish /* Wait for a running proccess to finish */
RetProc wait(Proc); 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 enum Redirect: U32
{ {
+34 -7
View File
@@ -6,22 +6,49 @@
#include "childProcess.hpp" #include "childProcess.hpp"
inline RetProc::RetProc(Proc origin, int status) inline DeadProc::DeadProc(Proc origin, int status)
: Proc(origin) : Proc(origin)
, normal_exit(WIFEXITED(status)) , 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; int status;
waitpid(p.pid, &status, 0); if( waitpid(p.pid, &status, 0) == -1 )
return RetProc(p, status); {
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 namespace _cppipe
+8 -8
View File
@@ -26,7 +26,7 @@ public:
/* Execute the command, if arguments are not given use stdin,out,err /* Execute the command, if arguments are not given use stdin,out,err
else use the given file desciptors. this can also be used else use the given file desciptors. this can also be used
to redirect err to out by giving err=1 like in shell */ 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 & */ /* 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); Proc detach(fd_t in=0, fd_t out=1, fd_t err=2);
@@ -57,7 +57,7 @@ public:
PendingCmd& operator=(const PendingCmd&) = delete; PendingCmd& operator=(const PendingCmd&) = delete;
/* Run the command */ /* Run the command */
RetProc operator()(); DeadProc operator()();
/* Run the command async /* Run the command async
shell: cmd & shell: cmd &
@@ -90,12 +90,12 @@ void exec(const Cmd&); /* todo: take Pending? */
cd; cd;
*/ */
PendingCmd operator,(const PendingCmd&, const Cmd&); PendingCmd operator,(const PendingCmd&, const Cmd&);
PendingCmd operator,(RetProc, const Cmd&); PendingCmd operator,(DeadProc, const Cmd&);
/* Forbiden funcion to prevent wrong sequencing such as: /* Forbiden funcion to prevent wrong sequencing such as:
echo, echo && echo echo, echo && echo
here the 2nd and 3rd echos would be ran before 1st here the 2nd and 3rd echos would be ran before 1st
due to the C++ operator precedence*/ 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 /* 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&); PendingCmd operator|(const PendingCmd&, const Cmd&);
/* Shell operator && - run the second command only if first returns 0 (no errors)*/ /* Shell operator && - run the second command only if first returns 0 (no errors)*/
RetProc operator&&(const PendingCmd&, const Cmd&); DeadProc operator&&(const PendingCmd&, const Cmd&);
RetProc operator&&(RetProc, const Cmd&); DeadProc operator&&(DeadProc, const Cmd&);
/* Shell operator || - run second only if first returns != 0 /* Shell operator || - run second only if first returns != 0
Operator precedence is different from shell, C precendence is && > || Operator precedence is different from shell, C precendence is && > ||
so mixing || and && may not compile, but shouldn't cause other issues, so mixing || and && may not compile, but shouldn't cause other issues,
use () to resolve these cases */ use () to resolve these cases */
RetProc operator||(const PendingCmd&, const Cmd&); DeadProc operator||(const PendingCmd&, const Cmd&);
RetProc operator||(RetProc, const Cmd&); DeadProc operator||(DeadProc, const Cmd&);
/* Shell operator > - redirect output to file /* Shell operator > - redirect output to file
shell: cmd > file 2>&1 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); Proc p = createProcess(argv.data(), in, out, err);
@@ -93,7 +93,7 @@ inline PendingCmd::~PendingCmd()
/* close(err); */ /* close(err); */
} }
inline RetProc PendingCmd::operator()() inline DeadProc PendingCmd::operator()()
{ {
assert(!execed_ && "Executed command twice"); assert(!execed_ && "Executed command twice");
execed_ = true; execed_ = true;
@@ -161,7 +161,7 @@ inline PendingCmd operator,(const PendingCmd& cfirst, const Cmd& second)
return PendingCmd(second); return PendingCmd(second);
} }
inline PendingCmd operator,(RetProc, const Cmd& second) inline PendingCmd operator,(DeadProc, const Cmd& second)
{ {
return PendingCmd(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& first = const_cast<PendingCmd&>(cfirst);
auto& second = const_cast<Cmd&>(csecond); auto& second = const_cast<Cmd&>(csecond);
RetProc firstProc = first(); DeadProc firstProc = first();
if(firstProc) if(firstProc)
return second(); return second();
@@ -186,7 +186,7 @@ inline RetProc operator&&(const PendingCmd& cfirst, const Cmd& csecond)
return firstProc; return firstProc;
} }
inline RetProc operator&&(RetProc p, const Cmd& ccmd) inline DeadProc operator&&(DeadProc p, const Cmd& ccmd)
{ {
auto& cmd = const_cast<Cmd&>(ccmd); auto& cmd = const_cast<Cmd&>(ccmd);
if(p) if(p)
@@ -195,11 +195,11 @@ inline RetProc operator&&(RetProc p, const Cmd& ccmd)
return p; 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& first = const_cast<PendingCmd&>(cfirst);
auto& second = const_cast<Cmd&>(csecond); auto& second = const_cast<Cmd&>(csecond);
RetProc firstProc = first(); DeadProc firstProc = first();
if(!firstProc) if(!firstProc)
return second(); return second();
@@ -207,7 +207,7 @@ inline RetProc operator||(const PendingCmd& cfirst, const Cmd& csecond)
return firstProc; return firstProc;
} }
inline RetProc operator||(RetProc p, const Cmd& ccmd) inline DeadProc operator||(DeadProc p, const Cmd& ccmd)
{ {
auto& cmd = const_cast<Cmd&>(ccmd); auto& cmd = const_cast<Cmd&>(ccmd);
if(!p) if(!p)
+1 -2
View File
@@ -1,6 +1,5 @@
man man
tips tips (sigaction SIGCHILD, SIG_IGN, SIG_DFL)
openBSD support
? ?
precompiled header cppipe.h precompiled header cppipe.h