From 3ad7ab4fc3ed7c5e3d627526ff202068607489a2 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 5 Oct 2014 15:02:50 +0200 Subject: [PATCH] Add gethostname(2) and sethostname(2). --- kernel/Makefile | 1 + kernel/hostname.cpp | 87 +++++++++++++++++++++++++++++++++ kernel/hostname.h | 36 ++++++++++++++ kernel/include/sortix/limits.h | 36 ++++++++++++++ kernel/include/sortix/syscall.h | 4 +- kernel/kernel.cpp | 4 ++ libc/Makefile | 1 + libc/include/unistd.h | 1 + libc/unistd/gethostname.cpp | 22 +++------ libc/unistd/sethostname.cpp | 34 +++++++++++++ utils/sortix-sh.cpp | 6 ++- 11 files changed, 215 insertions(+), 17 deletions(-) create mode 100644 kernel/hostname.cpp create mode 100644 kernel/hostname.h create mode 100644 kernel/include/sortix/limits.h create mode 100644 libc/unistd/sethostname.cpp diff --git a/kernel/Makefile b/kernel/Makefile index 57e3407f..e7d09076 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -92,6 +92,7 @@ fs/user.o \ fs/util.o \ fs/zero.o \ gpu/bga/bga.o \ +hostname.o \ identity.o \ initrd.o \ inode.o \ diff --git a/kernel/hostname.cpp b/kernel/hostname.cpp new file mode 100644 index 00000000..498d80a5 --- /dev/null +++ b/kernel/hostname.cpp @@ -0,0 +1,87 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + hostname.cpp + System calls for managing the hostname of the current system. + +*******************************************************************************/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "hostname.h" + +namespace Sortix { +namespace Hostname { + +static kthread_mutex_t hostname_lock = KTHREAD_MUTEX_INITIALIZER; + +static char hostname[HOST_NAME_MAX + 1] = "sortix"; +static size_t hostname_length = 6; + +static int sys_gethostname(char* dst_name, size_t dst_name_size) +{ + if ( dst_name_size == 0 ) + return errno = EINVAL, -1; + size_t dst_name_length = dst_name_size - 1; + ScopedLock lock(&hostname_lock); + if ( dst_name_length < hostname_length ) + errno = ERANGE; + if ( hostname_length < dst_name_length ) + dst_name_length = hostname_length; + if ( !CopyToUser(dst_name, hostname, dst_name_length) ) + return -1; + char nul = '\0'; + if ( !CopyToUser(dst_name + dst_name_length, &nul, 1) ) + return -1; + return 0; +} + +static int sys_sethostname(const char* src_name, size_t src_name_size) +{ + char new_hostname[HOST_NAME_MAX + 1]; + if ( sizeof(new_hostname) < src_name_size ) + return errno = EINVAL, -1; + if ( !CopyFromUser(new_hostname, src_name, src_name_size) ) + return -1; + size_t new_hostname_length = strnlen(new_hostname, sizeof(new_hostname)); + if ( HOST_NAME_MAX < new_hostname_length ) + return errno = EINVAL, -1; + new_hostname[new_hostname_length] = '\0'; + ScopedLock lock(&hostname_lock); + memcpy(hostname, new_hostname, new_hostname_length + 1); + hostname_length = new_hostname_length; + return 0; +} + +void Init() +{ + Syscall::Register(SYSCALL_GETHOSTNAME, (void*) sys_gethostname); + Syscall::Register(SYSCALL_SETHOSTNAME, (void*) sys_sethostname); +} + +} // namespace Hostname +} // namespace Sortix diff --git a/kernel/hostname.h b/kernel/hostname.h new file mode 100644 index 00000000..f706c226 --- /dev/null +++ b/kernel/hostname.h @@ -0,0 +1,36 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + hostname.h + System calls for managing the hostname of the current system. + +*******************************************************************************/ + +#ifndef SORTIX_HOSTNAME_H +#define SORTIX_HOSTNAME_H + +namespace Sortix { +namespace Hostname { + +void Init(); + +} // namespace Hostname +} // namespace Sortix + +#endif diff --git a/kernel/include/sortix/limits.h b/kernel/include/sortix/limits.h new file mode 100644 index 00000000..53e83a0c --- /dev/null +++ b/kernel/include/sortix/limits.h @@ -0,0 +1,36 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + sortix/limits.h + System limits. + +*******************************************************************************/ + +#ifndef INCLUDE_SORTIX_LIMITS_H +#define INCLUDE_SORTIX_LIMITS_H + +#include + +__BEGIN_DECLS + +#define HOST_NAME_MAX 255 + +__END_DECLS + +#endif diff --git a/kernel/include/sortix/syscall.h b/kernel/include/sortix/syscall.h index 229faa9c..d213d203 100644 --- a/kernel/include/sortix/syscall.h +++ b/kernel/include/sortix/syscall.h @@ -173,6 +173,8 @@ #define SYSCALL_GETSOCKNAME 145 #define SYSCALL_SHUTDOWN 146 #define SYSCALL_GETENTROPY 147 -#define SYSCALL_MAX_NUM 148 /* index of highest constant + 1 */ +#define SYSCALL_GETHOSTNAME 148 +#define SYSCALL_SETHOSTNAME 149 +#define SYSCALL_MAX_NUM 150 /* index of highest constant + 1 */ #endif diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 40719440..f885ec3e 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -79,6 +79,7 @@ #include "fs/user.h" #include "fs/zero.h" #include "gpu/bga/bga.h" +#include "hostname.h" #include "identity.h" #include "initrd.h" #include "io.h" @@ -613,6 +614,9 @@ static void BootThread(void* /*user*/) // Initialize the identity system calls. Identity::Init(); + // Initialize the hostname system calls. + Hostname::Init(); + // Initialize the IO system. IO::Init(); diff --git a/libc/Makefile b/libc/Makefile index 86e335f3..deb603e3 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -617,6 +617,7 @@ unistd/sbrk.o \ unistd/setegid.o \ unistd/seteuid.o \ unistd/setgid.o \ +unistd/sethostname.o \ unistd/setpgid.o \ unistd/setuid.o \ unistd/sfork.o \ diff --git a/libc/include/unistd.h b/libc/include/unistd.h index 6a97b01a..40ce431b 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -553,6 +553,7 @@ int getdomainname(char*, size_t); int getentropy(void*, size_t); int pipe2(int [2], int); void* sbrk(__intptr_t increment); +int sethostname(const char*, size_t); typedef unsigned int useconds_t; int usleep(useconds_t useconds); #endif diff --git a/libc/unistd/gethostname.cpp b/libc/unistd/gethostname.cpp index 9f756d81..3ac3c167 100644 --- a/libc/unistd/gethostname.cpp +++ b/libc/unistd/gethostname.cpp @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(C) Jonas 'Sortie' Termansen 2013. + Copyright(C) Jonas 'Sortie' Termansen 2013, 2014. This file is part of the Sortix C Library. @@ -22,19 +22,13 @@ *******************************************************************************/ -#include -#include -#include -#include +#include -extern "C" int gethostname(char* name, size_t len) +#include + +DEFN_SYSCALL2(int, sys_gethostname, SYSCALL_GETHOSTNAME, char*, size_t); + +extern "C" int gethostname(char* name, size_t name_size) { - const char* hostname = getenv("HOSTNAME"); - if ( !hostname ) - hostname = "sortix"; - size_t hostname_len = strlen(hostname); - if ( len < hostname_len+1 ) - return errno = ENAMETOOLONG, -1; - strcpy(name, hostname); - return 0; + return sys_gethostname(name, name_size); } diff --git a/libc/unistd/sethostname.cpp b/libc/unistd/sethostname.cpp new file mode 100644 index 00000000..1482c67c --- /dev/null +++ b/libc/unistd/sethostname.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + unistd/sethostname.cpp + Set the hostname. + +*******************************************************************************/ + +#include + +#include + +DEFN_SYSCALL2(int, sys_sethostname, SYSCALL_SETHOSTNAME, const char*, size_t); + +extern "C" int sethostname(const char* name, size_t name_size) +{ + return sys_sethostname(name, name_size); +} diff --git a/utils/sortix-sh.cpp b/utils/sortix-sh.cpp index 521f853f..138de3ea 100644 --- a/utils/sortix-sh.cpp +++ b/utils/sortix-sh.cpp @@ -377,14 +377,16 @@ int get_and_run_command(FILE* fp, const char* fpname, bool interactive, const char* print_username = getlogin(); if ( !print_username ) print_username = getuid() == 0 ? "root" : "?"; - const char* print_hostname = getenv_safe("HOSTNAME", "sortix"); + char hostname[256]; + if ( gethostname(hostname, sizeof(hostname)) < 0 ) + strlcpy(hostname, "(none)", sizeof(hostname)); const char* print_dir = getenv_safe("PWD", "?"); const char* home_dir = getenv_safe("HOME", ""); size_t home_dir_len = strlen(home_dir); printf("\e[32m"); printf("%s", print_username); printf("@"); - printf("%s", print_hostname); + printf("%s", hostname); printf(" "); printf("\e[36m"); if ( home_dir_len && strncmp(print_dir, home_dir, home_dir_len) == 0 )