- Add date command implementation that displays current time in UTC format - Add pwd command to print current working directory - Update Makefile to build date and pwd as user programs with shared ELF loading - Refactor syscall handling to use shared header definitions - Remove KernelGreeting class from kernel startup sequence - Update README and ROADMAP documentation for new user commands - Add test assertions for date and pwd command output in test suite - Introduce reusable command address space management in process.cmaster
parent
0cfa577db1
commit
66184e775c
12 changed files with 332 additions and 87 deletions
@ -0,0 +1,18 @@ |
|||||||
|
#ifndef TYPEPHP_OS_SYSCALL_H |
||||||
|
#define TYPEPHP_OS_SYSCALL_H |
||||||
|
|
||||||
|
/* Keep familiar Linux x86_64 numbers where the operation has a close match.
|
||||||
|
* READDIR is currently a compact TypePHP-OS directory-list operation rather |
||||||
|
* than Linux getdents64's binary record ABI. */ |
||||||
|
enum typephp_os_syscall_number { |
||||||
|
TYPEPHP_SYS_READ = 0, |
||||||
|
TYPEPHP_SYS_WRITE = 1, |
||||||
|
TYPEPHP_SYS_EXEC = 59, |
||||||
|
TYPEPHP_SYS_EXIT = 60, |
||||||
|
TYPEPHP_SYS_GETCWD = 79, |
||||||
|
TYPEPHP_SYS_CHDIR = 80, |
||||||
|
TYPEPHP_SYS_TIME = 201, |
||||||
|
TYPEPHP_SYS_READDIR = 217, |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,82 @@ |
|||||||
|
#include "syscall.h" |
||||||
|
|
||||||
|
static int leap_year(long year) |
||||||
|
{ |
||||||
|
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; |
||||||
|
} |
||||||
|
|
||||||
|
static void append_two_digits(char *output, size_t *offset, long value) |
||||||
|
{ |
||||||
|
output[(*offset)++] = (char) ('0' + (value / 10) % 10); |
||||||
|
output[(*offset)++] = (char) ('0' + value % 10); |
||||||
|
} |
||||||
|
|
||||||
|
static void append_four_digits(char *output, size_t *offset, long value) |
||||||
|
{ |
||||||
|
output[(*offset)++] = (char) ('0' + (value / 1000) % 10); |
||||||
|
output[(*offset)++] = (char) ('0' + (value / 100) % 10); |
||||||
|
output[(*offset)++] = (char) ('0' + (value / 10) % 10); |
||||||
|
output[(*offset)++] = (char) ('0' + value % 10); |
||||||
|
} |
||||||
|
|
||||||
|
void _start(const char *argument) |
||||||
|
{ |
||||||
|
static const int month_days[] = { |
||||||
|
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, |
||||||
|
}; |
||||||
|
char output[25]; |
||||||
|
size_t offset = 0; |
||||||
|
long seconds = typephp_syscall(TYPEPHP_SYS_TIME, 0, 0, 0); |
||||||
|
long days; |
||||||
|
long day_seconds; |
||||||
|
long year = 1970; |
||||||
|
long month = 0; |
||||||
|
int days_in_year; |
||||||
|
int days_in_month; |
||||||
|
|
||||||
|
(void) argument; |
||||||
|
if (seconds < 0) { |
||||||
|
typephp_write("date: clock unavailable\n"); |
||||||
|
typephp_exit(1); |
||||||
|
} |
||||||
|
days = seconds / 86400; |
||||||
|
day_seconds = seconds % 86400; |
||||||
|
for (;;) { |
||||||
|
days_in_year = leap_year(year) ? 366 : 365; |
||||||
|
if (days < days_in_year) { |
||||||
|
break; |
||||||
|
} |
||||||
|
days -= days_in_year; |
||||||
|
++year; |
||||||
|
} |
||||||
|
for (;;) { |
||||||
|
days_in_month = month_days[month]; |
||||||
|
if (month == 1 && leap_year(year)) { |
||||||
|
++days_in_month; |
||||||
|
} |
||||||
|
if (days < days_in_month) { |
||||||
|
break; |
||||||
|
} |
||||||
|
days -= days_in_month; |
||||||
|
++month; |
||||||
|
} |
||||||
|
|
||||||
|
append_four_digits(output, &offset, year); |
||||||
|
output[offset++] = '-'; |
||||||
|
append_two_digits(output, &offset, month + 1); |
||||||
|
output[offset++] = '-'; |
||||||
|
append_two_digits(output, &offset, days + 1); |
||||||
|
output[offset++] = ' '; |
||||||
|
append_two_digits(output, &offset, day_seconds / 3600); |
||||||
|
output[offset++] = ':'; |
||||||
|
append_two_digits(output, &offset, (day_seconds / 60) % 60); |
||||||
|
output[offset++] = ':'; |
||||||
|
append_two_digits(output, &offset, day_seconds % 60); |
||||||
|
output[offset++] = ' '; |
||||||
|
output[offset++] = 'U'; |
||||||
|
output[offset++] = 'T'; |
||||||
|
output[offset++] = 'C'; |
||||||
|
output[offset++] = '\n'; |
||||||
|
typephp_write_bytes(output, offset); |
||||||
|
typephp_exit(0); |
||||||
|
} |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
#include "syscall.h" |
||||||
|
|
||||||
|
void _start(const char *argument) |
||||||
|
{ |
||||||
|
char cwd[16]; |
||||||
|
(void) argument; |
||||||
|
if (typephp_syscall(TYPEPHP_SYS_GETCWD, (long) cwd, sizeof(cwd), 0) < 0) { |
||||||
|
typephp_write("pwd: working directory unavailable\n"); |
||||||
|
typephp_exit(1); |
||||||
|
} |
||||||
|
typephp_write(cwd); |
||||||
|
typephp_write("\n"); |
||||||
|
typephp_exit(0); |
||||||
|
} |
||||||
Loading…
Reference in new issue