mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:07:45 +00:00
Canonicalize the path used by sh.
With a bunch of LibC work to support the feature. LibC now initializes AK::StringImpl by default. It's now fine to use AK in LibC/Userland! :^)
This commit is contained in:
parent
88ad59bfb1
commit
e904f193c1
15 changed files with 170 additions and 24 deletions
|
@ -1,8 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef SERENITY
|
#ifdef SERENITY
|
||||||
|
#ifdef KERNEL
|
||||||
#include <Kernel/kassert.h>
|
#include <Kernel/kassert.h>
|
||||||
#else
|
#else
|
||||||
|
#include <LibC/assert.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define ASSERT(x) assert(x)
|
#define ASSERT(x) assert(x)
|
||||||
#define ASSERT_NOT_REACHED() assert(false)
|
#define ASSERT_NOT_REACHED() assert(false)
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef SERENITY
|
#ifdef SERENITY
|
||||||
|
#ifdef KERNEL
|
||||||
#include <Kernel/StdLib.h>
|
#include <Kernel/StdLib.h>
|
||||||
#else
|
#else
|
||||||
|
#include <LibC/stdlib.h>
|
||||||
|
#include <LibC/string.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
48
AK/kmalloc.h
48
AK/kmalloc.h
|
@ -3,10 +3,52 @@
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
#ifdef SERENITY
|
#ifdef SERENITY
|
||||||
#ifdef USERLAND
|
#ifdef KERNEL
|
||||||
#include <LibC/stdlib.h>
|
|
||||||
#else
|
|
||||||
#include <Kernel/kmalloc.h>
|
#include <Kernel/kmalloc.h>
|
||||||
|
#else
|
||||||
|
#include <LibC/stdlib.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void* kcalloc(size_t nmemb, size_t size);
|
||||||
|
void* kmalloc(size_t size) MALLOC_ATTR;
|
||||||
|
void kfree(void* ptr);
|
||||||
|
void* krealloc(void* ptr, size_t size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* operator new(size_t size)
|
||||||
|
{
|
||||||
|
return kmalloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* operator new[](size_t size)
|
||||||
|
{
|
||||||
|
return kmalloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator delete(void* ptr)
|
||||||
|
{
|
||||||
|
return kfree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator delete[](void* ptr)
|
||||||
|
{
|
||||||
|
return kfree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator delete(void* ptr, size_t)
|
||||||
|
{
|
||||||
|
return kfree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator delete[](void* ptr, size_t)
|
||||||
|
{
|
||||||
|
return kfree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* operator new(size_t, void* p) { return p; }
|
||||||
|
inline void* operator new[](size_t, void* p) { return p; }
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
|
@ -59,7 +59,7 @@ FLAVOR_FLAGS = -mregparm=3 -march=i386 -m32 -fno-exceptions -fno-rtti -fmerge-al
|
||||||
OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables
|
OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables
|
||||||
INCLUDE_FLAGS = -I.. -I.
|
INCLUDE_FLAGS = -I.. -I.
|
||||||
|
|
||||||
DEFINES = -DSERENITY -DSANITIZE_PTRS
|
DEFINES = -DSERENITY -DKERNEL -DSANITIZE_PTRS
|
||||||
|
|
||||||
CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(KERNEL_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
|
CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(KERNEL_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
|
||||||
#CXX = /usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-g++
|
#CXX = /usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-g++
|
||||||
|
|
|
@ -142,6 +142,7 @@ Task::Region* Task::allocateRegion(size_t size, String&& name)
|
||||||
|
|
||||||
bool Task::deallocateRegion(Region& region)
|
bool Task::deallocateRegion(Region& region)
|
||||||
{
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
for (size_t i = 0; i < m_regions.size(); ++i) {
|
for (size_t i = 0; i < m_regions.size(); ++i) {
|
||||||
if (m_regions[i].ptr() == ®ion) {
|
if (m_regions[i].ptr() == ®ion) {
|
||||||
// FIXME: This seems racy.
|
// FIXME: This seems racy.
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
OBJS = \
|
AK_OBJS = \
|
||||||
|
../AK/StringImpl.o \
|
||||||
|
../AK/String.o \
|
||||||
|
../AK/StringBuilder.o \
|
||||||
|
../AK/FileSystemPath.o \
|
||||||
|
../AK/kmalloc.o
|
||||||
|
|
||||||
|
LIBC_OBJS = \
|
||||||
stdio.o \
|
stdio.o \
|
||||||
unistd.o \
|
unistd.o \
|
||||||
string.o \
|
string.o \
|
||||||
|
@ -8,8 +15,11 @@ OBJS = \
|
||||||
stdlib.o \
|
stdlib.o \
|
||||||
time.o \
|
time.o \
|
||||||
utsname.o \
|
utsname.o \
|
||||||
|
assert.o \
|
||||||
entry.o
|
entry.o
|
||||||
|
|
||||||
|
OBJS = $(AK_OBJS) $(LIBC_OBJS)
|
||||||
|
|
||||||
LIBRARY = LibC.a
|
LIBRARY = LibC.a
|
||||||
ARCH_FLAGS =
|
ARCH_FLAGS =
|
||||||
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
|
STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib
|
||||||
|
@ -19,7 +29,7 @@ FLAVOR_FLAGS = -fomit-frame-pointer -mregparm=3 -march=i386 -m32 -fno-exceptions
|
||||||
OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables
|
OPTIMIZATION_FLAGS = -Os -fno-asynchronous-unwind-tables
|
||||||
INCLUDE_FLAGS = -I.. -I.
|
INCLUDE_FLAGS = -I.. -I.
|
||||||
|
|
||||||
DEFINES = -DSERENITY -DSANITIZE_PTRS
|
DEFINES = -DSERENITY -DUSERLAND -DSANITIZE_PTRS
|
||||||
|
|
||||||
CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(LIBC_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
|
CXXFLAGS = $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(LIBC_FLAGS) $(FLAVOR_FLAGS) $(ARCH_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
|
||||||
CXX = g++-8
|
CXX = g++-8
|
||||||
|
|
14
LibC/assert.cpp
Normal file
14
LibC/assert.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "assert.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
extern void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func)
|
||||||
|
{
|
||||||
|
printf("ASSERTION FAILED: %s\n%s:%u in %s\n", msg, file, line, func);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
14
LibC/assert.h
Normal file
14
LibC/assert.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void __assertion_failed(const char* msg, const char* file, unsigned line, const char* func);
|
||||||
|
|
||||||
|
#define assert(expr) (static_cast<bool>(expr) ? (void)0 : __assertion_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__))
|
||||||
|
#define CRASH() do { asm volatile("ud2"); } while(0)
|
||||||
|
#define ASSERT assert
|
||||||
|
#define RELEASE_ASSERT assert
|
||||||
|
#define ASSERT_NOT_REACHED() assert(false)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <Kernel/Syscall.h>
|
#include <Kernel/Syscall.h>
|
||||||
|
#include <AK/StringImpl.h>
|
||||||
|
|
||||||
extern "C" int main(int, char**);
|
extern "C" int main(int, char**);
|
||||||
|
|
||||||
|
@ -8,6 +9,8 @@ extern "C" int _start()
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
|
StringImpl::initializeGlobals();
|
||||||
|
|
||||||
int argc;
|
int argc;
|
||||||
char** argv;
|
char** argv;
|
||||||
int rc = Syscall::invoke(Syscall::GetArguments, (dword)&argc, (dword)&argv);
|
int rc = Syscall::invoke(Syscall::GetArguments, (dword)&argc, (dword)&argv);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "mman.h"
|
#include "mman.h"
|
||||||
|
#include <Kernel/Syscall.h>
|
||||||
|
#include <AK/Assertions.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -20,5 +22,28 @@ void free(void* ptr)
|
||||||
munmap(ptr, 4096);
|
munmap(ptr, 4096);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* calloc(size_t nmemb, size_t)
|
||||||
|
{
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* realloc(void *ptr, size_t)
|
||||||
|
{
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exit(int status)
|
||||||
|
{
|
||||||
|
Syscall::invoke(Syscall::PosixExit, (dword)status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void abort()
|
||||||
|
{
|
||||||
|
// FIXME: Implement proper abort().
|
||||||
|
exit(253);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,11 @@ extern "C" {
|
||||||
|
|
||||||
void* malloc(size_t);
|
void* malloc(size_t);
|
||||||
void free(void*);
|
void free(void*);
|
||||||
|
void* calloc(size_t nmemb, size_t);
|
||||||
|
void* realloc(void *ptr, size_t);
|
||||||
|
|
||||||
|
void exit(int status);
|
||||||
|
void abort();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,17 @@ int strcmp(const char* s1, const char* s2)
|
||||||
return *(const unsigned char*)s1 < *(const unsigned char*)s2 ? -1 : 1;
|
return *(const unsigned char*)s1 < *(const unsigned char*)s2 ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int memcmp(const void* v1, const void* v2, size_t n)
|
||||||
|
{
|
||||||
|
auto* s1 = (const byte*)v1;
|
||||||
|
auto* s2 = (const byte*)v2;
|
||||||
|
while (n-- > 0) {
|
||||||
|
if (*s1++ != *s2++)
|
||||||
|
return s1[-1] < s2[-1] ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void memcpy(void* dest, const void* src, size_t n)
|
void memcpy(void* dest, const void* src, size_t n)
|
||||||
{
|
{
|
||||||
auto* bdest = (unsigned char*)dest;
|
auto* bdest = (unsigned char*)dest;
|
||||||
|
|
|
@ -6,6 +6,7 @@ extern "C" {
|
||||||
|
|
||||||
size_t strlen(const char*);
|
size_t strlen(const char*);
|
||||||
int strcmp(const char*, const char*);
|
int strcmp(const char*, const char*);
|
||||||
|
int memcmp(const void*, const void*, size_t);
|
||||||
void memcpy(void*, const void*, size_t);
|
void memcpy(void*, const void*, size_t);
|
||||||
const char* strerror(int errnum);
|
const char* strerror(int errnum);
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,25 @@
|
||||||
#include <LibC/errno.h>
|
#include <LibC/errno.h>
|
||||||
#include <LibC/string.h>
|
#include <LibC/string.h>
|
||||||
#include <LibC/stdlib.h>
|
#include <LibC/stdlib.h>
|
||||||
|
#include <AK/FileSystemPath.h>
|
||||||
|
|
||||||
char* g_cwd = nullptr;
|
struct GlobalState {
|
||||||
char g_hostname[32];
|
String cwd;
|
||||||
|
char hostname[32];
|
||||||
|
};
|
||||||
|
static GlobalState* g;
|
||||||
|
|
||||||
static void prompt()
|
static void prompt()
|
||||||
{
|
{
|
||||||
if (getuid() == 0)
|
if (getuid() == 0)
|
||||||
printf("# ");
|
printf("# ");
|
||||||
else
|
else
|
||||||
printf("\033[32;1m%s\033[0m:\033[34;1m%s\033[0m$> ", g_hostname, g_cwd);
|
printf("\033[32;1m%s\033[0m:\033[34;1m%s\033[0m$> ", g->hostname, g->cwd.characters());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sh_pwd(int, const char**)
|
static int sh_pwd(int, const char**)
|
||||||
{
|
{
|
||||||
printf("%s\n", g_cwd);
|
printf("%s\n", g->cwd.characters());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,26 +34,34 @@ static int sh_cd(int argc, const char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
char pathbuf[128];
|
char pathbuf[128];
|
||||||
if (argv[1][1] == '/')
|
if (argv[1][0] == '/')
|
||||||
memcpy(pathbuf, argv[1], strlen(argv[1]));
|
memcpy(pathbuf, argv[1], strlen(argv[1]) + 1);
|
||||||
else
|
else
|
||||||
sprintf(pathbuf, "%s/%s", g_cwd, argv[1]);
|
sprintf(pathbuf, "%s/%s", g->cwd.characters(), argv[1]);
|
||||||
|
|
||||||
|
FileSystemPath canonicalPath(pathbuf);
|
||||||
|
if (!canonicalPath.isValid()) {
|
||||||
|
printf("FileSystemPath failed to canonicalize '%s'\n", pathbuf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const char* path = canonicalPath.string().characters();
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int rc = lstat(pathbuf, &st);
|
int rc = lstat(path, &st);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
printf("lstat(%s) failed: %s\n", pathbuf, strerror(errno));
|
printf("lstat(%s) failed: %s\n", path, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(st.st_mode)) {
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
printf("Not a directory: %s\n", pathbuf);
|
printf("Not a directory: %s\n", path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
rc = chdir(pathbuf);
|
rc = chdir(path);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
printf("chdir(%s) failed: %s\n", pathbuf, strerror(errno));
|
printf("chdir(%s) failed: %s\n", path, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memcpy(g_cwd, pathbuf, strlen(pathbuf));
|
g->cwd = canonicalPath.string();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +127,8 @@ static int runcmd(char* cmd)
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
int rc = gethostname(g_hostname, sizeof(g_hostname));
|
g = new GlobalState;
|
||||||
|
int rc = gethostname(g->hostname, sizeof(g->hostname));
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
perror("gethostname");
|
perror("gethostname");
|
||||||
|
|
||||||
|
@ -128,9 +141,7 @@ int main(int, char**)
|
||||||
printf("failed to open /dev/keyboard :(\n");
|
printf("failed to open /dev/keyboard :(\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
g_cwd = (char*)malloc(1024);
|
g->cwd = "/";
|
||||||
g_cwd[0] = '/';
|
|
||||||
g_cwd[1] = '\0';
|
|
||||||
prompt();
|
prompt();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char keybuf[16];
|
char keybuf[16];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <LibC/stdio.cpp>
|
#include <LibC/stdio.h>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue