@ -14,70 +14,101 @@
namespace Util {
void System : : operator ( ) ( const char * command )
System : : System ( )
{
// Split modifies the string, so two copies are needed
char charCommand [ strlen ( command ) ] ;
strcpy ( charCommand , command ) ;
char charCommand2 [ strlen ( command ) ] ;
strcpy ( charCommand2 , command ) ;
size_t index = split ( charCommand , " " ) ;
}
// Preallocation is roughly ~10% faster even with just a single space.
std : : vector < char * > arguments ( index + 1 , 0 ) ;
System : : System ( std : : vector < std : : string > arguments )
: m_arguments ( arguments )
{
}
split ( charCommand2 , " " , [ & arguments ] ( int index , char * pointer ) {
arguments [ index ] = pointer ;
} ) ;
System System : : operator ( ) ( )
{
return exec ( ) ;
}
operator ( ) ( arguments ) ;
System System : : operator ( ) ( const char * command )
{
return operator ( ) ( std : : string { command } ) ;
}
void System : : operator ( ) ( std : : string command )
System System : : operator ( ) ( std : : string command )
{
operator ( ) ( command . c_str ( ) ) ;
std : : vector < std : : string > arguments ;
size_t index = 0 ;
while ( index ! = std : : string : : npos ) {
index = command . find_first_of ( " " ) ;
arguments . push_back ( command . substr ( 0 , index ) ) ;
command = command . substr ( index + 1 ) ;
}
return System ( arguments ) ;
}
void System : : operator ( ) ( std : : string_view command )
System System : : operator ( ) ( std : : string_view command )
{
operator ( ) ( command . data ( ) ) ;
return operator ( ) ( std : : string { command } ) ;
}
void System : : operator ( ) ( const std : : vector < const char * > & arguments )
System System : : operator ( ) ( const std : : vector < const char * > & arguments )
{
std : : vector < char * > nonCon stArguments( arguments . size ( ) + 1 , 0 ) ;
std : : vector < std : : string > string Arguments ( arguments . size ( ) , " " ) ;
for ( size_t i = 0 ; i < arguments . size ( ) ; + + i ) {
nonCon stArguments[ i ] = const_cast < char * > ( arguments [ i ] ) ;
string Arguments [ i ] = arguments [ i ] ;
}
operator ( ) ( nonConstArguments ) ;
return System ( stringArguments ) ;
}
void System : : operator ( ) ( const std : : vector < std : : string > & arguments )
System System : : operator ( ) ( const std : : vector < std : : string > & arguments )
{
std : : vector < char * > nonConstArguments ( arguments . size ( ) + 1 , 0 ) ;
return System ( arguments ) ;
}
System System : : operator ( ) ( const std : : vector < std : : string_view > & arguments )
{
std : : vector < std : : string > stringArguments ( arguments . size ( ) , " " ) ;
for ( size_t i = 0 ; i < arguments . size ( ) ; + + i ) {
nonConstArguments [ i ] = const_cast < char * > ( arguments [ i ] . c_str ( ) ) ;
string Arguments [ i ] = arguments [ i ] ;
}
operator ( ) ( nonConstArguments ) ;
return System ( stringArguments ) ;
}
System System : : operator | ( System rhs )
{
rhs . exec ( exec ( ) . output ( ) ) ;
return rhs ;
}
void System : : operator ( ) ( const std : : vector < std : : string_view > & arguments )
void System : : print ( const std : : vector < std : : string > & arguments )
{
std : : vector < char * > nonConstArguments ( arguments . size ( ) + 1 , 0 ) ;
if ( ! arguments . size ( ) ) {
return ;
}
printf ( " ---------- \n " ) ;
printf ( " size: %zu \n " , arguments . size ( ) ) ;
printf ( " command: " ) ;
for ( size_t i = 0 ; i < arguments . size ( ) ; + + i ) {
nonConstArguments [ i ] = const_cast < char * > ( arguments [ i ] . data ( ) ) ;
printf ( " %s " , arguments . at ( i ) . c_str ( ) ) ;
}
operator ( ) ( nonConstArguments ) ;
printf ( " \n " ) ;
printf ( " ---------- \n " ) ;
}
// -----------------------------------------
void System : : operator ( ) ( const std : : vector < char * > & arguments )
System System : : exec ( std : : string input )
{
int stdinFd [ 2 ] ;
int stdoutFd [ 2 ] ;
int stderrFd [ 2 ] ;
if ( pipe ( stdinFd ) < 0 ) {
perror ( " \033 [31;1mError \033 [0m " ) ;
}
if ( pipe ( stdoutFd ) < 0 ) {
perror ( " \033 [31;1mError \033 [0m " ) ;
}
@ -93,6 +124,10 @@ void System::operator()(const std::vector<char*>& arguments)
break ;
// Child
case 0 : {
close ( stdinFd [ WriteFileDescriptor ] ) ;
dup2 ( stdinFd [ ReadFileDescriptor ] , fileno ( stdin ) ) ;
close ( stdinFd [ ReadFileDescriptor ] ) ;
close ( stdoutFd [ ReadFileDescriptor ] ) ;
dup2 ( stdoutFd [ WriteFileDescriptor ] , fileno ( stdout ) ) ;
close ( stdoutFd [ WriteFileDescriptor ] ) ;
@ -101,7 +136,12 @@ void System::operator()(const std::vector<char*>& arguments)
dup2 ( stderrFd [ WriteFileDescriptor ] , fileno ( stderr ) ) ;
close ( stderrFd [ WriteFileDescriptor ] ) ;
execvp ( arguments [ 0 ] , & arguments [ 0 ] ) ;
std : : vector < char * > charArguments ( m_arguments . size ( ) + 1 , 0 ) ;
for ( size_t i = 0 ; i < m_arguments . size ( ) ; + + i ) {
charArguments [ i ] = const_cast < char * > ( m_arguments [ i ] . c_str ( ) ) ;
}
execvp ( charArguments [ 0 ] , & charArguments [ 0 ] ) ;
exit ( 0 ) ;
}
// Parent
@ -109,6 +149,12 @@ void System::operator()(const std::vector<char*>& arguments)
break ;
}
close ( stdinFd [ ReadFileDescriptor ] ) ;
if ( ! input . empty ( ) ) {
write ( stdinFd [ WriteFileDescriptor ] , input . c_str ( ) , input . size ( ) ) ;
}
close ( stdinFd [ WriteFileDescriptor ] ) ;
readFromFileDescriptor ( stdoutFd , m_output ) ;
readFromFileDescriptor ( stderrFd , m_error ) ;
@ -117,11 +163,14 @@ void System::operator()(const std::vector<char*>& arguments)
result = waitpid ( pid , & m_status , 0 ) ;
} while ( result = = - 1 & & errno = = EINTR ) ;
m_status = WEXITSTATUS ( m_status ) ;
return * this ;
}
void System : : readFromFileDescriptor ( int fileDescriptor [ 2 ] , std : : string & output )
{
close ( fileDescriptor [ WriteFileDescriptor ] ) ;
output . clear ( ) ;
constexpr int bufferSize = 4096 ;
char buffer [ bufferSize ] ;
@ -141,19 +190,4 @@ void System::readFromFileDescriptor(int fileDescriptor[2], std::string& output)
close ( fileDescriptor [ ReadFileDescriptor ] ) ;
}
size_t System : : split ( char * split , const char * delimiters , SplitCallback callback )
{
size_t index = 0 ;
char * pointer = strtok ( split , delimiters ) ;
while ( pointer ! = nullptr ) {
if ( callback ) {
callback ( index , pointer ) ;
}
index + + ;
pointer = strtok ( nullptr , delimiters ) ;
}
return index ;
}
} // namespace Util