Userspace: Shell now has time builtin

This commit is contained in:
Bananymous 2023-07-06 00:39:04 +03:00
parent 3c068aa0ae
commit 7f8b7b811e
1 changed files with 43 additions and 18 deletions

View File

@ -4,12 +4,15 @@
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <ctype.h> #include <ctype.h>
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
#define ERROR_RETURN(msg) { perror(msg); return 1; }
struct termios old_termios, new_termios; struct termios old_termios, new_termios;
BAN::Optional<BAN::String> parse_dollar(BAN::StringView command, size_t& i) BAN::Optional<BAN::String> parse_dollar(BAN::StringView command, size_t& i)
@ -173,10 +176,7 @@ int execute_command(BAN::StringView command)
continue; continue;
if (setenv(BAN::String(split[0]).data(), BAN::String(split[1]).data(), true) == -1) if (setenv(BAN::String(split[0]).data(), BAN::String(split[1]).data(), true) == -1)
{ ERROR_RETURN("setenv");
perror("setenv");
return 1;
}
} }
} }
else if (args.front() == "cd"sv) else if (args.front() == "cd"sv)
@ -200,33 +200,58 @@ int execute_command(BAN::StringView command)
path = args[1]; path = args[1];
if (chdir(path.data()) == -1) if (chdir(path.data()) == -1)
{ ERROR_RETURN("chdir");
perror("chdir");
return 1;
}
} }
else else
{ {
bool time = false;
if (args.front() == "time"sv)
{
args.remove(0);
time = true;
}
BAN::Vector<char*> cmd_args;
MUST(cmd_args.reserve(args.size() + 1));
for (const auto& arg : args)
MUST(cmd_args.push_back((char*)arg.data()));
MUST(cmd_args.push_back(nullptr));
timespec start;
if (time && clock_gettime(CLOCK_MONOTONIC, &start) == -1)
ERROR_RETURN("clock_gettime");
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) if (pid == 0)
{ {
BAN::Vector<char*> cmd_args;
MUST(cmd_args.reserve(args.size() + 1));
for (const auto& arg : args)
MUST(cmd_args.push_back((char*)arg.data()));
MUST(cmd_args.push_back(nullptr));
execv(cmd_args.front(), cmd_args.data()); execv(cmd_args.front(), cmd_args.data());
perror("execv"); perror("execv");
exit(1); exit(1);
} }
if (pid == -1) if (pid == -1)
{ ERROR_RETURN("fork");
perror("fork");
return 1;
}
int status; int status;
if (waitpid(pid, &status, 0) == -1) if (waitpid(pid, &status, 0) == -1)
perror("waitpid"); ERROR_RETURN("waitpid");
if (time)
{
timespec end;
if (clock_gettime(CLOCK_MONOTONIC, &end) == -1)
ERROR_RETURN("clock_gettime");
uint64_t total_ns = 0;
total_ns += (end.tv_sec - start.tv_sec) * 1'000'000'000;
total_ns += end.tv_nsec - start.tv_nsec;
printf(
"took %d.%03d s\n",
(int)( total_ns / 1'000'000'000),
(int)((total_ns % 1'000'000'000) / 1'000'000)
);
}
return status;
} }
return 0; return 0;