summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/MemoryManager.cpp2
-rw-r--r--Kernel/Process.cpp5
-rw-r--r--Kernel/UnixTypes.h8
-rw-r--r--Kernel/VirtualFileSystem.cpp22
-rw-r--r--Kernel/VirtualFileSystem.h1
-rwxr-xr-xKernel/makeall.sh1
-rw-r--r--LibC/crt0.cpp2
-rw-r--r--LibC/ctype.cpp13
-rw-r--r--LibC/ctype.h15
-rw-r--r--LibC/signal.cpp36
-rw-r--r--LibC/signal.h1
-rw-r--r--LibC/signal_numbers.h75
-rw-r--r--LibC/stdlib.cpp55
-rw-r--r--LibC/string.cpp2
-rw-r--r--LibC/strings.cpp28
-rw-r--r--LibC/termios.cpp9
-rw-r--r--LibC/termios.h2
17 files changed, 200 insertions, 77 deletions
diff --git a/Kernel/MemoryManager.cpp b/Kernel/MemoryManager.cpp
index ad9241d201..05f7083f7d 100644
--- a/Kernel/MemoryManager.cpp
+++ b/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();
}
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index a160c43bf7..67d09899cb 100644
--- a/Kernel/Process.cpp
+++ b/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)
diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h
index 0f9d835e5b..9c1d94ebb9 100644
--- a/Kernel/UnixTypes.h
+++ b/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 {
diff --git a/Kernel/VirtualFileSystem.cpp b/Kernel/VirtualFileSystem.cpp
index 96a9df0849..8f5cc6dd62 100644
--- a/Kernel/VirtualFileSystem.cpp
+++ b/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);
diff --git a/Kernel/VirtualFileSystem.h b/Kernel/VirtualFileSystem.h
index dc41b2dacf..895acf87b8 100644
--- a/Kernel/VirtualFileSystem.h
+++ b/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);
diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh
index d3c5f7fc56..7858fee3c5 100755
--- a/Kernel/makeall.sh
+++ b/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) && \
diff --git a/LibC/crt0.cpp b/LibC/crt0.cpp
index ab6a3ebfe2..a607390e14 100644
--- a/LibC/crt0.cpp
+++ b/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();
diff --git a/LibC/ctype.cpp b/LibC/ctype.cpp
index ba4eb48a2b..af37f95036 100644
--- a/LibC/ctype.cpp
+++ b/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;
+}
diff --git a/LibC/ctype.h b/LibC/ctype.h
index c1282644bd..03ee173e05 100644
--- a/LibC/ctype.h
+++ b/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)
{
diff --git a/LibC/signal.cpp b/LibC/signal.cpp
index 248ac08556..ec2d8c2767 100644
--- a/LibC/signal.cpp
+++ b/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)
diff --git a/LibC/signal.h b/LibC/signal.h
index 2977c7e802..e854b7ed0b 100644
--- a/LibC/signal.h
+++ b/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)
diff --git a/LibC/signal_numbers.h b/LibC/signal_numbers.h
index a26beeaa15..5c974cbf1c 100644
--- a/LibC/signal_numbers.h
+++ b/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
diff --git a/LibC/stdlib.cpp b/LibC/stdlib.cpp
index d7e12e9276..37078f4986 100644
--- a/LibC/stdlib.cpp
+++ b/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);
}
diff --git a/LibC/string.cpp b/LibC/string.cpp
index 01661e3174..e252377cc5 100644
--- a/LibC/string.cpp
+++ b/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");
}
diff --git a/LibC/strings.cpp b/LibC/strings.cpp
index 27d4b8135c..abbfeca214 100644
--- a/LibC/strings.cpp
+++ b/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;
}
}
diff --git a/LibC/termios.cpp b/LibC/termios.cpp
index c3c0ea6b57..8af27ffa06 100644
--- a/LibC/termios.cpp
+++ b/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;
}
}
diff --git a/LibC/termios.h b/LibC/termios.h
index a055f8e255..01529f3df9 100644
--- a/LibC/termios.h
+++ b/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*);