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 )