add check_exited, exit on waitpid errors
This commit is contained in:
+10
-6
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user