Ver código fonte

Compat work towards porting vim.

Andreas Kling 6 anos atrás
pai
commit
a356746d04

+ 1 - 1
Kernel/MemoryManager.cpp

@@ -389,7 +389,7 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault)
             ASSERT(success);
             return PageFaultResponse::Continue;
         }
-        kprintf("PV(error) fault in Region{%p}[%u]\n", region, page_index_in_region);
+        kprintf("PV(error) fault in Region{%p}[%u] at L%x\n", region, page_index_in_region, fault.laddr().get());
     } else {
         ASSERT_NOT_REACHED();
     }

+ 2 - 3
Kernel/Process.cpp

@@ -226,7 +226,7 @@ Process* Process::fork(RegisterDump& regs)
 
     for (auto& region : m_regions) {
 #ifdef FORK_DEBUG
-        dbgprintf("fork: cloning Region{%p} \"%s\" L%x\n", region.ptr(), region->name.characters(), region->laddr().get());
+        dbgprintf("fork: cloning Region{%p} \"%s\" L%x\n", region.ptr(), region->name().characters(), region->laddr().get());
 #endif
         auto cloned_region = region->clone();
         child->m_regions.append(move(cloned_region));
@@ -1140,10 +1140,9 @@ int Process::sys$utime(const char* pathname, const utimbuf* buf)
 
 int Process::sys$access(const char* pathname, int mode)
 {
-    (void) mode;
     if (!validate_read_str(pathname))
         return -EFAULT;
-    ASSERT_NOT_REACHED();
+    return VFS::the().access(String(pathname), mode, cwd_inode());
 }
 
 int Process::sys$fcntl(int fd, int cmd, dword arg)

+ 8 - 0
Kernel/UnixTypes.h

@@ -2,6 +2,11 @@
 
 #define WNOHANG 1
 
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_OK 0
+
 #define SIG_DFL ((void*)0)
 #define SIG_ERR ((void*)-1)
 #define SIG_IGN ((void*)1)
@@ -265,6 +270,7 @@ typedef dword blkcnt_t;
 
 typedef uint32_t tcflag_t;
 typedef uint8_t cc_t;
+typedef uint32_t speed_t;
 
 struct termios {
     tcflag_t c_iflag;
@@ -272,6 +278,8 @@ struct termios {
     tcflag_t c_cflag;
     tcflag_t c_lflag;
     cc_t     c_cc[NCCS];
+    speed_t  c_ispeed;
+    speed_t  c_ospeed;
 };
 
 struct stat {

+ 22 - 0
Kernel/VirtualFileSystem.cpp

@@ -268,6 +268,28 @@ KResult VFS::mkdir(const String& path, mode_t mode, Inode& base)
     return KResult(error);
 }
 
+KResult VFS::access(const String& path, int mode, Inode& base)
+{
+    auto inode_or_error = resolve_path_to_inode(path, base);
+    if (inode_or_error.is_error())
+        return inode_or_error.error();
+    auto inode = inode_or_error.value();
+    auto metadata = inode->metadata();
+    if (mode & R_OK) {
+        if (!metadata.may_read(*current))
+            return KResult(-EACCES);
+    }
+    if (mode & W_OK) {
+        if (!metadata.may_write(*current))
+            return KResult(-EACCES);
+    }
+    if (mode & X_OK) {
+        if (!metadata.may_execute(*current))
+            return KResult(-EACCES);
+    }
+    return KSuccess;
+}
+
 KResult VFS::chmod(const String& path, mode_t mode, Inode& base)
 {
     auto inode_or_error = resolve_path_to_inode(path, base);

+ 1 - 0
Kernel/VirtualFileSystem.h

@@ -70,6 +70,7 @@ public:
     bool unlink(const String& path, Inode& base, int& error);
     bool rmdir(const String& path, Inode& base, int& error);
     KResult chmod(const String& path, mode_t, Inode& base);
+    KResult access(const String& path, int mode, Inode& base);
     bool stat(const String& path, int& error, int options, Inode& base, struct stat&);
     KResult utime(const String& path, Inode& base, time_t atime, time_t mtime);
 

+ 0 - 1
Kernel/makeall.sh

@@ -4,7 +4,6 @@ sudo id
 
 make_cmd="make -j2"
 
-rm -r ../Root/usr && \
 $make_cmd -C ../LibC clean && \
 $make_cmd -C ../LibC && \
 (cd ../LibC && ./install.sh) && \

+ 2 - 0
LibC/crt0.cpp

@@ -8,6 +8,7 @@ int main(int, char**);
 
 int errno;
 char** environ;
+//bool __environ_is_malloced;
 
 void __malloc_init();
 void __stdio_init();
@@ -16,6 +17,7 @@ int _start(int argc, char** argv, char** env)
 {
     errno = 0;
     environ = env;
+    //__environ_is_malloced = false;
 
     __stdio_init();
     __malloc_init();

+ 13 - 0
LibC/ctype.cpp

@@ -1,3 +1,16 @@
 #include <ctype.h>
 #include <string.h>
 
+int __tolower(int c)
+{
+    if (c >= 'A' && c <= 'Z')
+        return c | 0x20;
+    return c;
+}
+
+int __toupper(int c)
+{
+    if (c >= 'a' && c <= 'z')
+        return c & ~0x20;
+    return c;
+}

+ 2 - 13
LibC/ctype.h

@@ -25,19 +25,8 @@ ALWAYS_INLINE int __isupper(int c)
     return c >= 'A' && c <= 'Z';
 }
 
-ALWAYS_INLINE int __tolower(int c)
-{
-    if (__isupper(c))
-        return c | 0x20;
-    return c;
-}
-
-ALWAYS_INLINE int __toupper(int c)
-{
-    if (__islower(c))
-        return c & ~0x20;
-    return c;
-}
+int __tolower(int);
+int __toupper(int);
 
 ALWAYS_INLINE int __isdigit(int c)
 {

+ 32 - 4
LibC/signal.cpp

@@ -102,10 +102,38 @@ int sigpending(sigset_t* set)
 }
 
 const char* sys_siglist[NSIG] = {
-#undef __SIGNAL
-#define __SIGNAL(a, b) b,
-    __ENUMERATE_ALL_SIGNALS
-#undef __SIGNAL
+    "Invalid signal number",
+    "Hangup",
+    "Interrupt",
+    "Quit",
+    "Illegal instruction",
+    "Trap",
+    "Aborted",
+    "Bus error",
+    "FP exception",
+    "Killed",
+    "User signal 1",
+    "Segmentation violation",
+    "User signal 2",
+    "Broken pipe",
+    "Alarm clock",
+    "Terminated",
+    "Stack fault",
+    "Child exited",
+    "Continued",
+    "Stopped (signal)",
+    "Stopped",
+    "Stopped (tty input)",
+    "Stopped (tty output)",
+    "Urgent I/O condition)",
+    "CPU limit exceeded",
+    "File size limit exceeded",
+    "Virtual timer expired",
+    "Profiling timer expired",
+    "Window changed",
+    "I/O possible",
+    "Power failure",
+    "Bad system call",
 };
 
 int sigsetjmp(jmp_buf env, int savesigs)

+ 0 - 1
LibC/signal.h

@@ -35,7 +35,6 @@ int sigprocmask(int how, const sigset_t* set, sigset_t* old_set);
 int sigpending(sigset_t*);
 int raise(int sig);
 
-#define NSIG 32
 extern const char* sys_siglist[NSIG];
 
 #define SIG_DFL ((__sighandler_t)0)

+ 33 - 42
LibC/signal_numbers.h

@@ -1,44 +1,35 @@
 #pragma once
 
-#define __ENUMERATE_ALL_SIGNALS \
-    __SIGNAL(SIGINVAL,  "Invalid signal number") \
-    __SIGNAL(SIGHUP,    "Hangup") \
-    __SIGNAL(SIGINT,    "Interrupt") \
-    __SIGNAL(SIGQUIT,   "Quit") \
-    __SIGNAL(SIGILL,    "Illegal instruction") \
-    __SIGNAL(SIGTRAP,   "Trap") \
-    __SIGNAL(SIGABRT,   "Aborted") \
-    __SIGNAL(SIGBUS,    "Bus error") \
-    __SIGNAL(SIGFPE,    "FP exception") \
-    __SIGNAL(SIGKILL,   "Killed") \
-    __SIGNAL(SIGUSR1,   "User signal 1") \
-    __SIGNAL(SIGSEGV,   "Segmentation violation") \
-    __SIGNAL(SIGUSR2,   "User signal 2") \
-    __SIGNAL(SIGPIPE,   "Broken pipe") \
-    __SIGNAL(SIGALRM,   "Alarm clock") \
-    __SIGNAL(SIGTERM,   "Terminated") \
-    __SIGNAL(SIGSTKFLT, "Stack fault") \
-    __SIGNAL(SIGCHLD,   "Child exited") \
-    __SIGNAL(SIGCONT,   "Continued") \
-    __SIGNAL(SIGSTOP,   "Stopped (signal)") \
-    __SIGNAL(SIGTSTP,   "Stopped") \
-    __SIGNAL(SIGTTIN,   "Stopped (tty input)") \
-    __SIGNAL(SIGTTOU,   "Stopped (tty output)") \
-    __SIGNAL(SIGURG,    "Urgent I/O condition)") \
-    __SIGNAL(SIGXCPU,   "CPU limit exceeded") \
-    __SIGNAL(SIGXFSZ,   "File size limit exceeded") \
-    __SIGNAL(SIGVTALRM, "Virtual timer expired") \
-    __SIGNAL(SIGPROF,   "Profiling timer expired") \
-    __SIGNAL(SIGWINCH,  "Window changed") \
-    __SIGNAL(SIGIO,     "I/O possible") \
-    __SIGNAL(SIGPWR,    "Power failure") \
-    __SIGNAL(SIGSYS,    "Bad system call") \
-
-
-enum __signal_numbers {
-#undef __SIGNAL
-#define __SIGNAL(a, b) a,
-    __ENUMERATE_ALL_SIGNALS
-#undef __SIGNAL
-    __signal_count
-};
+#define SIGINVAL   0
+#define SIGHUP     1
+#define SIGINT     2
+#define SIGQUIT    3
+#define SIGILL     4
+#define SIGTRAP    5
+#define SIGABRT    6
+#define SIGBUS     7
+#define SIGFPE     8
+#define SIGKILL    9
+#define SIGUSR1    10
+#define SIGSEGV    11
+#define SIGUSR2    12
+#define SIGPIPE    13
+#define SIGALRM    14
+#define SIGTERM    15
+#define SIGSTKFLT  16
+#define SIGCHLD    17
+#define SIGCONT    18
+#define SIGSTOP    19
+#define SIGTSTP    20
+#define SIGTTIN    21
+#define SIGTTOU    22
+#define SIGURG     23
+#define SIGXCPU    24
+#define SIGXFSZ    25
+#define SIGVTALRM  26
+#define SIGPROF    27
+#define SIGWINCH   28
+#define SIGIO      29
+#define SIGPWR     30
+#define SIGSYS     31
+#define NSIG       32

+ 50 - 5
LibC/stdlib.cpp

@@ -10,6 +10,8 @@
 #include <AK/Types.h>
 #include <Kernel/Syscall.h>
 #include <AK/StdLibExtras.h>
+#include <AK/HashMap.h>
+#include <AK/AKString.h>
 
 extern "C" {
 
@@ -31,8 +33,8 @@ struct MallocFooter {
     uint32_t xorcheck;
 };
 
-#define CHUNK_SIZE  8
-#define POOL_SIZE   128 * 1024
+#define CHUNK_SIZE  16
+#define POOL_SIZE   4 * 1048576
 
 static const size_t malloc_budget = POOL_SIZE;
 static byte s_malloc_map[POOL_SIZE / CHUNK_SIZE / 8];
@@ -201,13 +203,56 @@ char* getenv(const char* name)
     return nullptr;
 }
 
-int putenv(char*)
+int putenv(char* new_var)
 {
-    assert(false);
+    HashMap<String, String> environment;
+
+    auto handle_environment_entry = [&environment] (const char* decl) {
+        char* eq = strchr(decl, '=');
+        if (!eq)
+            return;
+        size_t var_length = eq - decl;
+        char* var = (char*)alloca(var_length + 1);
+        memcpy(var, decl, var_length);
+        var[var_length] = '\0';
+        const char* value = eq + 1;
+        environment.set(var, value);
+    };
+    for (size_t i = 0; environ[i]; ++i)
+        handle_environment_entry(environ[i]);
+    handle_environment_entry(new_var);
+
+    //extern bool __environ_is_malloced;
+    //if (__environ_is_malloced)
+    //    free(environ);
+    //__environ_is_malloced = true;
+
+    int environment_size = sizeof(char*); // For the null sentinel.
+    for (auto& it : environment)
+        environment_size += (int)sizeof(char*) + it.key.length() + 1 + it.value.length() + 1;
+
+    char* buffer = (char*)malloc(environment_size);
+    environ = (char**)buffer;
+    char* bufptr = buffer + sizeof(char*) * (environment.size() + 1);
+
+    int i = 0;
+    for (auto& it : environment) {
+        environ[i] = bufptr;
+        memcpy(bufptr, it.key.characters(), it.key.length());
+        bufptr += it.key.length();
+        *(bufptr++) = '=';
+        memcpy(bufptr, it.value.characters(), it.value.length());
+        bufptr += it.value.length();
+        *(bufptr++) = '\0';
+        ++i;
+    }
+    environ[environment.size()] = nullptr;
+    return 0;
 }
 
-double atof(const char*)
+double atof(const char* str)
 {
+    dbgprintf("LibC: atof: '%s'\n", str);
     assert(false);
 }
 

+ 1 - 1
LibC/string.cpp

@@ -260,7 +260,7 @@ char* strerror(int errnum)
 
 char* strsignal(int signum)
 {
-    if (signum >= __signal_count) {
+    if (signum >= NSIG) {
         printf("strsignal() missing string for signum=%d\n", signum);
         return const_cast<char*>("Unknown signal");
     }

+ 24 - 4
LibC/strings.cpp

@@ -1,16 +1,36 @@
 #include <strings.h>
 #include <assert.h>
+#include <ctype.h>
 
 extern "C" {
 
-int strcasecmp(const char*, const char*)
+static char foldcase(char ch)
 {
-    assert(false);
+    if (isalpha(ch))
+        return tolower(ch);
+    return ch;
 }
 
-int strncasecmp(const char*, const char*, size_t)
+int strcasecmp(const char* s1, const char* s2)
 {
-    assert(false);
+    for (; foldcase(*s1) == foldcase(*s2); ++s1, ++s2) {
+        if (*s1 == 0)
+            return 0;
+    }
+    return foldcase(*(const unsigned char*)s1) < foldcase(*(const unsigned char*)s2) ? -1 : 1;
+}
+
+int strncasecmp(const char* s1, const char* s2, size_t n)
+{
+    if (!n)
+        return 0;
+    do {
+        if (foldcase(*s1) != foldcase(*s2++))
+            return foldcase(*(const unsigned char*)s1) - foldcase(*(const unsigned char*)--s2);
+        if (*s1++ == 0)
+            break;
+    } while (--n);
+    return 0;
 }
 
 }

+ 7 - 2
LibC/termios.cpp

@@ -39,9 +39,14 @@ int tcflush(int fd, int queue_selector)
     assert(false);
 }
 
-speed_t cfgetospeed(const struct termios*)
+speed_t cfgetispeed(const struct termios* tp)
 {
-    assert(false);
+    return tp->c_ispeed;
+}
+
+speed_t cfgetospeed(const struct termios* tp)
+{
+    return tp->c_ospeed;
 }
 
 }

+ 2 - 0
LibC/termios.h

@@ -17,6 +17,8 @@ struct termios {
     tcflag_t c_cflag;
     tcflag_t c_lflag;
     cc_t     c_cc[NCCS];
+    speed_t  c_ispeed;
+    speed_t  c_ospeed;
 };
 
 int tcgetattr(int fd, struct termios*);