2020-01-18 11:38:21 +03:00
/*
2020-09-16 19:56:00 +03:00
* Copyright ( c ) 2020 , the SerenityOS developers .
2020-01-18 11:38:21 +03:00
*
2021-04-22 11:24:48 +03:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-01-18 11:38:21 +03:00
*/
2021-04-03 22:57:31 +03:00
# include <LibCore/ArgsParser.h>
2020-09-16 19:56:00 +03:00
# include <LibCore/DirIterator.h>
2019-02-22 03:55:22 +03:00
# include <stdio.h>
2020-09-16 19:56:00 +03:00
# include <stdlib.h>
2019-06-07 12:49:31 +03:00
# include <unistd.h>
2019-02-22 03:55:22 +03:00
2020-09-16 19:56:00 +03:00
int main ( int argc , char * * argv )
2019-02-22 03:55:22 +03:00
{
2020-09-16 19:56:00 +03:00
if ( pledge ( " stdio rpath exec " , nullptr ) < 0 ) {
2020-02-18 15:19:10 +03:00
perror ( " pledge " ) ;
return 1 ;
}
2021-04-03 22:57:31 +03:00
bool ignore_env = false ;
const char * split_string = nullptr ;
Vector < const char * > values ;
2020-09-16 19:56:00 +03:00
2021-04-03 22:57:31 +03:00
Core : : ArgsParser args_parser ;
2021-06-07 22:27:21 +03:00
args_parser . set_stop_on_first_non_option ( true ) ;
2021-04-03 22:57:31 +03:00
args_parser . add_option ( ignore_env , " Start with an empty environment " , " ignore-environment " , ' i ' ) ;
args_parser . add_option ( split_string , " Process and split S into separate arguments; used to pass multiple arguments on shebang lines " , " split-string " , ' S ' , " S " ) ;
args_parser . add_positional_argument ( values , " Environment and commands " , " env/command " , Core : : ArgsParser : : Required : : No ) ;
args_parser . parse ( argc , argv ) ;
if ( ignore_env )
clearenv ( ) ;
size_t argv_start ;
for ( argv_start = 0 ; argv_start < values . size ( ) ; + + argv_start ) {
if ( StringView { values [ argv_start ] } . contains ( ' = ' ) ) {
putenv ( const_cast < char * > ( values [ argv_start ] ) ) ;
2020-09-16 19:56:00 +03:00
} else {
break ;
}
}
2021-04-03 22:57:31 +03:00
Vector < String > split_string_storage ;
Vector < const char * > new_argv ;
if ( split_string ) {
for ( auto view : StringView ( split_string ) . split_view ( ' ' ) ) {
split_string_storage . append ( view ) ;
}
for ( auto & str : split_string_storage ) {
new_argv . append ( str . characters ( ) ) ;
}
}
for ( size_t i = argv_start ; i < values . size ( ) ; + + i ) {
new_argv . append ( values [ i ] ) ;
}
if ( new_argv . size ( ) = = 0 ) {
2020-09-16 19:56:00 +03:00
for ( auto entry = environ ; * entry ! = nullptr ; + + entry )
2021-05-31 17:43:25 +03:00
outln ( " {} " , * entry ) ;
2020-09-16 19:56:00 +03:00
return 0 ;
}
2021-04-03 22:57:31 +03:00
new_argv . append ( nullptr ) ;
2020-09-16 19:56:00 +03:00
2021-04-03 22:57:31 +03:00
const char * executable = new_argv [ 0 ] ;
char * const * new_argv_ptr = const_cast < char * const * > ( & new_argv [ 0 ] ) ;
2020-09-16 19:56:00 +03:00
2021-04-03 22:57:31 +03:00
execvp ( executable , new_argv_ptr ) ;
perror ( " execvp " ) ;
2020-09-16 19:56:00 +03:00
return 1 ;
2019-02-22 03:55:22 +03:00
}