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>
2021-12-24 19:23:25 +03:00
# include <LibCore/System.h>
# include <LibMain/Main.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
2021-12-24 19:23:25 +03:00
ErrorOr < int > serenity_main ( Main : : Arguments arguments )
2019-02-22 03:55:22 +03:00
{
2021-12-24 19:23:25 +03:00
TRY ( Core : : System : : pledge ( " stdio rpath exec " ) ) ;
2020-02-18 15:19:10 +03:00
2021-04-03 22:57:31 +03:00
bool ignore_env = false ;
2022-07-11 23:42:03 +03:00
StringView split_string { } ;
2023-12-16 17:19:34 +03:00
Vector < ByteString > values_to_set ;
Vector < ByteString > values_to_unset ;
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 " ) ;
2023-06-25 13:53:26 +03:00
args_parser . add_option ( Core : : ArgsParser : : Option {
. argument_mode = Core : : ArgsParser : : OptionArgumentMode : : Required ,
. help_string = " Remove variable from the environment " ,
. long_name = " unset " ,
. short_name = ' u ' ,
. value_name = " name " ,
. accept_value = [ & values_to_unset ] ( StringView value ) {
values_to_unset . append ( value ) ;
return true ;
} ,
} ) ;
2021-04-03 22:57:31 +03:00
2023-06-25 13:53:26 +03:00
args_parser . add_positional_argument ( values_to_set , " Environment and commands " , " env/command " , Core : : ArgsParser : : Required : : No ) ;
2021-12-24 19:23:25 +03:00
args_parser . parse ( arguments ) ;
2021-04-03 22:57:31 +03:00
2023-06-25 13:53:26 +03:00
if ( ignore_env ) {
2021-04-03 22:57:31 +03:00
clearenv ( ) ;
2023-06-25 13:53:26 +03:00
} else {
for ( auto const & value : values_to_unset ) {
if ( unsetenv ( value . characters ( ) ) < 0 ) {
warnln ( " env: cannot unset '{}': {} " , value , strerror ( errno ) ) ;
return 1 ;
}
}
}
2021-04-03 22:57:31 +03:00
size_t argv_start ;
2023-06-25 13:53:26 +03:00
for ( argv_start = 0 ; argv_start < values_to_set . size ( ) ; + + argv_start ) {
if ( values_to_set [ argv_start ] . contains ( ' = ' ) ) {
putenv ( const_cast < char * > ( values_to_set [ argv_start ] . characters ( ) ) ) ;
2020-09-16 19:56:00 +03:00
} else {
break ;
}
}
2022-04-02 18:48:43 +03:00
Vector < StringView > new_argv ;
2022-07-11 23:42:03 +03:00
if ( ! split_string . is_empty ( ) ) {
for ( auto view : split_string . split_view ( ' ' ) ) {
2022-04-02 18:48:43 +03:00
new_argv . append ( view ) ;
2021-04-03 22:57:31 +03:00
}
}
2023-06-25 13:53:26 +03:00
for ( size_t i = argv_start ; i < values_to_set . size ( ) ; + + i ) {
new_argv . append ( values_to_set [ i ] ) ;
2021-04-03 22:57:31 +03:00
}
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 ;
}
2022-04-02 18:48:43 +03:00
TRY ( Core : : System : : exec ( new_argv [ 0 ] , new_argv , Core : : System : : SearchInPath : : Yes ) ) ;
2020-09-16 19:56:00 +03:00
return 1 ;
2019-02-22 03:55:22 +03:00
}