init
This commit is contained in:
+160
@@ -0,0 +1,160 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "childProcess.hpp"
|
||||
|
||||
/* All CONST references are used and cast away to allow for taking
|
||||
both l and r values without using templates or making copies
|
||||
|
||||
implicitly convert to it but not to const char* and we want the
|
||||
implicit conversion for quick scripting
|
||||
arg pointers are kept and used not copied */
|
||||
|
||||
/* A shell command */
|
||||
class Cmd
|
||||
{
|
||||
public:
|
||||
/* all args must be const char* */
|
||||
template<typename... Args>
|
||||
explicit Cmd(Args... args)
|
||||
: argv({args...})
|
||||
{
|
||||
argv.push_back(nullptr);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Append arguments */
|
||||
void append_args(std::initializer_list<const char*>);
|
||||
/* Append an argument and return the new command */
|
||||
Cmd operator+(const char* arg);
|
||||
/* Append an argument */
|
||||
Cmd& operator+=(const char* arg);
|
||||
|
||||
std::vector<const char*> argv; /* null terminateded arg list */
|
||||
};
|
||||
|
||||
/* An instance of a shell comand that is pending execution
|
||||
if the command is not executed during the life of the obj
|
||||
its executed on destruction */
|
||||
class PendingCmd
|
||||
{
|
||||
public:
|
||||
/* Can be implicitly created from a command */
|
||||
PendingCmd(const Cmd&, fd_t in=0, fd_t out=1, fd_t err=2);
|
||||
/* Execute the command on destruction */
|
||||
~PendingCmd();
|
||||
|
||||
/* No copy we use unnamed return value optimization to return PendingCmd without destruction */
|
||||
PendingCmd(const PendingCmd&) = delete;
|
||||
PendingCmd& operator=(const PendingCmd&) = delete;
|
||||
|
||||
/* Run the command */
|
||||
RetProc operator()();
|
||||
/* Run the command, capturing the output in a new pipe */
|
||||
RetProc runRedir();
|
||||
|
||||
/* Run the command async
|
||||
shell: cmd &
|
||||
becomes: cmd.detach() */
|
||||
Proc detach();
|
||||
/* Detach but redirect output to a pipe */
|
||||
Proc detachRedirOut();
|
||||
|
||||
/* Prevent a pending command from being executed on destruction */
|
||||
void cancel();
|
||||
|
||||
Cmd cmd;
|
||||
fd_t in, out, err;
|
||||
private:
|
||||
bool execed_;
|
||||
};
|
||||
|
||||
|
||||
/* Anything that takes PendingCmd can take Cmd aswell */
|
||||
|
||||
/* Like shell's exec */
|
||||
void exec(const Cmd&); /* todo: take Pending? */
|
||||
|
||||
/* Run commands in sequence
|
||||
shell:
|
||||
ls
|
||||
cd
|
||||
becomes:
|
||||
ls,
|
||||
cd;
|
||||
*/
|
||||
PendingCmd operator,(const PendingCmd&, const Cmd&);
|
||||
PendingCmd operator,(RetProc, 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;
|
||||
|
||||
|
||||
/* Shell pipe operator | - execute two commands, second takes input
|
||||
from first can be chained many times */
|
||||
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&);
|
||||
|
||||
/* 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&);
|
||||
|
||||
/* Shell operator > - redirect output to file
|
||||
shell: cmd > file 2>&1
|
||||
becomes: cmd > "file" >=1 */
|
||||
PendingCmd& operator>(const PendingCmd&, const char* file);
|
||||
/* A file descriptor can be given istead of a file path in which case
|
||||
* no truncation occurs */
|
||||
PendingCmd& operator>(const PendingCmd&, fd_t);
|
||||
/* Same but append rather then truncate the file */
|
||||
PendingCmd& operator>>(const PendingCmd&, const char* file);
|
||||
PendingCmd& operator>>(const PendingCmd&, fd_t);
|
||||
/* Redirect errors to file */
|
||||
PendingCmd& operator>=(const PendingCmd&, const char* file);
|
||||
PendingCmd& operator>=(const PendingCmd&, fd_t);
|
||||
/* todo >>= */
|
||||
|
||||
/* Shell oprator < use file as input */
|
||||
PendingCmd& operator<(const PendingCmd&, const char* file);
|
||||
PendingCmd& operator<(const PendingCmd&, fd_t);
|
||||
|
||||
/* Shell operator & but only for single processes
|
||||
e.g.: echo a && echo b & echo c
|
||||
in shell would detach "echo a && echo b" but here
|
||||
this is not possible */
|
||||
PendingCmd operator&(const PendingCmd&, const Cmd&);
|
||||
|
||||
/* string that is implicitly cast to const char* and doesn't deallocate
|
||||
to allow for simpler synthax, speed and safety
|
||||
e.g: echo + some_string
|
||||
rather then: echo + some_string.c_str() */
|
||||
class str: public std::basic_string<char> /* todo: allocator */
|
||||
{
|
||||
public:
|
||||
using std::basic_string<char>::basic_string;
|
||||
operator const char*() { return c_str();}
|
||||
};
|
||||
|
||||
/* Execute a command and capture the output
|
||||
shell:
|
||||
var=$(ls)
|
||||
becomes:
|
||||
string var = $(ls);
|
||||
*/
|
||||
str $(const PendingCmd&);
|
||||
Reference in New Issue
Block a user