Rage hacking to get bash to run. It finally runs. So cool! :^)

This commit is contained in:
Andreas Kling 2018-11-11 15:36:40 +01:00
parent 9b70808ab5
commit d5d45d1088
31 changed files with 567 additions and 61 deletions

View file

@ -48,7 +48,7 @@ public:
--m_size;
}
private:
//private:
friend class Vector<T, Allocator>;
VectorImpl(size_t capacity) : m_capacity(capacity) { }
@ -235,7 +235,7 @@ public:
ConstIterator begin() const { return ConstIterator(*this, 0); }
ConstIterator end() const { return ConstIterator(*this, size()); }
private:
//private:
static size_t paddedCapacity(size_t capacity)
{
return max(size_t(4), capacity + (capacity / 4) + 4);

View file

@ -289,7 +289,9 @@ bool MemoryManager::page_in_from_vnode(PageDirectory& page_directory, Region& re
}
remap_region_page(&page_directory, region, page_index_in_region, true);
byte* dest_ptr = region.linearAddress.offset(page_index_in_region * PAGE_SIZE).asPtr();
#ifdef MM_DEBUG
dbgprintf("MM: page_in_from_vnode ready to read from vnode, will write to L%x!\n", dest_ptr);
#endif
sti(); // Oh god here we go...
auto nread = vnode.fileSystem()->readInodeBytes(vnode.inode, vmo.vnode_offset() + ((region.first_page_index() + page_index_in_region) * PAGE_SIZE), PAGE_SIZE, dest_ptr, nullptr);
if (nread < 0) {
@ -444,7 +446,9 @@ void MemoryManager::map_region_at_address(PageDirectory* page_directory, Region&
{
InterruptDisabler disabler;
auto& vmo = region.vmo();
#ifdef MM_DEBUG
dbgprintf("MM: map_region_at_address will map VMO pages %u - %u (VMO page count: %u)\n", region.first_page_index(), region.last_page_index(), vmo.page_count());
#endif
for (size_t i = region.first_page_index(); i <= region.last_page_index(); ++i) {
auto page_laddr = laddr.offset(i * PAGE_SIZE);
auto pte = ensurePTE(page_directory, page_laddr);

View file

@ -431,11 +431,13 @@ int Process::sys$execve(const char* filename, const char** argv, const char** en
{
VALIDATE_USER_READ(filename, strlen(filename));
if (argv) {
VALIDATE_USER_READ(argv, sizeof(const char**));
for (size_t i = 0; argv[i]; ++i) {
VALIDATE_USER_READ(argv[i], strlen(argv[i]));
}
}
if (envp) {
VALIDATE_USER_READ(envp, sizeof(const char**));
for (size_t i = 0; envp[i]; ++i) {
VALIDATE_USER_READ(envp[i], strlen(envp[i]));
}
@ -455,9 +457,8 @@ int Process::sys$execve(const char* filename, const char** argv, const char** en
Vector<String> environment;
if (envp) {
for (size_t i = 0; envp[i]; ++i) {
for (size_t i = 0; envp[i]; ++i)
environment.append(envp[i]);
}
}
int rc = exec(path, move(arguments), move(environment));
@ -976,12 +977,9 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size)
{
VALIDATE_USER_READ(data, size);
#ifdef DEBUG_IO
kprintf("Process::sys$write: called(%d, %p, %u)\n", fd, data, size);
dbgprintf("%s(%u): sys$write(%d, %p, %u)\n", name().characters(), pid(), fd, data, size);
#endif
auto* descriptor = file_descriptor(fd);
#ifdef DEBUG_IO
kprintf("Process::sys$write: handle=%p\n", descriptor);
#endif
if (!descriptor)
return -EBADF;
auto nwritten = descriptor->write((const byte*)data, size);
@ -992,7 +990,7 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size)
return -EINTR;
}
#ifdef DEBUG_IO
kprintf("Process::sys$write: nwritten=%u\n", nwritten);
dbgprintf("%s(%u) sys$write: nwritten=%u\n", name().characters(), pid(), nwritten);
#endif
return nwritten;
}
@ -1001,12 +999,9 @@ ssize_t Process::sys$read(int fd, void* outbuf, size_t nread)
{
VALIDATE_USER_WRITE(outbuf, nread);
#ifdef DEBUG_IO
kprintf("Process::sys$read: called(%d, %p, %u)\n", fd, outbuf, nread);
dbgprintf("%s(%u) sys$read(%d, %p, %u)\n", name().characters(), pid(), fd, outbuf, nread);
#endif
auto* descriptor = file_descriptor(fd);
#ifdef DEBUG_IO
kprintf("Process::sys$read: handle=%p\n", descriptor);
#endif
if (!descriptor)
return -EBADF;
if (descriptor->isBlocking()) {
@ -1020,7 +1015,7 @@ ssize_t Process::sys$read(int fd, void* outbuf, size_t nread)
}
nread = descriptor->read((byte*)outbuf, nread);
#ifdef DEBUG_IO
kprintf("Process::sys$read: nread=%u\n", nread);
dbgprintf("%s(%u) Process::sys$read: nread=%u\n", name().characters(), pid(), nread);
#endif
return nread;
}
@ -1042,14 +1037,27 @@ int Process::sys$access(const char* pathname, int mode)
ASSERT_NOT_REACHED();
}
int Process::sys$fcntl(int fd, int cmd, dword extra_arg)
int Process::sys$fcntl(int fd, int cmd, dword arg)
{
(void) cmd;
(void) extra_arg;
(void) arg;
dbgprintf("sys$fcntl: fd=%d, cmd=%d, arg=%u\n", fd, cmd, arg);
auto* descriptor = file_descriptor(fd);
if (!descriptor)
return -EBADF;
ASSERT_NOT_REACHED();
switch (cmd) {
case F_GETFD:
return descriptor->fd_flags();
case F_SETFD:
return descriptor->set_fd_flags(arg);
case F_GETFL:
return descriptor->file_flags();
case F_SETFL:
return descriptor->set_file_flags(arg);
default:
ASSERT_NOT_REACHED();
}
return 0;
}
int Process::sys$fstat(int fd, Unix::stat* statbuf)
@ -1129,7 +1137,7 @@ int Process::sys$getcwd(char* buffer, size_t size)
if (size < path.length() + 1)
return -ERANGE;
strcpy(buffer, path.characters());
return -ENOTIMPL;
return 0;
}
size_t Process::number_of_open_file_descriptors() const
@ -1145,7 +1153,7 @@ size_t Process::number_of_open_file_descriptors() const
int Process::sys$open(const char* path, int options)
{
#ifdef DEBUG_IO
kprintf("Process::sys$open(): PID=%u, path=%s {%u}\n", m_pid, path, pathLength);
dbgprintf("%s(%u) sys$open(\"%s\")\n", name().characters(), pid(), path);
#endif
VALIDATE_USER_READ(path, strlen(path));
if (number_of_open_file_descriptors() >= m_max_open_file_descriptors)
@ -1307,6 +1315,7 @@ void Process::reap(Process& process)
pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
{
//kprintf("sys$waitpid(%d, %p, %d)\n", waitee, wstatus, options);
// FIXME: Respect options
(void) options;
if (wstatus)
@ -1314,7 +1323,7 @@ pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
{
InterruptDisabler disabler;
if (!Process::from_pid(waitee))
if (waitee != -1 && !Process::from_pid(waitee))
return -ECHILD;
}
m_waitee = waitee;
@ -1326,7 +1335,9 @@ pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
Process* waitee_process;
{
InterruptDisabler disabler;
waitee_process = Process::from_pid(waitee);
// NOTE: If waitee was -1, m_waitee will have been filled in by the scheduler.
waitee_process = Process::from_pid(m_waitee);
}
ASSERT(waitee_process);
reap(*waitee_process);
@ -1471,7 +1482,12 @@ int Process::sys$tcgetattr(int fd, Unix::termios* tp)
return -EBADF;
if (!descriptor->isTTY())
return -ENOTTY;
ASSERT_NOT_REACHED();
auto& tty = *descriptor->tty();
#ifdef TERMIOS_DEBUG
kprintf("sys$tcgetattr(fd=%d, tp=%p)\n", fd, tp);
#endif
memcpy(tp, &tty.termios(), sizeof(Unix::termios));
return 0;
}
int Process::sys$tcsetattr(int fd, int optional_actions, const Unix::termios* tp)
@ -1483,7 +1499,12 @@ int Process::sys$tcsetattr(int fd, int optional_actions, const Unix::termios* tp
return -EBADF;
if (!descriptor->isTTY())
return -ENOTTY;
ASSERT_NOT_REACHED();
#ifdef TERMIOS_DEBUG
kprintf("sys$tcsetattr(fd=%d, tp=%p)\n", fd, tp);
#endif
auto& tty = *descriptor->tty();
memcpy(&tty.termios(), tp, sizeof(Unix::termios));
return 0;
}
pid_t Process::sys$tcgetpgrp(int fd)
@ -1560,20 +1581,25 @@ Unix::sighandler_t Process::sys$signal(int signum, Unix::sighandler_t handler)
int Process::sys$sigprocmask(int how, const Unix::sigset_t* set, Unix::sigset_t* old_set)
{
VALIDATE_USER_READ(set, sizeof(Unix::sigset_t));
if (old_set)
if (old_set) {
VALIDATE_USER_READ(old_set, sizeof(Unix::sigset_t));
*old_set = m_signal_mask;
switch (how) {
case SIG_BLOCK:
m_signal_mask &= ~(*set);
break;
case SIG_UNBLOCK:
m_signal_mask |= *set;
break;
case SIG_SETMASK:
m_signal_mask = *set;
break;
*old_set = m_signal_mask;
}
if (set) {
VALIDATE_USER_READ(set, sizeof(Unix::sigset_t));
switch (how) {
case SIG_BLOCK:
m_signal_mask &= ~(*set);
break;
case SIG_UNBLOCK:
m_signal_mask |= *set;
break;
case SIG_SETMASK:
m_signal_mask = *set;
break;
default:
return -EINVAL;
}
}
return 0;
}

View file

@ -104,6 +104,7 @@ public:
template<typename Callback> static void for_each_in_pgrp(pid_t, Callback);
template<typename Callback> static void for_each_in_state(State, Callback);
template<typename Callback> static void for_each_not_in_state(State, Callback);
template<typename Callback> void for_each_child(Callback);
bool tick() { ++m_ticks; return --m_ticksLeft; }
void set_ticks_left(dword t) { m_ticksLeft = t; }
@ -360,6 +361,21 @@ inline void Process::for_each(Callback callback)
}
}
template<typename Callback>
inline void Process::for_each_child(Callback callback)
{
ASSERT_INTERRUPTS_DISABLED();
pid_t my_pid = pid();
for (auto* process = g_processes->head(); process;) {
auto* next_process = process->next();
if (process->ppid() == my_pid) {
if (!callback(*process))
break;
}
process = next_process;
}
}
template<typename Callback>
inline void Process::for_each_in_pgrp(pid_t pgid, Callback callback)
{

View file

@ -35,15 +35,17 @@ bool Scheduler::pick_next()
}
if (process.state() == Process::BlockedWait) {
auto* waitee = Process::from_pid(process.waitee());
if (!waitee) {
kprintf("waitee %u of %s(%u) reaped before I could wait?\n", process.waitee(), process.name().characters(), process.pid());
ASSERT_NOT_REACHED();
}
if (waitee->state() == Process::Dead) {
process.m_waitee_status = (waitee->m_termination_status << 8) | waitee->m_termination_signal;
process.unblock();
}
process.for_each_child([&process] (Process& child) {
if (child.state() != Process::Dead)
return true;
if (process.waitee() == -1 || process.waitee() == child.pid()) {
process.m_waitee_status = (child.m_termination_status << 8) | child.m_termination_signal;
process.m_waitee = child.pid();
process.unblock();
return false;
}
return true;
});
return true;
}

View file

@ -5,6 +5,8 @@
TTY::TTY(unsigned major, unsigned minor)
: CharacterDevice(major, minor)
{
memset(&m_termios, 0, sizeof(m_termios));
m_termios.c_lflag |= ISIG | ECHO;
}
TTY::~TTY()
@ -42,6 +44,8 @@ void TTY::emit(byte ch)
void TTY::interrupt()
{
if (!should_generate_signals())
return;
dbgprintf("%s: Interrupt ^C pressed!\n", ttyName().characters());
if (pgid()) {
dbgprintf("%s: Send SIGINT to everyone in pgrp %d\n", ttyName().characters(), pgid());

View file

@ -1,6 +1,7 @@
#pragma once
#include <VirtualFileSystem/CharacterDevice.h>
#include <VirtualFileSystem/UnixTypes.h>
class TTY : public CharacterDevice {
public:
@ -15,6 +16,10 @@ public:
void set_pgid(pid_t pgid) { m_pgid = pgid; }
pid_t pgid() const { return m_pgid; }
Unix::termios& termios() { return m_termios; }
bool should_generate_signals() const { return m_termios.c_lflag & ISIG; }
bool should_echo_input() const { return m_termios.c_lflag & ECHO; }
protected:
virtual bool isTTY() const final override { return true; }
@ -28,5 +33,6 @@ protected:
private:
Vector<byte> m_buffer;
pid_t m_pgid { 0 };
Unix::termios m_termios;
};

View file

@ -261,6 +261,17 @@ void VirtualConsole::escape$H(const Vector<unsigned>& params)
set_cursor(row - 1, col - 1);
}
void VirtualConsole::escape$A(const Vector<unsigned>& params)
{
int num = 1;
if (params.size() >= 1)
num = params[0];
int new_row = (int)m_cursor_row - num;
if (new_row < 0)
new_row = 0;
set_cursor(new_row, m_cursor_column);
}
void VirtualConsole::escape$J(const Vector<unsigned>& params)
{
int mode = 0;

View file

@ -40,6 +40,7 @@ private:
void set_cursor(unsigned row, unsigned column);
void put_character_at(unsigned row, unsigned column, byte ch);
void escape$A(const Vector<unsigned>&);
void escape$H(const Vector<unsigned>&);
void escape$J(const Vector<unsigned>&);
void escape$m(const Vector<unsigned>&);

View file

@ -239,8 +239,11 @@ static void init_stage2()
}
#endif
Vector<String> environment;
environment.append("TERM=ansi");
int error;
Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty0);
Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), move(environment), tty0);
#ifdef SPAWN_MULTIPLE_SHELLS
Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty1);
Process::create_user_process("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, Vector<String>(), Vector<String>(), tty2);

View file

@ -5,3 +5,6 @@ cp ../../figlet-2.2.5/fonts/standard.flf mnt/$FIGLET_FONTDIR
cp ../../figlet-2.2.5/fonts/big.flf mnt/$FIGLET_FONTDIR
cp ../../figlet-2.2.5/fonts/slant.flf mnt/$FIGLET_FONTDIR
cp ../../figlet-2.2.5/fonts/lean.flf mnt/$FIGLET_FONTDIR
cp ../../bash-1.14.7/bash2 mnt/bin/bash

View file

@ -28,6 +28,8 @@ LIBC_OBJS = \
ctype.o \
fcntl.o \
termios.o \
ulimit.o \
qsort.o \
entry.o
OBJS = $(AK_OBJS) $(LIBC_OBJS)

View file

@ -1,6 +1,7 @@
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <Kernel/Syscall.h>
extern "C" {

77
LibC/qsort.cpp Normal file
View file

@ -0,0 +1,77 @@
/*-
* Copyright (c) 1980, 1983, 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)qsort.c 5.9 (Berkeley) 2/23/91";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdlib.h>
static void insertion_sort(void* bot, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
void qsort(void* bot, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
{
if (nmemb <= 1)
return;
insertion_sort(bot, nmemb, size, compar);
}
void insertion_sort(void* bot, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
{
int cnt;
unsigned char ch;
char *s1, *s2, *t1, *t2, *top;
/*
* A simple insertion sort (see Knuth, Vol. 3, page 81, Algorithm
* S). Insertion sort has the same worst case as most simple sorts
* (O N^2). It gets used here because it is (O N) in the case of
* sorted data.
*/
top = (char*)bot + nmemb * size;
for (t1 = (char*)bot + size; t1 < top;) {
for (t2 = t1; (t2 -= size) >= bot && compar(t1, t2) < 0;);
if (t1 != (t2 += size)) {
/* Bubble bytes up through each element. */
for (cnt = size; cnt--; ++t1) {
ch = *t1;
for (s1 = s2 = t1; (s2 -= size) >= t2; s1 = s2)
*s1 = *s2;
*s1 = ch;
}
} else
t1 += size;
}
}

View file

@ -4,7 +4,8 @@
int setjmp(jmp_buf)
{
assert(false);
//assert(false);
return 0;
}
void longjmp(jmp_buf, int)

View file

@ -1,6 +1,7 @@
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <Kernel/Syscall.h>
extern "C" {

View file

@ -45,6 +45,7 @@ void __stdio_init()
int setvbuf(FILE* stream, char* buf, int mode, size_t size)
{
fprintf(stderr, "setvbuf(%p [fd=%d], %p, %d, %u)\n", stream, stream->fd, buf, mode, size);
if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF) {
errno = EINVAL;
return -1;
@ -57,6 +58,7 @@ int setvbuf(FILE* stream, char* buf, int mode, size_t size)
stream->buffer = stream->default_buffer;
stream->buffer_size = BUFSIZ;
}
stream->buffer_index = 0;
return 0;
}
@ -65,9 +67,9 @@ void setbuf(FILE* stream, char* buf)
setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
}
void setlinebuf(FILE* stream, char* buf)
void setlinebuf(FILE* stream)
{
setvbuf(stream, buf, buf ? _IOLBF : _IONBF, BUFSIZ);
setvbuf(stream, nullptr, _IOLBF, 0);
}
int fileno(FILE* stream)
@ -138,7 +140,7 @@ int fputc(int ch, FILE* stream)
stream->buffer[stream->buffer_index++] = ch;
if (stream->buffer_index >= stream->buffer_size)
fflush(stream);
else if (stream->mode == _IOLBF && ch == '\n')
else if (stream->mode == _IONBF || (stream->mode == _IOLBF && ch == '\n'))
fflush(stream);
if (stream->eof)
return EOF;

View file

@ -61,7 +61,7 @@ int sscanf (const char* buf, const char* fmt, ...);
int fscanf(FILE*, const char* fmt, ...);
int setvbuf(FILE*, char* buf, int mode, size_t);
void setbuf(FILE*, char* buf);
void setlinebuf(FILE*, char* buf);
void setlinebuf(FILE*);
__END_DECLS

View file

@ -1,9 +1,10 @@
#include <stdlib.h>
#include <mman.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <alloca.h>
#include <assert.h>
#include <Kernel/Syscall.h>
#include <AK/Assertions.h>
@ -54,11 +55,12 @@ void* calloc(size_t nmemb, size_t)
return nullptr;
}
void* realloc(void *ptr, size_t)
void* realloc(void *ptr, size_t size)
{
(void) ptr;
ASSERT_NOT_REACHED();
return nullptr;
// FIXME: This is broken as shit.
auto* new_ptr = malloc(size);
memcpy(new_ptr, ptr, size);
return new_ptr;
}
void exit(int status)
@ -116,4 +118,13 @@ long atol(const char* str)
return atoi(str);
}
void __qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
{
(void) base;
(void) nmemb;
(void) size;
(void) compar;
assert(false);
}
}

