From f191b84b5032880f17d3a8973a3b6b21048013dc Mon Sep 17 00:00:00 2001 From: Luke Payne <1432762+lukepayne@users.noreply.github.com> Date: Sun, 26 Apr 2020 15:59:47 +1000 Subject: [PATCH] Kernel: Added the ability to set the hostname via new syscall Userland/hostname: Now takes parameter to set the hostname LibC/unistd: Added sethostname function --- Kernel/Process.cpp | 12 ++++++++++++ Kernel/Process.h | 1 + Kernel/Syscall.h | 1 + Libraries/LibC/unistd.cpp | 6 ++++++ Libraries/LibC/unistd.h | 1 + Shell/GlobalState.h | 2 +- Userland/hostname.cpp | 26 ++++++++++++++++++-------- 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index ec5befdc5ed..c81e9598ed6 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -712,6 +712,18 @@ int Process::sys$gethostname(char* buffer, ssize_t size) return 0; } +int Process::sys$sethostname(const char* hostname, ssize_t length) +{ + REQUIRE_PROMISE(stdio); + if (length < 0) + return -EINVAL; + LOCKER(*s_hostname_lock, Lock::Mode::Shared); + if (length > 64) + return -ENAMETOOLONG; + *s_hostname = validate_and_copy_string_from_user(hostname, length); + return 0; +} + pid_t Process::sys$fork(RegisterState& regs) { REQUIRE_PROMISE(proc); diff --git a/Kernel/Process.h b/Kernel/Process.h index fb9c505e9ce..0727b7d0e74 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -223,6 +223,7 @@ public: int sys$clock_settime(clockid_t, timespec*); int sys$clock_nanosleep(const Syscall::SC_clock_nanosleep_params*); int sys$gethostname(char*, ssize_t); + int sys$sethostname(const char*, ssize_t); int sys$uname(utsname*); int sys$readlink(const Syscall::SC_readlink_params*); int sys$ttyname_r(int fd, char*, ssize_t); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index c0820c45a9a..b1b8fa130d9 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -63,6 +63,7 @@ namespace Kernel { __ENUMERATE_SYSCALL(getcwd) \ __ENUMERATE_SYSCALL(gettimeofday) \ __ENUMERATE_SYSCALL(gethostname) \ + __ENUMERATE_SYSCALL(sethostname) \ __ENUMERATE_SYSCALL(chdir) \ __ENUMERATE_SYSCALL(uname) \ __ENUMERATE_SYSCALL(set_mmap_name) \ diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index 8b03c9df3e5..03c44bd0601 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -352,6 +352,12 @@ int gethostname(char* buffer, size_t size) __RETURN_WITH_ERRNO(rc, rc, -1); } +int sethostname(const char* hostname, ssize_t size) +{ + int rc = syscall(SC_sethostname, hostname, size); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + ssize_t readlink(const char* path, char* buffer, size_t size) { Syscall::SC_readlink_params params { { path, strlen(path) }, { buffer, size } }; diff --git a/Libraries/LibC/unistd.h b/Libraries/LibC/unistd.h index bf8e80068ce..7ed9ebeee8a 100644 --- a/Libraries/LibC/unistd.h +++ b/Libraries/LibC/unistd.h @@ -104,6 +104,7 @@ int stat(const char* path, struct stat* statbuf); int sleep(unsigned seconds); int usleep(useconds_t); int gethostname(char*, size_t); +int sethostname(const char*, ssize_t); ssize_t readlink(const char* path, char* buffer, size_t); char* ttyname(int fd); int ttyname_r(int fd, char* buffer, size_t); diff --git a/Shell/GlobalState.h b/Shell/GlobalState.h index 3a92ca34b66..4558447ad20 100644 --- a/Shell/GlobalState.h +++ b/Shell/GlobalState.h @@ -36,7 +36,7 @@ struct GlobalState { String username; String home; char ttyname[32]; - char hostname[32]; + char hostname[64]; uid_t uid; struct termios termios; struct termios default_termios; diff --git a/Userland/hostname.cpp b/Userland/hostname.cpp index 15eba021dd1..5015f62a82a 100644 --- a/Userland/hostname.cpp +++ b/Userland/hostname.cpp @@ -36,14 +36,24 @@ int main(int argc, char** argv) return 1; } - (void)argc; - (void)argv; - char buffer[HOST_NAME_MAX]; - int rc = gethostname(buffer, sizeof(buffer)); - if (rc < 0) { - printf("gethostname() error: %s\n", strerror(errno)); - return 1; + if (argc == 1) { + char buffer[HOST_NAME_MAX]; + int rc = gethostname(buffer, sizeof(buffer)); + if (rc < 0) { + printf("gethostname() error: %s\n", strerror(errno)); + return 1; + } + printf("%s\n", buffer); } - printf("%s\n", buffer); + else if (argc == 2) { + if (strlen(argv[1]) >= HOST_NAME_MAX) { + printf("hostname must be less than %i characters\n", HOST_NAME_MAX); + return 1; + } + else { + sethostname(argv[1], strlen(argv[1])); + } + } + return 0; }