From 22f04f137b459b046d758c1829cd69b7d63dc56b Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Wed, 13 Mar 2013 21:55:25 -0700 Subject: [PATCH] Relatively compliant uname() implementation Also, sleep() as a function (implemented by way of nanosleep) and new absolute and relative sleep system calls added to newlib. [ci skip] I damn well know this is going to break CI. --- kernel/include/utsname.h | 1 + kernel/sys/syscall.c | 33 +++- toolchain/patches/newlib/include/syscall.h | 6 +- toolchain/patches/newlib/toaru/sys/utsname.h | 19 +++ toolchain/patches/newlib/toaru/syscalls.c | 168 ++++++++++--------- toolchain/prepare.sh | 4 +- userspace/core/login.c | 14 +- userspace/core/sleep.c | 2 - userspace/core/uname.c | 100 ++++++++++- userspace/extra/csnow.c | 1 - userspace/extra/nyancat.c | 1 - userspace/gui/basic/clock-win.c | 2 - userspace/gui/core/glogin.c | 14 +- userspace/gui/core/panel.c | 14 +- userspace/gui/terminal/terminal.c | 2 - 15 files changed, 261 insertions(+), 120 deletions(-) create mode 120000 kernel/include/utsname.h create mode 100644 toolchain/patches/newlib/toaru/sys/utsname.h diff --git a/kernel/include/utsname.h b/kernel/include/utsname.h new file mode 120000 index 00000000..b78897fd --- /dev/null +++ b/kernel/include/utsname.h @@ -0,0 +1 @@ +../../toolchain/patches/newlib/toaru/sys/utsname.h \ No newline at end of file diff --git a/kernel/sys/syscall.c b/kernel/sys/syscall.c index b4c9e353..c6b983ae 100644 --- a/kernel/sys/syscall.c +++ b/kernel/sys/syscall.c @@ -11,10 +11,16 @@ #include #include +#include + #define SPECIAL_CASE_STDIO #define RESERVED 1 + +static char hostname[256]; +static size_t hostname_len = 0; + /* * System calls themselves */ @@ -328,6 +334,28 @@ static int kernel_name_XXX(char * buffer) { __kernel_arch); } +static int uname(struct utsname * name) { + validate((void *)name); + char version_number[256]; + sprintf(version_number, __kernel_version_format, + __kernel_version_major, + __kernel_version_minor, + __kernel_version_lower, + __kernel_version_suffix); + char version_string[256]; + sprintf(version_string, "%s %s %s", + __kernel_version_codename, + __kernel_build_date, + __kernel_build_time); + strcpy(name->sysname, __kernel_name); + strcpy(name->nodename, hostname); + strcpy(name->release, version_number); + strcpy(name->version, version_string); + strcpy(name->machine, __kernel_arch); + strcpy(name->domainname, ""); + return 0; +} + static int send_signal(pid_t process, uint32_t signal) { process_t * receiver = process_from_pid(process); @@ -426,9 +454,6 @@ static char * getcwd(char * buf, size_t size) { return buf; } -static char hostname[256]; -static size_t hostname_len = 0; - static int sethostname(char * new_hostname) { if (current_process->user == USER_ROOT_UID) { size_t len = strlen(new_hostname) + 1; @@ -579,7 +604,7 @@ static uintptr_t syscalls[] = { (uintptr_t)&sys_getpid, (uintptr_t)&sys_sbrk, (uintptr_t)&getgraphicsaddress, - (uintptr_t)RESERVED, /* 12 */ + (uintptr_t)&uname, /* 12 */ (uintptr_t)RESERVED, (uintptr_t)&seek, (uintptr_t)&stat, diff --git a/toolchain/patches/newlib/include/syscall.h b/toolchain/patches/newlib/include/syscall.h index 291d799e..c3707df0 100644 --- a/toolchain/patches/newlib/include/syscall.h +++ b/toolchain/patches/newlib/include/syscall.h @@ -60,8 +60,7 @@ DECL_SYSCALL0(fork); DECL_SYSCALL0(getpid); DECL_SYSCALL1(sbrk, int); DECL_SYSCALL0(getgraphicsaddress); -DECL_SYSCALL1(kbd_mode, int); -DECL_SYSCALL0(kbd_get); +DECL_SYSCALL1(uname, void *); DECL_SYSCALL3(lseek, int, int, int); DECL_SYSCALL2(fstat, int, void *); DECL_SYSCALL1(setgraphicsoffset, int); @@ -92,6 +91,9 @@ DECL_SYSCALL1(get_fd, int); DECL_SYSCALL0(gettid); DECL_SYSCALL0(yield); DECL_SYSCALL2(system_function, int, char **); +DECL_SYSCALL1(open_serial, int); +DECL_SYSCALL2(sleepabs, unsigned long, unsigned long); +DECL_SYSCALL2(nanosleep, unsigned long, unsigned long); #endif /* diff --git a/toolchain/patches/newlib/toaru/sys/utsname.h b/toolchain/patches/newlib/toaru/sys/utsname.h new file mode 100644 index 00000000..afd80881 --- /dev/null +++ b/toolchain/patches/newlib/toaru/sys/utsname.h @@ -0,0 +1,19 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#define _UTSNAME_LENGTH 256 + +struct utsname { + char sysname[_UTSNAME_LENGTH]; + char nodename[_UTSNAME_LENGTH]; + char release[_UTSNAME_LENGTH]; + char version[_UTSNAME_LENGTH]; + char machine[_UTSNAME_LENGTH]; + char domainname[_UTSNAME_LENGTH]; +}; + +#ifndef _KERNEL_ +int uname(struct utsname *); +#endif + +#endif diff --git a/toolchain/patches/newlib/toaru/syscalls.c b/toolchain/patches/newlib/toaru/syscalls.c index 315456b3..8b2b87c2 100644 --- a/toolchain/patches/newlib/toaru/syscalls.c +++ b/toolchain/patches/newlib/toaru/syscalls.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -34,8 +35,8 @@ DEFN_SYSCALL0(fork, 8); DEFN_SYSCALL0(getpid, 9); DEFN_SYSCALL1(sbrk, 10, int); DEFN_SYSCALL0(getgraphicsaddress, 11); -DEFN_SYSCALL1(kbd_mode, 12, int); -DEFN_SYSCALL0(kbd_get, 13); +DEFN_SYSCALL1(uname, 12, void *); +/* RESERVED syscall 13 */ DEFN_SYSCALL3(lseek, 14, int, int, int); DEFN_SYSCALL2(fstat, 15, int, void *); DEFN_SYSCALL1(setgraphicsoffset, 16, int); @@ -66,6 +67,10 @@ DEFN_SYSCALL1(get_fd, 40, int); DEFN_SYSCALL0(gettid, 41); DEFN_SYSCALL0(yield, 42); DEFN_SYSCALL2(system_function, 43, int, char **); +DEFN_SYSCALL1(open_serial, 44, int); +DEFN_SYSCALL2(sleepabs, 45, unsigned long, unsigned long); +DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); + extern char ** environ; @@ -101,6 +106,10 @@ int fork(void) { return syscall_fork(); } +int uname(struct utsname *__name) { + return syscall_uname((void *)__name); +} + /* * kill -- go out via exit... @@ -176,12 +185,6 @@ int stat(const char *file, struct stat *st){ return ret; } -int unlink(char *name) { - fprintf(stderr, "[debug] pid %d unlink(%s);\n", getpid(), name); - errno = ENOENT; - return -1; -} - int write(int file, char *ptr, int len) { return syscall_write(file,ptr,len); } @@ -217,63 +220,14 @@ int pipe(int fildes[2]) { return 0; } -int fcntl(int fd, int cmd, ...) { - if (cmd == F_GETFD || cmd == F_SETFD) { - return 0; - } - fprintf(stderr, "[user/debug] Unsupported operation [fcntl]\n"); - /* Not supported */ - return -1; -} - -mode_t umask(mode_t mask) { - fprintf(stderr, "[user/debug] Unsupported operation [umask]\n"); - /* Not supported */ - return 0; -} - char *getwd(char *buf) { return syscall_getcwd(buf, 256); } -int chmod(const char *path, mode_t mode) { - fprintf(stderr, "[user/debug] Unsupported operation [chmod]\n"); - /* Not supported */ - return -1; -} - -int access(const char *pathname, int mode) { - fprintf(stderr, "[user/debug] Unsupported operation [access]\n"); - /* Not supported */ - return -1; -} - int lstat(const char *path, struct stat *buf) { return stat(path, buf); } -long pathconf(char *path, int name) { - fprintf(stderr, "[user/debug] Unsupported operation [pathconf]\n"); - /* Not supported */ - return -1; -} - - -int utime(const char *filename, const struct utimbuf *times) { - fprintf(stderr, "[user/debug] Unsupported operation [utime]\n"); - return -1; -} - -int chown(const char *path, uid_t owner, gid_t group) { - fprintf(stderr, "[user/debug] Unsupported operation [chown]\n"); - return -1; -} - -int rmdir(const char *pathname) { - fprintf(stderr, "[user/debug] Unsupported operation [rmdir]\n"); - return -1; -} - int mkdir(const char *pathname, mode_t mode) { return syscall_mkdir(pathname, mode); } @@ -282,13 +236,8 @@ int chdir(const char *path) { return syscall_chdir(path); } -char *ttyname(int fd) { - errno = ENOTTY; - return NULL; -} - unsigned int sleep(unsigned int seconds) { - /* lol go fuck yourself */ + syscall_nanosleep(seconds, 0); return 0; } @@ -327,16 +276,6 @@ int dup2(int oldfd, int newfd) { return syscall_dup2(oldfd, newfd); } -unsigned int alarm(unsigned int seconds) { - fprintf(stderr, "alarm(%s);\n", seconds); - return 0; -} - -clock_t times(struct tms *buf) { - fprintf(stderr, "times(...)\n"); - return -1; -} - DIR * opendir (const char * dirname) { int fd = open(dirname, O_RDONLY); if (fd == -1) { @@ -369,11 +308,6 @@ struct dirent * readdir (DIR * dirp) { return &ent; } -long sysconf(int name) { - fprintf(stderr, "sysconf(%d);\n", name); - return -1; -} - void pre_main(int argc, char * argv[]) { unsigned int x = 0; unsigned int nulls = 0; @@ -395,6 +329,84 @@ void pre_main(int argc, char * argv[]) { } +/* XXX Unimplemented functions */ +unsigned int alarm(unsigned int seconds) { + fprintf(stderr, "alarm(%s);\n", seconds); + return 0; +} + +clock_t times(struct tms *buf) { + fprintf(stderr, "times(...)\n"); + return -1; +} + + +int fcntl(int fd, int cmd, ...) { + if (cmd == F_GETFD || cmd == F_SETFD) { + return 0; + } + fprintf(stderr, "[user/debug] Unsupported operation [fcntl]\n"); + /* Not supported */ + return -1; +} + +mode_t umask(mode_t mask) { + fprintf(stderr, "[user/debug] Unsupported operation [umask]\n"); + /* Not supported */ + return 0; +} + +int chmod(const char *path, mode_t mode) { + fprintf(stderr, "[user/debug] Unsupported operation [chmod]\n"); + /* Not supported */ + return -1; +} + +int unlink(char *name) { + fprintf(stderr, "[debug] pid %d unlink(%s);\n", getpid(), name); + errno = ENOENT; + return -1; +} + +int access(const char *pathname, int mode) { + fprintf(stderr, "[user/debug] Unsupported operation [access]\n"); + /* Not supported */ + return -1; +} + +long pathconf(char *path, int name) { + fprintf(stderr, "[user/debug] Unsupported operation [pathconf]\n"); + /* Not supported */ + return -1; +} + + +int utime(const char *filename, const struct utimbuf *times) { + fprintf(stderr, "[user/debug] Unsupported operation [utime]\n"); + return -1; +} + +int chown(const char *path, uid_t owner, gid_t group) { + fprintf(stderr, "[user/debug] Unsupported operation [chown]\n"); + return -1; +} + +int rmdir(const char *pathname) { + fprintf(stderr, "[user/debug] Unsupported operation [rmdir]\n"); + return -1; +} + + +char *ttyname(int fd) { + errno = ENOTTY; + return NULL; +} + +long sysconf(int name) { + fprintf(stderr, "sysconf(%d);\n", name); + return -1; +} + /* termios */ speed_t cfgetispeed(const struct termios * tio) { return 0; diff --git a/toolchain/prepare.sh b/toolchain/prepare.sh index 9b9aeab7..746e340b 100755 --- a/toolchain/prepare.sh +++ b/toolchain/prepare.sh @@ -19,8 +19,8 @@ pushd "$DIR" > /dev/null fi pushd tarballs > /dev/null $INFO "wget" "Pulling source packages..." - grab "gcc" "http://gcc.petsads.us/releases/gcc-4.6.0" "gcc-core-4.6.0.tar.gz" - grab "g++" "http://gcc.petsads.us/releases/gcc-4.6.0" "gcc-g++-4.6.0.tar.gz" + grab "gcc" "http://www.netgull.com/gcc/releases/gcc-4.6.0" "gcc-core-4.6.0.tar.gz" + grab "g++" "http://www.netgull.com/gcc/releases/gcc-4.6.0" "gcc-g++-4.6.0.tar.gz" #grab "mpc" "http://www.multiprecision.org/mpc/download" "mpc-0.9.tar.gz" #grab "mpfr" "http://www.mpfr.org/mpfr-3.0.1" "mpfr-3.0.1.tar.gz" #grab "gmp" "ftp://ftp.gmplib.org/pub/gmp-5.0.1" "gmp-5.0.1.tar.gz" diff --git a/userspace/core/login.c b/userspace/core/login.c index 87cf77f6..1ce6b7e9 100644 --- a/userspace/core/login.c +++ b/userspace/core/login.c @@ -14,6 +14,8 @@ #include #include +#include + #include "lib/sha2.h" uint32_t child = 0; @@ -70,11 +72,15 @@ int checkUserPass(char * user, char * pass) { int main(int argc, char ** argv) { - /* TODO: uname() */ - char * _uname = malloc(sizeof(char) * 1024); - syscall_kernel_string_XXX(_uname); + struct utsname u; + uname(&u); - fprintf(stdout, "\n%s\n\n", _uname); + fprintf(stdout, "\n%s %s %s %s\n\n", + u.sysname, + u.nodename, + u.release, + u.version + ); syscall_signal(2, sig_int); syscall_signal(11, sig_segv); diff --git a/userspace/core/sleep.c b/userspace/core/sleep.c index cbf12cbf..931532c6 100644 --- a/userspace/core/sleep.c +++ b/userspace/core/sleep.c @@ -5,8 +5,6 @@ #include #include -DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); - int main(int argc, char ** argv) { int ret = 0; diff --git a/userspace/core/uname.c b/userspace/core/uname.c index bf884f20..0e046d0f 100644 --- a/userspace/core/uname.c +++ b/userspace/core/uname.c @@ -6,10 +6,104 @@ */ #include #include +#include +#include +#include + +#define FLAG_SYSNAME 0x01 +#define FLAG_NODENAME 0x02 +#define FLAG_RELEASE 0x04 +#define FLAG_VERSION 0x08 +#define FLAG_MACHINE 0x10 + +#define FLAG_ALL (FLAG_SYSNAME|FLAG_NODENAME|FLAG_RELEASE|FLAG_VERSION|FLAG_MACHINE) + +#define _ITALIC "\033[3m" +#define _END "\033[0m\n" + +void show_usage(int argc, char * argv[]) { + fprintf(stderr, + "uname - Print system version information.\n" + "\n" + "usage: %s [-asnrvm]\n" + "\n" + " -a " _ITALIC "Print the standard uname string we all love" _END + " -s " _ITALIC "Print kernel name" _END + " -n " _ITALIC "Print system name" _END + " -r " _ITALIC "Print kernel version number" _END + " -v " _ITALIC "Print the extra kernel version information" _END + " -m " _ITALIC "Print the architecture name" _END + "\n", argv[0]); + exit(1); +} int main(int argc, char * argv[]) { - char _uname[1024]; - syscall_kernel_string_XXX(_uname); + struct utsname u; - fprintf(stdout, "%s\n", _uname); + int c; + int flags = 0; + int space = 0; + + while ((c = getopt(argc, argv, "ahmnrsv")) != -1) { + switch (c) { + case 'a': + flags |= FLAG_ALL; + break; + case 's': + flags |= FLAG_SYSNAME; + break; + case 'n': + flags |= FLAG_NODENAME; + break; + case 'r': + flags |= FLAG_RELEASE; + break; + case 'v': + flags |= FLAG_VERSION; + break; + case 'm': + flags |= FLAG_MACHINE; + break; + case 'h': + default: + show_usage(argc, argv); + break; + } + } + + uname(&u); + + if (!flags) { + /* By default, we just print the kernel name */ + flags = FLAG_SYSNAME; + } + + if (flags & FLAG_SYSNAME) { + if (space++) printf(" "); + printf("%s", u.sysname); + } + + if (flags & FLAG_NODENAME) { + if (space++) printf(" "); + printf("%s", u.nodename); + } + + if (flags & FLAG_RELEASE) { + if (space++) printf(" "); + printf("%s", u.release); + } + + if (flags & FLAG_VERSION) { + if (space++) printf(" "); + printf("%s", u.version); + } + + if (flags & FLAG_MACHINE) { + if (space++) printf(" "); + printf("%s", u.machine); + } + + printf("\n"); + + return 0; } diff --git a/userspace/extra/csnow.c b/userspace/extra/csnow.c index 48c6010f..96e555f6 100644 --- a/userspace/extra/csnow.c +++ b/userspace/extra/csnow.c @@ -5,7 +5,6 @@ #ifdef __toaru__ #include -DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); int usleep(useconds_t time) { syscall_nanosleep(0, time / 10000); } #else #include diff --git a/userspace/extra/nyancat.c b/userspace/extra/nyancat.c index 370afcb2..b9c59ced 100644 --- a/userspace/extra/nyancat.c +++ b/userspace/extra/nyancat.c @@ -69,7 +69,6 @@ #ifndef usleep #include -DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); int usleep(useconds_t time) { syscall_nanosleep(0, time / 10000); diff --git a/userspace/gui/basic/clock-win.c b/userspace/gui/basic/clock-win.c index 8570339d..2dd422b3 100644 --- a/userspace/gui/basic/clock-win.c +++ b/userspace/gui/basic/clock-win.c @@ -18,8 +18,6 @@ struct timeval { #define PI 3.14159265 -DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); - #include #include FT_FREETYPE_H #include FT_CACHE_H diff --git a/userspace/gui/core/glogin.c b/userspace/gui/core/glogin.c index a9ba0184..6cef3fe3 100644 --- a/userspace/gui/core/glogin.c +++ b/userspace/gui/core/glogin.c @@ -10,6 +10,8 @@ #include #include +#include + #include "lib/sha2.h" #include "lib/window.h" #include "lib/graphics.h" @@ -203,17 +205,11 @@ int main (int argc, char ** argv) { char kernel_v[512]; { - char _uname[1024]; - syscall_kernel_string_XXX(_uname); - - char * os_version = strstr(_uname, " "); - os_version++; - char * tmp = strstr(os_version, " "); - tmp[0] = 0; - + struct utsname u; + uname(&u); /* UTF-8 Strings FTW! */ uint8_t * os_name_ = "とあるOS"; - uint32_t l = snprintf(kernel_v, 512, "%s %s", os_name_, os_version); + uint32_t l = snprintf(kernel_v, 512, "%s %s", os_name_, u.release); } uid = 0; diff --git a/userspace/gui/core/panel.c b/userspace/gui/core/panel.c index 44cba199..8c5e7791 100644 --- a/userspace/gui/core/panel.c +++ b/userspace/gui/core/panel.c @@ -10,6 +10,7 @@ #include #include #include +#include #define PANEL_HEIGHT 28 @@ -24,8 +25,6 @@ uint16_t win_width; uint16_t win_height; gfx_context_t * ctx; -DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); - int center_x(int x) { return (win_width - x) / 2; } @@ -107,18 +106,13 @@ int main (int argc, char ** argv) { struct tm * timeinfo; char buffer[80]; - char _uname[1024]; - syscall_kernel_string_XXX(_uname); - - char * os_version = strstr(_uname, " "); - os_version++; - char * tmp = strstr(os_version, " "); - tmp[0] = 0; + struct utsname u; + uname(&u); /* UTF-8 Strings FTW! */ uint8_t * os_name_ = "とあるOS"; uint8_t final[512]; - uint32_t l = snprintf(final, 512, "%s %s", os_name_, os_version); + uint32_t l = snprintf(final, 512, "%s %s", os_name_, u.release); syscall_signal(2, sig_int); diff --git a/userspace/gui/terminal/terminal.c b/userspace/gui/terminal/terminal.c index ab0fce98..3ecb150a 100644 --- a/userspace/gui/terminal/terminal.c +++ b/userspace/gui/terminal/terminal.c @@ -26,8 +26,6 @@ #include FT_FREETYPE_H #include FT_CACHE_H -DEFN_SYSCALL2(nanosleep, 46, unsigned long, unsigned long); - #include #include "lib/wcwidth.h"