View file

@ -12,7 +12,7 @@ void* realloc(void *ptr, size_t);
char* getenv(const char* name);
int atoi(const char*);
long atol(const char*);
void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
void exit(int status) __NORETURN;
void abort() __NORETURN;

View file

@ -2,6 +2,7 @@
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <assert.h>
extern "C" {
@ -97,6 +98,14 @@ void memcpy(void* dest, const void* src, size_t n)
*(bdest++) = *(bsrc++);
}
void memmove(void* dest, const void* src, size_t n)
{
if (dest < src)
return memcpy(dest, src, n);
// FIXME: Implement backwards copy.
assert(false);
}
char* strcpy(char* dest, const char *src)
{
char* originalDest = dest;

View file

@ -1,4 +1,9 @@
#include <termcap.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <AK/HashMap.h>
#include <AK/String.h>
extern "C" {
@ -6,5 +11,94 @@ char PC;
char* UP;
char* BC;
int tgetent(char* bp, const char* name)
{
fprintf(stderr, "tgetent: bp=%p, name='%s'\n", bp, name);
if (!strcmp(name, "ansi")) {
PC = '\0';
BC = const_cast<char*>("\033[D");
UP = const_cast<char*>("\033[A");
return 1;
}
assert(false);
}
static HashMap<String, String>* caps = nullptr;
void ensure_caps()
{
if (caps)
return;
caps = new HashMap<String, String>;
caps->set("DC", "\033[%p1%dP");
caps->set("IC", "\033[%p1%d@");
caps->set("ce", "\033[K");
caps->set("cl", "\033[H\033[J");
caps->set("cr", "\015");
caps->set("dc", "\033[P");
caps->set("ei", "");
caps->set("ic", "");
caps->set("im", "");
caps->set("kd", "\033[B");
caps->set("kl", "\033[D");
caps->set("kr", "\033[C");
caps->set("ku", "\033[A");
caps->set("ks", "");
caps->set("ke", "");
caps->set("le", "\033[D");
caps->set("mm", "");
caps->set("mo", "");
caps->set("pc", "");
caps->set("up", "\033[A");
caps->set("vb", "");
caps->set("am", "");
caps->set("co", "80");
caps->set("li", "25");
}
char* tgetstr(char* id, char** area)
{
ensure_caps();
fprintf(stderr, "tgetstr: id='%s', area=%p\n", id, area);
auto it = caps->find(id);
if (it != caps->end()) {
char* ret = *area;
strcpy(*area, (*it).value.characters());
*area += (*it).value.length() + 1;
return ret;
}
assert(false);
}
int tgetflag(char* id)
{
fprintf(stderr, "tgetflag: '%s'\n", id);
auto it = caps->find(id);
if (it != caps->end())
return 1;
return 0;
}
int tgetnum(char* id)
{
fprintf(stderr, "tgetnum: '%s'\n", id);
auto it = caps->find(id);
if (it != caps->end()) {
return atoi((*it).value.characters());
}
assert(false);
}
char* tgoto(const char* cap, int col, int row)
{
assert(false);
}
int tputs(const char* str, int affcnt, int (*putc)(int))
{
assert(false);
}
}

View file

@ -8,5 +8,12 @@ extern char PC;
extern char* UP;
extern char* BC;
int tgetent(char* bp, const char* name);
int tgetflag(char* id);
int tgetnum(char* id);
char* tgetstr(char* id, char** area);
char* tgoto(const char* cap, int col, int row);
int tputs(const char* str, int affcnt, int (*putc)(int));
__END_DECLS

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include <errno.h>
#include <termios.h>
#include <Kernel/Syscall.h>
@ -16,5 +17,12 @@ int tcsetattr(int fd, int optional_actions, const struct termios* t)
__RETURN_WITH_ERRNO(rc, rc, -1);
}
int tcflow(int fd, int action)
{
(void) fd;
(void) action;
assert(false);
}
}

