mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-24 21:45:20 +00:00
Userland: Add support for -S to env command
- Refactor env to use Core::ArgsParser - create symlink from /bin/env to /usr/bin/env for compatiability
This commit is contained in:
parent
938924f36d
commit
eca20e92da
Notes:
sideshowbarker
2024-07-18 20:29:18 +09:00
Author: https://github.com/petelliott Commit: https://github.com/SerenityOS/serenity/commit/eca20e92daf Pull-request: https://github.com/SerenityOS/serenity/pull/6227 Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/bcoles
2 changed files with 40 additions and 21 deletions
1
Base/usr/bin/env
Symbolic link
1
Base/usr/bin/env
Symbolic link
|
@ -0,0 +1 @@
|
|||
/bin/env
|
|
@ -24,6 +24,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/DirIterator.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -36,40 +37,57 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
const char* filename = nullptr;
|
||||
bool ignore_env = false;
|
||||
const char* split_string = nullptr;
|
||||
Vector<const char*> values;
|
||||
|
||||
for (int idx = 1; idx < argc; ++idx) {
|
||||
if (idx == 1) {
|
||||
if (StringView { argv[idx] } == "-i" || StringView { argv[idx] } == "--ignore-environment") {
|
||||
clearenv();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (StringView { argv[idx] }.contains('=')) {
|
||||
putenv(argv[idx]);
|
||||
Core::ArgsParser args_parser;
|
||||
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]));
|
||||
} else {
|
||||
filename = argv[idx];
|
||||
argv += idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filename == nullptr) {
|
||||
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) {
|
||||
for (auto entry = environ; *entry != nullptr; ++entry)
|
||||
printf("%s\n", *entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
String filepath = Core::find_executable_in_path(filename);
|
||||
new_argv.append(nullptr);
|
||||
|
||||
if (filepath.is_null()) {
|
||||
warnln("no {} in path", filename);
|
||||
return 1;
|
||||
}
|
||||
const char* executable = new_argv[0];
|
||||
char* const* new_argv_ptr = const_cast<char* const*>(&new_argv[0]);
|
||||
|
||||
execv(filepath.characters(), argv);
|
||||
|
||||
perror("execv");
|
||||
execvp(executable, new_argv_ptr);
|
||||
perror("execvp");
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue