Browse Source

Add sys$gethostname and /bin/hostname

Andreas Kling 6 years ago
parent
commit
53abfa7ea1
16 changed files with 77 additions and 40 deletions
  1. 12 0
      AK/String.cpp
  2. 2 0
      AK/String.h
  3. 2 0
      Kernel/Syscall.cpp
  4. 1 0
      Kernel/Syscall.h
  5. 20 0
      Kernel/Task.cpp
  6. 1 0
      Kernel/Task.h
  7. BIN
      Kernel/_fs_contents
  8. 2 1
      Kernel/errno.h
  9. 1 0
      Kernel/sync-sh
  10. 1 37
      LibC/errno.h
  11. 1 0
      LibC/string.cpp
  12. 6 0
      LibC/unistd.cpp
  13. 3 0
      LibC/unistd.h
  14. 1 0
      Userland/.gitignore
  15. 7 2
      Userland/Makefile
  16. 17 0
      Userland/hostname.cpp

+ 12 - 0
AK/String.cpp

@@ -22,6 +22,18 @@ String String::empty()
     return StringImpl::theEmptyStringImpl();
 }
 
+String String::isolatedCopy() const
+{
+    if (!m_impl)
+        return { };
+    if (!m_impl->length())
+        return empty();
+    char* buffer;
+    auto impl = StringImpl::createUninitialized(length(), buffer);
+    memcpy(buffer, m_impl->characters(), m_impl->length());
+    return String(move(*impl));
+}
+
 String String::substring(size_t start, size_t length) const
 {
     ASSERT(m_impl);

+ 2 - 0
AK/String.h

@@ -69,6 +69,8 @@ public:
     bool operator==(const String&) const;
     bool operator!=(const String& other) const { return !(*this == other); }
 
+    String isolatedCopy() const;
+
     static String empty();
 
     StringImpl* impl() { return m_impl.ptr(); }

+ 2 - 0
Kernel/Syscall.cpp

@@ -100,6 +100,8 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3)
         return (dword)current->sys$mmap((void*)arg1, (size_t)arg2);
     case Syscall::PosixMunmap:
         return current->sys$munmap((void*)arg1, (size_t)arg2);
+    case Syscall::PosixGethostname:
+        return current->sys$gethostname((char*)arg1, (size_t)arg2);
     case Syscall::PosixExit:
         cli();
         locker.unlock();

+ 1 - 0
Kernel/Syscall.h

@@ -30,6 +30,7 @@ enum Function {
     PosixLstat = 0x1998,
     PosixGetcwd = 0x1999,
     PosixGettimeofday = 0x2000,
+    PosixGethostname = 0x2001,
 };
 
 void initialize();

+ 20 - 0
Kernel/Task.cpp

@@ -24,6 +24,13 @@ Task* s_kernelTask;
 static pid_t next_pid;
 static InlineLinkedList<Task>* s_tasks;
 static InlineLinkedList<Task>* s_deadTasks;
+static String* s_hostname;
+
+static String& hostname(InterruptDisabler&)
+{
+    ASSERT(s_hostname);
+    return *s_hostname;
+}
 
 static bool contextSwitch(Task*);
 
@@ -61,6 +68,7 @@ void Task::initialize()
     s_tasks = new InlineLinkedList<Task>;
     s_deadTasks = new InlineLinkedList<Task>;
     s_kernelTask = Task::createKernelTask(nullptr, "colonel");
+    s_hostname = new String("birx");
     redoKernelTaskTSS();
     loadTaskRegister(s_kernelTask->selector());
 }
@@ -167,6 +175,18 @@ int Task::sys$munmap(void* addr, size_t size)
     return 0;
 }
 
+int Task::sys$gethostname(char* buffer, size_t size)
+{
+    String hn;
+    {
+        InterruptDisabler disabler;
+        hn = hostname(disabler).isolatedCopy();
+    }
+    if (size < (hn.length() + 1))
+        return -ENAMETOOLONG;
+    memcpy(buffer, hn.characters(), size);
+}
+
 int Task::sys$spawn(const char* path)
 {
     int error = 0;

+ 1 - 0
Kernel/Task.h

@@ -100,6 +100,7 @@ public:
     int sys$getcwd(char*, size_t);
     int sys$sleep(unsigned seconds);
     int sys$gettimeofday(timeval*);
+    int sys$gethostname(char* name, size_t length);
 
     static void initialize();
 

BIN
Kernel/_fs_contents


+ 2 - 1
Kernel/errno.h

@@ -34,5 +34,6 @@
 #define EPIPE     32    // Broken pipe
 #define EDOM      33    // Math argument out of domain of func
 #define ERANGE    34    // Math result not representable
+#define ENAMETOOLONG 36 // Name too long
 
-#define EOVERFLOW 75    // Value too large for defined data type 
+#define EOVERFLOW 75    // Value too large for defined data type

+ 1 - 0
Kernel/sync-sh

@@ -9,5 +9,6 @@ cp ../Userland/sleep mnt/bin/sleep
 cp ../Userland/date mnt/bin/date
 cp ../Userland/true mnt/bin/true
 cp ../Userland/false mnt/bin/false
+cp ../Userland/hostname mnt/bin/hostname
 umount mnt
 sync

+ 1 - 37
LibC/errno.h

@@ -1,42 +1,6 @@
 #pragma once
 
-#define EPERM      1    // Operation not permitted
-#define ENOENT     2    // No such file or directory
-#define ESRCH      3    // No such process
-#define EINTR      4    // Interrupted system call
-#define EIO        5    // I/O error
-#define ENXIO      6    // No such device or address
-#define E2BIG      7    // Argument list too long
-#define ENOEXEC    8    // Exec format error
-#define EBADF      9    // Bad file number
-#define ECHILD    10    // No child processes
-#define EAGAIN    11    // Try again
-#define ENOMEM    12    // Out of memory
-#define EACCES    13    // Permission denied
-#define EFAULT    14    // Bad address
-#define ENOTBLK   15    // Block device required
-#define EBUSY     16    // Device or resource busy
-#define EEXIST    17    // File exists
-#define EXDEV     18    // Cross-device link
-#define ENODEV    19    // No such device
-#define ENOTDIR   20    // Not a directory
-#define EISDIR    21    // Is a directory
-#define EINVAL    22    // Invalid argument
-#define ENFILE    23    // File table overflow
-#define EMFILE    24    // Too many open files
-#define ENOTTY    25    // Not a typewriter
-#define ETXTBSY   26    // Text file busy
-#define EFBIG     27    // File too large
-#define ENOSPC    28    // No space left on device
-#define ESPIPE    29    // Illegal seek
-#define EROFS     30    // Read-only file system
-#define EMLINK    31    // Too many links
-#define EPIPE     32    // Broken pipe
-#define EDOM      33    // Math argument out of domain of func
-#define ERANGE    34    // Math result not representable
-
-#define EOVERFLOW 75    // Value too large for defined data type
-
+#include <Kernel/errno.h>
 
 #define __RETURN_WITH_ERRNO(rc, good_ret, bad_ret) \
     do { \

+ 1 - 0
LibC/string.cpp

@@ -50,6 +50,7 @@ const char* strerror(int errnum)
     case EPIPE: return "Broken pipe";
     case EDOM: return "Math argument out of domain";
     case ERANGE: return "Math result not representable";
+    case ENAMETOOLONG: return "Name too long";
     case EOVERFLOW: return "Value too large for data type";
     }
     printf("strerror() missing string for errnum=%d\n", errnum);

+ 6 - 0
LibC/unistd.cpp

@@ -62,5 +62,11 @@ int sleep(unsigned seconds)
     return Syscall::invoke(Syscall::Sleep, (dword)seconds);
 }
 
+int gethostname(char* buffer, size_t size)
+{
+    int rc = Syscall::invoke(Syscall::PosixGethostname, (dword)buffer, (dword)size);
+    __RETURN_WITH_ERRNO(rc, rc, -1);
+}
+
 }
 

+ 3 - 0
LibC/unistd.h

@@ -14,6 +14,9 @@ pid_t waitpid(pid_t);
 char* getcwd(char* buffer, size_t size);
 int lstat(const char* path, stat* statbuf);
 int sleep(unsigned seconds);
+int gethostname(char*, size_t);
+
+#define HOST_NAME_MAX 64
 
 #define	S_IFMT 0170000
 #define	S_IFDIR 0040000

+ 1 - 0
Userland/.gitignore

@@ -7,4 +7,5 @@ sleep
 date
 false
 true
+hostname
 *.o

+ 7 - 2
Userland/Makefile

@@ -7,7 +7,8 @@ OBJS = \
        sleep.o \
        date.o \
        true.o \
-       false.o
+       false.o \
+       hostname.o
 
 APPS = \
        id \
@@ -18,7 +19,8 @@ APPS = \
        sleep \
        date \
        true \
-       false
+       false \
+       hostname
 
 ARCH_FLAGS =
 STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
@@ -65,6 +67,9 @@ true: true.o
 false: false.o
 	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
 
+hostname: hostname.o
+	$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
+
 .cpp.o:
 	@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
 

+ 17 - 0
Userland/hostname.cpp

@@ -0,0 +1,17 @@
+#include <LibC/unistd.h>
+#include <LibC/stdio.h>
+#include <LibC/errno.h>
+#include <LibC/string.h>
+
+int main(int c, char** v)
+{
+    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);
+    return 0;
+}
+