View file

@ -20,6 +20,7 @@ struct termios {
int tcgetattr(int fd, struct termios*);
int tcsetattr(int fd, int optional_actions, const struct termios*);
int tcflow(int fd, int action);
/* c_cc characters */
#define VINTR 0

14
LibC/ulimit.cpp Normal file
View file

@ -0,0 +1,14 @@
#include <ulimit.h>
#include <assert.h>
extern "C" {
long ulimit(int cmd, long newlimit)
{
(void) cmd;
(void) newlimit;
assert(false);
}
}

10
LibC/ulimit.h Normal file
View file

@ -0,0 +1,10 @@
#pragma once
#include <sys/cdefs.h>
__BEGIN_DECLS
long ulimit(int cmd, long newlimit);
__END_DECLS

View file

@ -167,7 +167,8 @@ char* getcwd(char* buffer, size_t size)
char* getwd(char* buf)
{
return getcwd(buf, PATH_MAX);
auto* p = getcwd(buf, PATH_MAX);
return p;
}
int sleep(unsigned seconds)

View file

@ -253,13 +253,13 @@ static bool handle_builtin(int argc, const char** argv, int& retval)
static int try_exec(const char* path, const char** argv)
{
int ret = execve(path, argv, nullptr);
int ret = execve(path, argv, const_cast<const char**>(environ));
assert(ret < 0);
const char* search_path = "/bin";
char pathbuf[128];
sprintf(pathbuf, "%s/%s", search_path, argv[0]);
ret = execve(pathbuf, argv, nullptr);
ret = execve(pathbuf, argv, const_cast<const char**>(environ));
if (ret == -1)
return -1;
return ret;
@ -317,7 +317,8 @@ static int runcmd(char* cmd)
tcsetpgrp(0, getpid());
if (WIFEXITED(wstatus)) {
//printf("Exited normally with status %d\n", WEXITSTATUS(wstatus));
if (WEXITSTATUS(wstatus) != 0)
printf("Exited with status %d\n", WEXITSTATUS(wstatus));
} else {
if (WIFSIGNALED(wstatus)) {
switch (WTERMSIG(wstatus)) {

View file

@ -46,6 +46,12 @@ public:
#ifdef SERENITY
bool isBlocking() const { return m_isBlocking; }
void setBlocking(bool b) { m_isBlocking = b; }
dword file_flags() const { return m_file_flags; }
int set_file_flags(dword flags) { m_file_flags = flags; return 0; }
dword fd_flags() const { return m_fd_flags; }
int set_fd_flags(dword flags) { m_fd_flags = flags; return 0; }
#endif
ByteBuffer& generatorCache() { return m_generatorCache; }
@ -62,6 +68,8 @@ private:
#ifdef SERENITY
bool m_isBlocking { true };
dword m_fd_flags { 0 };
dword m_file_flags { 0 };
#endif
};

View file

@ -19,6 +19,188 @@ namespace Unix {
#define PROT_EXEC 0x4
#define PROT_NONE 0x0
#define F_DUPFD 0
#define F_GETFD 1
#define F_SETFD 2
#define F_GETFL 3
#define F_SETFL 4
/* c_cc characters */
#define VINTR 0
#define VQUIT 1
#define VERASE 2
#define VKILL 3
#define VEOF 4
#define VTIME 5
#define VMIN 6
#define VSWTC 7
#define VSTART 8
#define VSTOP 9
#define VSUSP 10
#define VEOL 11
#define VREPRINT 12
#define VDISCARD 13
#define VWERASE 14
#define VLNEXT 15
#define VEOL2 16
/* c_iflag bits */
#define IGNBRK 0000001
#define BRKINT 0000002
#define IGNPAR 0000004
#define PARMRK 0000010
#define INPCK 0000020
#define ISTRIP 0000040
#define INLCR 0000100
#define IGNCR 0000200
#define ICRNL 0000400
#define IUCLC 0001000
#define IXON 0002000
#define IXANY 0004000
#define IXOFF 0010000
#define IMAXBEL 0020000
#define IUTF8 0040000
/* c_oflag bits */
#define OPOST 0000001
#define OLCUC 0000002
#define ONLCR 0000004
#define OCRNL 0000010
#define ONOCR 0000020
#define ONLRET 0000040
#define OFILL 0000100
#define OFDEL 0000200
#if defined __USE_MISC || defined __USE_XOPEN
# define NLDLY 0000400
# define NL0 0000000
# define NL1 0000400
# define CRDLY 0003000
# define CR0 0000000
# define CR1 0001000
# define CR2 0002000
# define CR3 0003000
# define TABDLY 0014000
# define TAB0 0000000
# define TAB1 0004000
# define TAB2 0010000
# define TAB3 0014000
# define BSDLY 0020000
# define BS0 0000000
# define BS1 0020000
# define FFDLY 0100000
# define FF0 0000000
# define FF1 0100000
#endif
#define VTDLY 0040000
#define VT0 0000000
#define VT1 0040000
#ifdef __USE_MISC
# define XTABS 0014000
#endif
/* c_cflag bit meaning */
#ifdef __USE_MISC
# define CBAUD 0010017
#endif
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
#define B110 0000003
#define B134 0000004
#define B150 0000005
#define B200 0000006
#define B300 0000007
#define B600 0000010
#define B1200 0000011
#define B1800 0000012
#define B2400 0000013
#define B4800 0000014
#define B9600 0000015
#define B19200 0000016
#define B38400 0000017
#ifdef __USE_MISC
# define EXTA B19200
# define EXTB B38400
#endif
#define CSIZE 0000060
#define CS5 0000000
#define CS6 0000020
#define CS7 0000040
#define CS8 0000060
#define CSTOPB 0000100
#define CREAD 0000200
#define PARENB 0000400
#define PARODD 0001000
#define HUPCL 0002000
#define CLOCAL 0004000
#ifdef __USE_MISC
# define CBAUDEX 0010000
#endif
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define B460800 0010004
#define B500000 0010005
#define B576000 0010006
#define B921600 0010007
#define B1000000 0010010
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
#define __MAX_BAUD B4000000
#ifdef __USE_MISC
# define CIBAUD 002003600000 /* input baud rate (not used) */
# define CMSPAR 010000000000 /* mark or space (stick) parity */
# define CRTSCTS 020000000000 /* flow control */
#endif
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
#if defined __USE_MISC || (defined __USE_XOPEN && !defined __USE_XOPEN2K)
# define XCASE 0000004
#endif
#define ECHO 0000010
#define ECHOE 0000020
#define ECHOK 0000040
#define ECHONL 0000100
#define NOFLSH 0000200
#define TOSTOP 0000400
#ifdef __USE_MISC
# define ECHOCTL 0001000
# define ECHOPRT 0002000
# define ECHOKE 0004000
# define FLUSHO 0010000
# define PENDIN 0040000
#endif
#define IEXTEN 0100000
#ifdef __USE_MISC
# define EXTPROC 0200000
#endif
/* tcflow() and TCXONC use these */
#define TCOOFF 0
#define TCOON 1
#define TCIOFF 2
#define TCION 3
/* tcflush() and TCFLSH use these */
#define TCIFLUSH 0
#define TCOFLUSH 1
#define TCIOFLUSH 2
/* tcsetattr uses these */
#define TCSANOW 0
#define TCSADRAIN 1
#define TCSAFLUSH 2
typedef dword dev_t;
typedef dword ino_t;
typedef dword mode_t;