summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-18 03:03:28 +0200
committerMiguel <m.i@gmx.at>2018-09-18 03:03:28 +0200
commit2d91384197847a7e8fe2c3f548918a8277d3086d (patch)
tree7c93404e290a0ffbdaf9a8a94766d7bd0fd6e4f2
parent06e6e427c76bdb88a7f72dd04411d95a4bda3270 (diff)
sysfs, errno, improve foolshell, etc
-rw-r--r--README.md7
-rw-r--r--driver/keyboard.c24
-rw-r--r--fs/fd.c101
-rw-r--r--fs/fd.h8
-rw-r--r--fs/mount.c13
-rw-r--r--fs/mount.h3
-rw-r--r--fs/sysfs.c46
-rw-r--r--fs/sysfs.h1
-rw-r--r--kernel/fifo.c1
-rw-r--r--kernel/kernel.c4
-rw-r--r--kernel/kmalloc.c10
-rw-r--r--kernel/kmalloc.h4
-rw-r--r--kernel/mem.c8
-rw-r--r--kernel/mem.h3
-rw-r--r--kernel/scheduler.c2
-rw-r--r--kernel/syscalls.c60
-rw-r--r--userspace/Makefile7
-rw-r--r--userspace/foolshell.c279
-rw-r--r--userspace/init.c2
19 files changed, 358 insertions, 225 deletions
diff --git a/README.md b/README.md
index b78b139..8b39ab2 100644
--- a/README.md
+++ b/README.md
@@ -86,10 +86,11 @@ FoolOS is tested/developed on the following emulators/machines
Todos
-----
+
* Newlib errno / return value / argv / env
-* pipe\_syscall
+* pipe\_syscall / execve: support hashbangs
* DMA where possible!
-* Mouse & KB processing in seperate task.
+* optimized Mouse & KB processing in seperate task. (Kb all chars and different layouts)
* Kernel Stuff Reentrancy?
* Cleanup syscalls
* Writing to ext2 RAM-image
@@ -105,6 +106,8 @@ Todos
* GUI / Window Manager (update\_rect, etc..)
* Porting (ncurses, gcc, binutils, vim, apache...)
+* Crazy & Funny terminal effects while typing (idea)
+
Disclaimer
----------
diff --git a/driver/keyboard.c b/driver/keyboard.c
index d276f51..61b8e5f 100644
--- a/driver/keyboard.c
+++ b/driver/keyboard.c
@@ -11,10 +11,10 @@ static bool shift_r=false;
static bool capslock=false;
static uint32_t kb_stream;
+static char num_syms[]={')','!','@','#','$','%','^','&','*','('};
static void put(uint8_t c)
{
- klog("%c",c);
syscall_write(kb_stream,(char *)&c,1);
}
@@ -25,6 +25,7 @@ void keyboard_init(uint32_t s)
void keyboard_handle(uint8_t in)
{
+ // klog("kb_in 0x%x",in);
uint8_t make_alpha[]={
0x1e, // A
0x30, // B
@@ -143,6 +144,7 @@ void keyboard_handle(uint8_t in)
if(break_slash==in)
{
ascii='/';
+ if(shift_l||shift_r||capslock) ascii='?';
match=true;
}
else if(break_key_space==in)
@@ -153,31 +155,43 @@ void keyboard_handle(uint8_t in)
else if(in==0xB4)
{
ascii='.';
+ if(shift_l||shift_r||capslock) ascii='<';
match=true;
}
else if(in==0xB3)
{
ascii=',';
+ if(shift_l||shift_r||capslock) ascii='>';
match=true;
}
else if(in==0x8D)
{
- ascii='+';
+ ascii='=';
+ if(shift_l||shift_r||capslock) ascii='+';
match=true;
}
else if(in==0x8C)
{
ascii='-';
+ if(shift_l||shift_r||capslock) ascii='_';
match=true;
}
else if(in==0x9A)
{
ascii='[';
+ if(shift_l||shift_r||capslock) ascii='{';
match=true;
}
else if(in==0x9B)
{
ascii=']';
+ if(shift_l||shift_r||capslock) ascii='}';
+ match=true;
+ }
+ else if(in==0xab)
+ {
+ ascii='\\';
+ if(shift_l||shift_r||capslock) ascii='|';
match=true;
}
else if(break_key_backspace==in)
@@ -198,7 +212,7 @@ void keyboard_handle(uint8_t in)
}
else if(break_key_tab==in)
{
- ascii=0x09;
+ ascii='\t';
match=true;
}
@@ -223,6 +237,10 @@ void keyboard_handle(uint8_t in)
if(break_num[i]==in)
{
ascii=('0'+i);
+ if(shift_l||shift_r||capslock) // capslock makes trouble :(
+ {
+ ascii=num_syms[i];
+ }
match=true;
break;
}
diff --git a/fs/fd.c b/fs/fd.c
index ed8a3b1..43ffb0d 100644
--- a/fs/fd.c
+++ b/fs/fd.c
@@ -4,6 +4,9 @@
#include "kmalloc.h"
#include "ext2.h"
#include "log.h"
+#include "lib/string/string.h"
+#include "lib/printf/printf.h"
+#include "ringbuffer.h"
bool fd_write(fd* f,uint8_t c)
{
@@ -20,21 +23,14 @@ bool fd_has(fd* f)
return f->has(f->data);
}
-bool fd_close(fd* f)
+bool fd_eof(fd* f)
{
- return f->close(f->data);
+ return f->eof(f->data);
}
-fd fd_from_fifo(fifo* fif)
+bool fd_close(fd* f)
{
- fd f;
- f.type=FD_TYPE_FIFO_BUFFERED;
- f.data=fif;
- f.read=fifo_get;
- f.write=fifo_put;
-// f.close=fd_close;
- f.has=fifo_has;
- return f;
+ return f->close(f->data);
}
//----
@@ -62,17 +58,75 @@ uint8_t ext2_read(uint32_t* data)
bool ext2_has(uint32_t* data)
{
+ return 1;
+}
+
+bool ext2_eof(uint32_t* data)
+{
uint32_t save=data[1];
uint32_t c=ext2_read_inode(VMEM_EXT2_RAMIMAGE,data[0],&c,&data[1],1);
data[1]=save;
- return (c>0);
-
+ return (c==0);
}
+
void ext2_close(void* x)
{
kbfree(x);
}
+uint8_t sysfs_get(uint32_t *data)
+{
+ return ringbuffer_get(data);
+}
+
+bool sysfs_has(uint32_t *data)
+{
+ return true;
+}
+
+bool sysfs_eof(uint32_t *data)
+{
+ return !ringbuffer_has(data);
+}
+
+void sysfs_close(uint32_t *data)
+{
+ ringbuffer *r=data;
+ ringbuffer_free(data); // free ringbuffer buffer
+ kbfree(data); // free memory holding ringbuffer information
+}
+
+void get_sysfs_data(ringbuffer *r,char *format_string, ...)
+{
+ char buf[256];
+ va_list va;
+ va_start(va,format_string);
+ tfp_vsprintf(buf,format_string,va);
+ va_end(va);
+
+ for(int i=0;i<strlen(buf);i++)
+ ringbuffer_put(r,buf[i]);
+
+ ringbuffer_put(r,'\n');
+}
+
+bool fifo_eof(uint32_t* data)
+{
+ return false;
+}
+fd fd_from_fifo(fifo* fif)
+{
+ fd f;
+ f.type=FD_TYPE_FIFO_BUFFERED;
+ f.data=fif;
+ f.read=fifo_get;
+ f.write=fifo_put;
+ f.eof=fifo_eof;
+// f.close=fd_close; //TODO.. etc also otehr and cleanups
+ f.has=fifo_has;
+ return f;
+}
+
fd fd_from_path(char* path)
{
fd f;
@@ -81,6 +135,27 @@ fd fd_from_path(char* path)
f.read=ext2_read;
f.write=ext2_write;
f.close=ext2_close;
+ f.eof=ext2_eof;
f.has=ext2_has;
return f;
}
+
+fd fd_from_sysfs(void(*g)(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...)))
+{
+ fd f;
+ f.type=FD_TYPE_SYSFS;
+ f.data=kballoc(1);
+ ringbuffer r=ringbuffer_init(1);
+
+ g(&r,get_sysfs_data);
+ memcpy(f.data,&r,sizeof(ringbuffer));
+
+ f.read=sysfs_get;
+ f.write=0;
+ f.close=sysfs_close;
+ f.has=sysfs_has;
+ f.eof=sysfs_eof;
+
+ return f;
+}
+
diff --git a/fs/fd.h b/fs/fd.h
index a51a0f3..35e28d9 100644
--- a/fs/fd.h
+++ b/fs/fd.h
@@ -7,6 +7,7 @@
#include <stdbool.h>
#include "fifo.h"
+#include "ringbuffer.h"
/*
typedef struct
@@ -27,7 +28,8 @@ typedef struct
enum FD_TYPE{
FD_TYPE_FIFO_BUFFERED=1,
FD_TYPE_EXT2_FILE=2,
- FD_TYPE_EXT2_DIR=3
+ FD_TYPE_EXT2_DIR=3,
+ FD_TYPE_SYSFS=4
};
typedef struct fd_struct
@@ -35,6 +37,7 @@ typedef struct fd_struct
bool (*write)(struct fd_struct*,uint8_t);
uint8_t (*read)(struct fd_struct*);
bool (*has)(struct fd_struct*);
+ bool (*eof)(struct fd_struct*);
bool (*close)(struct fd_struct*);
uint8_t type;
@@ -43,10 +46,11 @@ typedef struct fd_struct
uint8_t fd_read(fd*);
bool fd_has(fd*);
+bool fd_eof(fd*);
bool fd_write(fd*,uint8_t);
bool fd_close(fd*);
fd fd_from_fifo(fifo* f);
fd fd_from_path(char *path);
-//fd fd_from_sysfs(void(*g)(void (*f)(char *fmt, ...)));
+fd fd_from_sysfs(void(*g)(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...)));
#endif
diff --git a/fs/mount.c b/fs/mount.c
index a7cd949..009647a 100644
--- a/fs/mount.c
+++ b/fs/mount.c
@@ -18,7 +18,7 @@ char *mount_type_to_str(uint32_t t)
{
case MOUNT_TYPE_EXT2: return "EXT2";
case MOUNT_TYPE_PIPES: return "PIPES";
- case MOUNT_TYPE_SYS: return "SYS";
+ case MOUNT_TYPE_SYS: return "SYSFS";
}
return "UNKNOWN";
}
@@ -39,6 +39,16 @@ void mount_dump()
}
}
+void mount_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...))
+{
+ f(r,"mounts:");
+ for(int i=0;i<mounts_count;i++)
+ {
+ mount *m=&mounts[i];
+ f(r,"%s mounted at: %s ",mount_type_to_str(m->type),m->path);
+ }
+}
+
static uint32_t check_match(char *p1, char *p2)
{
uint32_t c=0;
@@ -84,7 +94,6 @@ fd mount_file_open(char *path)
{
mount m;
char *p=get_mount_for_path(path,&m);
- klog("%s in %s",p,m.path);
return m.mount_file_open(&m,p);
}
diff --git a/fs/mount.h b/fs/mount.h
index 4e61c28..8a61f2b 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -50,4 +50,7 @@ fd mount_file_open(char *path);
/** TODO: should use fd number instead of PATH on each call*/
int mount_read_dir (char *path, fs_dirent *dirs, uint32_t *pos);
+/** sysfs interface */
+void mount_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...));
+
#endif
diff --git a/fs/sysfs.c b/fs/sysfs.c
new file mode 100644
index 0000000..57a56c8
--- /dev/null
+++ b/fs/sysfs.c
@@ -0,0 +1,46 @@
+#include "mount.h"
+#include "sysfs.h"
+
+#include "mem.h"
+#include "kmalloc.h"
+#include "mount.h"
+
+#include "log.h"
+
+#include "lib/string/string.h"
+
+static const char* names[] = {"/mem","/kmalloc","/mount"};
+static uint32_t map[]={mem_sysfs,kmalloc_sysfs,mount_sysfs};
+static uint32_t count=3;
+
+
+/* mount interface */
+
+fd sysfs_file_open(mount *m,char *path)
+{
+ klog("sysfs file open: %s",path);
+ for (int i=0;i<count;i++)
+ {
+ if(!strcmp(path,names[i]))
+ return fd_from_sysfs(map[i]);
+ }
+ return fd_from_sysfs(map[0]);
+}
+
+int sysfs_read_dir(mount *m,char *path, fs_dirent *dirs, uint32_t *pos)
+{
+ if(*pos>=count)return 0;
+ memcpy(dirs->name,names[*pos],strlen(names[*pos])+1);
+ *pos+=1;
+ return 1;
+}
+
+void sysfs_mount(char* path)
+{
+ mount m;
+ m.type=MOUNT_TYPE_SYS;
+ memcpy(m.path,path,strlen(path)+1);
+ m.mount_file_open=sysfs_file_open;
+ m.mount_read_dir=sysfs_read_dir;
+ mount_add(m);
+}
diff --git a/fs/sysfs.h b/fs/sysfs.h
new file mode 100644
index 0000000..7d09395
--- /dev/null
+++ b/fs/sysfs.h
@@ -0,0 +1 @@
+void sysfs_mount(char* path);
diff --git a/kernel/fifo.c b/kernel/fifo.c
index fadd248..10bc8ff 100644
--- a/kernel/fifo.c
+++ b/kernel/fifo.c
@@ -27,7 +27,6 @@ bool fifo_has(fifo* f)
fifo fifo_create_buffered(uint8_t size)
{
if (ringbuffer_c>=FIFO_MAX_RINGBUFFERS) kpanic("ran out of ringbuffers for fifos");
-
fifo f;
fifo_ringbuffers[ringbuffer_c]=ringbuffer_init(size);
f.data=&fifo_ringbuffers[ringbuffer_c];
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 0239489..072cebb 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -12,6 +12,7 @@
#include "vmem.h"
//-- clean below headers --//
+#include "sysfs.h"
#include "testing/testing.h"
#include "ext2.h"
#include "apic.h"
@@ -100,6 +101,9 @@ void kernel_main(uint32_t eax,uint32_t ebx)
ext2_dump_info(VMEM_EXT2_RAMIMAGE);
ext2_mount("/");
+ // -- MOUNT SYSFS --//
+ sysfs_mount("/sys/");
+
// -- APIC -- //
klog("Advanced Programmable Interrupt Controller (APIC) config ...");
apic_init(&cfg_acpi);
diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c
index 6a7520a..061d68e 100644
--- a/kernel/kmalloc.c
+++ b/kernel/kmalloc.c
@@ -117,7 +117,7 @@ void kbfree(uint32_t pos)
spinlock_release(SPINLOCK_ALLOC);
}
-void kmalloc_sysfs(void (*f)(char *fmt, ...))
+void kmalloc_sysfs(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...))
{
uint32_t free=0;
uint32_t used=0;
@@ -127,8 +127,8 @@ void kmalloc_sysfs(void (*f)(char *fmt, ...))
else free++;
}
- f("kernel blocks allocation/deallocation");
- f("total 4096kb blocks: %d (%d bytes)",BLOCKS,BLOCKS*4096);
- f("used 4096kb blocks: %d (%d bytes)",used,used*4096);
- f("free 4096kb blocks: %d (%d bytes)",free,free*4096);
+ f(r,"kernel blocks allocation/deallocation");
+ f(r,"total 4096kb blocks: %d (%d bytes)",BLOCKS,BLOCKS*4096);
+ f(r,"used 4096kb blocks: %d (%d bytes)",used,used*4096);
+ f(r,"free 4096kb blocks: %d (%d bytes)",free,free*4096);
}
diff --git a/kernel/kmalloc.h b/kernel/kmalloc.h
index 5ca4c8c..617872b 100644
--- a/kernel/kmalloc.h
+++ b/kernel/kmalloc.h
@@ -20,6 +20,8 @@
#include <stdint.h>
+#include "ringbuffer.h"
+
/** Allocate size*4096 bytes and returns a 32-bit address
* and 0 if fails.
* */
@@ -29,4 +31,4 @@ uint32_t kballoc (uint32_t size);
void kbfree (uint32_t addr);
/** Get current status for sysfs */
-void kmalloc_sysfs(void (*f)(char *fmt, ...));
+void kmalloc_sysfs(ringbuffer *r, void (*f)(ringbuffer *r, char *fmt, ...));
diff --git a/kernel/mem.c b/kernel/mem.c
index 52e08b6..97450d4 100644
--- a/kernel/mem.c
+++ b/kernel/mem.c
@@ -228,9 +228,9 @@ uint32_t mem_init(multiboot_information *info)
return 0;
}
-void mem_sysfs(void (*f)(char *fmt, ...))
+void mem_sysfs(ringbuffer *r, void (*f)(ringbuffer *r,char *fmt, ...))
{
- f("physical memory manager");
- f("free 4096kb blocks : %d",mem_free_blocks);
- f("free bytes : %d",mem_free_blocks*4096);
+ f(r,"physical memory manager");
+ f(r,"free 4096kb blocks : %d",mem_free_blocks);
+ f(r,"free bytes : %d",mem_free_blocks*4096);
}
diff --git a/kernel/mem.h b/kernel/mem.h
index 85fc688..5de95a9 100644
--- a/kernel/mem.h
+++ b/kernel/mem.h
@@ -19,6 +19,7 @@
*/
#include "multiboot.h"
+#include "ringbuffer.h"
/**
* Init the physical memory manager. Please provide the multiboot_information
@@ -29,4 +30,4 @@ uint32_t mem_init(multiboot_information *info);
void* mem_alloc_block ();
void mem_free_block(void* p);
uint32_t mem_get_free_blocks_count();
-void mem_sysfs(void (*f)(char *fmt, ...));
+void mem_sysfs(ringbuffer *r, void (*f)(ringbuffer *r, char *fmt, ...));
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 798d119..8f7f6d6 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -291,7 +291,7 @@ void task_syscall_worker()
{
uint32_t syscall=task_list[cpu][i].eax;
- klog("task pid=%d waiting on syscall %d/%s on cpu %d slot %d.",task_list[cpu][i].pid,syscall,syscall_get_name(syscall),cpu,i);
+// klog("task pid=%d waiting on syscall %d/%s on cpu %d slot %d.",task_list[cpu][i].pid,syscall,syscall_get_name(syscall),cpu,i);
task_list[cpu][0].vmem=task_list[cpu][i].vmem; // switch syscall worker to pagedir of calling userprog
x86_set_page_directory(task_list[cpu][0].vmem);
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index 8b5040a..aa20616 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -17,6 +17,15 @@
#include "log.h"
#include "timer.h"
#include "mount.h"
+#include "mem.h"
+#include "reent.h"
+#include "errno.h"
+
+void set_errno(int no)
+{
+ struct _reent *impure_ptr=VMEM_USER_NEWLIB;
+ impure_ptr->_errno=no;
+}
static fd fds[MAX_FD];
static uint32_t next_fd=0;
@@ -148,7 +157,7 @@ int syscall_write(int file, char *buf, int len)
*/
int syscall_read(int file, char *buf, int len)
{
- if(fds[file].type==FD_TYPE_EXT2_FILE && !fd_has(&fds[file]))return 0;
+ if(fd_eof(&fds[file]))return 0;
*buf=fd_read(&fds[file]);
return 1;
}
@@ -217,36 +226,28 @@ int copy_args(char **in, char **out)
return count;
}
-int syscall_execve(char *name, char **argv, char **env,int pid)
+/** does not return on success otherwise -1 and errrno set */
+int syscall_execve(const char *name, char *const argv[], char *const env[], int pid)
{
+
fixme("not overwrite yourself?");
int arg_count=0;
while(argv[arg_count]!=NULL)arg_count++;
char **argv1=VMEM_USER_ENV;
- if(argv!=NULL)
- {
- copy_args(argv,argv1);
- }
- else{
- argv1=NULL;
- }
+ if(argv!=NULL)copy_args(argv,argv1);
+ else argv1=NULL;
char **env1=VMEM_USER_ENV+1024*2;
- if(env!=NULL)
- {
- copy_args(env,env1);
- }
- else{
- env1=NULL;
- }
+ if(env!=NULL)copy_args(env,env1);
+ else env1=NULL;
uint32_t alloc;
uint32_t entry_global=load_elf(name,&alloc);
- if(!entry_global)
- {
- return -1; // errror loading
+ if(!entry_global){
+ set_errno(ENOENT);
+ return -1;
}
uint32_t *stack=VMEM_USER_STACK_TOP-4*32;
@@ -255,26 +256,6 @@ int syscall_execve(char *name, char **argv, char **env,int pid)
*--stack=env1;
task_reset(pid,entry_global,stack,alloc);
return 0;
-
- /* try to move this to asm */
- // asm volatile("jmp ."); // loop forever
- //klog("returning to jump addy (0x%08X)", entry_global);
- /*
- asm volatile("mov $0x08fff000,%esp"); // set stack at high end of process image
-
- asm volatile ("push %0" :: "r" (argv1));
- asm volatile ("push %0" :: "r" (arg_count));
- //asm volatile ("push %0" :: "r" (kballoc(1)));
- asm volatile ("push %0" :: "r" (env1));
-
- // push addr and return to it
- asm volatile ("pushl %0"::"r"(entry_global));
-
- asm volatile ("sti");
- asm volatile ("ret");
- */
-
- // this is never reached!
}
// minihack
@@ -402,7 +383,6 @@ uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3,
case SYSCALL_WAIT :
return !task_runs(p1);
case SYSCALL_READ :
- if(fds[p1].type==FD_TYPE_EXT2_FILE)return 1;
return fd_has(&fds[p1]);
case SYSCALL_EXIT :
return 1;
diff --git a/userspace/Makefile b/userspace/Makefile
index dbc2d0f..d39f15f 100644
--- a/userspace/Makefile
+++ b/userspace/Makefile
@@ -2,6 +2,8 @@ IMAGESIZE=10000 #ext2.img size in Kb
#######################
+GIT_REVISION=$(shell git rev-parse HEAD)
+
CC=i686-foolos-gcc
CC=i686-elf-gcc
AS=i686-elf-as
@@ -9,11 +11,13 @@ CC = @echo "Compiling (i686-elf-gcc) $<..."; i686-elf-gcc
AS = @echo "Assembling (i686-elf-as) $<..."; i686-elf-as
CFLAGS=
-CFLAGS=-w
+CFLAGS+=-DGIT_REVISION=\"$(GIT_REVISION)\"
+CFLAGS+=-w
CFLAGS+=-I..
CFLAGS+=-I/home/miguel/temp/foolos/usr/i686-foolos/include
CFLAGS+=-O0
CFLAGS+=-g
+CFLAGS+= -Werror=implicit-function-declaration
LDFLAGS=-L/home/miguel/temp/foolos/usr/i686-foolos/lib/
LDLIBS=-lc -lm -lg -lnosys
@@ -40,6 +44,7 @@ ext2.img: $(PROGS)
@echo "Welcome to FoolOs\nWe hope you will enjoy your stay." > mnt/home/miguel/hello.txt
@mkdir -p mnt/bin
@mkdir -p mnt/doc/test
+ @mkdir -p mnt/sys # mountpoint for sysfs
@cp test.txt mnt/doc/test/
@cp $(PROGS) mnt/bin
@cp fonts/binfont.bin mnt/
diff --git a/userspace/foolshell.c b/userspace/foolshell.c
index 0012592..e8b384e 100644
--- a/userspace/foolshell.c
+++ b/userspace/foolshell.c
@@ -1,47 +1,45 @@
+/**
+ * @file
+ *
+ * Fool's Shell
+ * =========
+ *
+ * A minimalsitic and naive shell developed along the Fool OS kernel.
+ * TODO: Free tokenizer / dynamic size!
+ */
+
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
-
-#include <reent.h>
+#include <errno.h>
+#include <string.h>
extern char **environ;
-extern struct _reent *_impure_ptr;
-uint8_t buf_test[1024*300];
+bool process(char *buf);
+bool cd(char *path);
-//
-void hello()
+void version()
+{
+ puts("Fool's Shell version git-commit:" GIT_REVISION "\ncompiled on " __DATE__ " at " __TIME__);
+}
+void help()
{
- // ascci art: http://patorjk.com/software/taag/#p=testall&f=Cards&t=Fool%20OS
- puts(
-
- "\033c"
-// "\033[36m"
-
-// " ______ __ ____ _____ \n"
-// " / ____/___ ____ / / / __ \\/ ___/ \n"
-// " / /_ / __ \\/ __ \\/ / / / / /\\__ \\ \n"
-// " / __/ / /_/ / /_/ / / / /_/ /___/ / \n"
-// " /_/ \\____/\\____/_/ \\____//____/ \n"
-// " \n"
-
-// "\033[37;44m"
-// " \n"
-
- " Welcome to FoolShell v0.12 (Compiled on " __DATE__ " at " __TIME__")\n"
- " ------------------------------------------------------------------\n\n"
- " Please type 'help' anytime, to show shell \"built-ins\". You can execute \n"
- " user programms that are in your $PATH directory by simply typing \n"
- " their filenames. Get additional information for many, of the available\n"
- " commands by invoking them with --help or -h. (e.g. ls --help) \n"
- " \n"
-
- "\033[37;40m"
- );
-
- printf(" Your $PATH is currently set to: %s\n",getenv("PATH"));
- printf(" Type 'ls %s' to list programms on your $PATH.\n\n",getenv("PATH"));
+ puts( "\nfoolshell: supported built-in commands/functions:\n\n"
+
+ "'env' - show all environment variables\n"
+ "'getenv [var]' - show environment variable\n"
+ "'setenv [var] [val]' - set environemnet variable\n"
+
+ "'cd [dir]' - change directory (set $PWD)\n"
+ "'[binary] [params...]' - run a binary\n"
+ "'[binary] [params...] &' - run a binary in background\n"
+ " TODO - pipes\n"
+
+ "'help' - show this message\n"
+ "'exit' - exit running foolshell\n\n");
+
}
void prompt()
@@ -49,23 +47,32 @@ void prompt()
printf("\033[36mfool\033[37m@\033[32mhill\033[33m:%s%s\033[37m",getenv("PWD"),getenv("PS1"));
}
-
int main(int argc, char **argv)
{
- bool silent=false;
for(int i=0;i<argc;i++)
{
- if(!strcmp(argv[i],"--silent"))silent=true;
+ if(!strcmp(argv[i],"--version"))
+ {
+ version();
+ return 0;
+ }
+
+ if(!strcmp(argv[i],"--help"))
+ {
+ help();
+ return 0;
+ }
}
-
- if(!silent)hello();
char *buf=calloc(sizeof(char),256);
+ // input and output without buffering
setvbuf(stdin,NULL,_IONBF,0);
setvbuf(stdout,NULL,_IONBF,0);
- while(1)
+ printf("\033c"); // clear screen
+
+ while(1) // process commands until exit
{
prompt();
int bl=0;
@@ -89,19 +96,18 @@ int main(int argc, char **argv)
}
}
- //fgets(buf,255,stdin);
- //buf[strlen(buf)-1]=0; // remove \n
- //printf("[%s]",buf);
- process(buf);
+ if(!process(buf))break; // process input and return if exit
}
return 0;
}
-char **tokenize(char *buf)
+// break the input in tokens on spaces
+char **tokenize(char *buf,char chr)
{
char **token;
token=malloc(10*sizeof(char*));
+ token=realloc(token,20*sizeof(char*));
int l=strlen(buf);
@@ -114,13 +120,13 @@ char **tokenize(char *buf)
token[c]=malloc(256);
//skip all the whitespace
- while(buf[i]==' '&&i<l)i++;
+ while(buf[i]==chr&&i<l)i++;
if(i==l)break;
//get token
int t=0;
- while(buf[i]!=' '&&i<l)
+ while(buf[i]!=chr&&i<l)
{
token[c][t]=buf[i];
t++;
@@ -136,129 +142,106 @@ char **tokenize(char *buf)
return token;
}
-int process(char *buf)
+bool process(char *buf)
{
- char **token=tokenize(buf);
+ char **token=tokenize(buf,' ');
char *command=token[0];
- // puts(command);
- // copied from trottelshell
-
- if(!strcmp(command,"help"))
- {
- puts( "\nfoolshell: supported built-in commands:\n\n"
- "'help' - show this message\n"
- "'echo [string]' - print given string to stdout\n"
- "'getenv [var]' - show environment variable\n"
- "'putenv/setenv [var] [val]' - set environemnet variable\n"
- "'env' - show all environment variables\n"
- "'cd [dir]' - change directory (set $PWD)\n"
- "'exit' - exit running foolshell\n\n");
- }
- else if(!strcmp(command,"cd"))
+ if(!strcmp(command,"help"))help();
+ else if(!strcmp(command,"cd"))cd(token[1]);
+ else if(!strcmp(command,"exit")) return false;
+ //else if(!strcmp(command,"getenv"))printf("(0x%08X) get: '%s' = '%s'(0x%08X) \n",environ,token[1],getenv(token[1]),getenv(token[1]));
+ else if(!strcmp(command,"getenv"))printf("%s\n",getenv(token[1]));
+ else if(!strcmp(command,"setenv"))
{
- char *dir=getenv("PWD");
-
- char buf[256];
-
- if(token[1][0]!='/')
- {
- sprintf(buf,"%s%s%s",dir,dir[0]=='/'&&dir[1]==0?"":"/",token[1]);
- }
- else
- {
- sprintf(buf,"%s",token[1]);
- }
-
- char token[10];
-
- //adjust pwd (resolve '..' and '.')
-//// printf("adjusting pwd: '%s'\n",buf);
- int left=1;
- int right=0;
-
- do{
-
- int t=0;
- do
- {
- right++;
- token[t]=buf[right];
-
- t++;
- }
- while(buf[right]!=0&&buf[right]!='/');
- token[t-1]=0;
-
-// printf("path token: '%s'\n",token);
-
- if(!strcmp(token,".."))
- {
- left--;
- while(buf[left]!='/')left--;
- }
- else if(!strcmp(token,"."))
- {
- }
- else
- {
- int i=0;
- if(left!=1)buf[left++]='/';
- do{buf[left++]=token[i++];}while(token[i]!=0);
- }
-
- }while(buf[right]!=0);
- buf[left]=0;
-// printf("adjusted: '%s'\n",buf);
- if(buf[0]==0)setenv("PWD","/",1);
- else setenv("PWD",buf,1);
- }
- else if(!strcmp(command,"exit"))
- {
- _exit(1);
- }
- else if(!strcmp(command,"echo"))
- {
- printf("\"%s\"\n",token[1]);
-
- }
- else if(!strcmp(command,"getenv"))
- {
- printf("(0x%08X) get: '%s' = '%s'(0x%08X) \n",environ,token[1],getenv(token[1]),getenv(token[1]));
- }
- else if(!strcmp(command,"putenv")||!strcmp(command,"setenv"))
- {
- char buf[256];
sprintf(buf,"%s=%s",token[1],token[2]);
putenv(buf);
- printf("(0x%08X) set: '%s' = '%s' \n",environ,token[1],getenv(token[1]));
+ //printf("(0x%08X) set: '%s' = '%s' \n",environ,token[1],getenv(token[1]));
}
else if(!strcmp(command,"env"))
{
int i=0;
- printf("env: 0x%08X\n",environ);
+// printf("env: 0x%08X\n",environ);
while(environ[i]!=NULL)
{
- printf("envvar %s (0x%08X)\n" ,environ[i],environ[i]);
+// printf("envvar %s (0x%08X)\n" ,environ[i],environ[i]);
+ printf("%s\n" ,environ[i]);
i++;
}
}
- else
+ else // otherwise treat command as exectutable and send to execve
{
int pid=_fork();
if(pid==0)
{
- sprintf(buf,"%s",token[0]);
- _execve(buf,token,environ);
- sprintf(buf,"%s/%s",getenv("PATH"),token[0]);
+ if(token[0][0]=='/')sprintf(buf,"%s",token[0]);
+ else sprintf(buf,"%s/%s",getenv("PATH"),token[0]);
_execve(buf,token,environ);
- puts("foolshell: command not found");
- exit(0);
+ printf("foolshell: %s (errno: %d)\n",strerror(errno),errno);
+ return false;
}
- if(token[1]==NULL||strcmp(token[1],"branch"))_wait(pid);
+ if(token[1]==NULL||strcmp(token[1],"&"))_wait(pid);
}
- return 0;
+ return true;
+}
+
+bool setpwd(char *path)
+{
+ if(!strcmp(path,"/"))
+ {
+ putenv("PWD=/");
+ return true;
+ }
+ char buf[255];
+ buf[0]=0;
+ strcat(buf,"PWD=");
+
+ char **t=tokenize(path,'/');
+
+ char *p[100];
+ int pp=0;
+
+ while(*t!=NULL)
+ {
+ if(!strcmp(*t,"..")){
+ pp--;
+ t++;
+ if(pp<0)pp=0;
+ continue;
+ }
+ if(!strcmp(*t,".")){t++; continue;}
+ if(**t!=0)
+ {
+ p[pp]=*t;
+ //printf("> %s\n",p[pp]);
+ pp++;
+ }
+ t++;
+ }
+
+ if(pp==0)
+ {
+ strcat(buf,"/");
+ }
+
+ for(int i=0;i<pp;i++)
+ {
+ strcat(buf,"/");
+ strcat(buf,p[i]);
+ }
+
+ putenv(buf);
+ return true; // TODO check if dir exists at all.
+}
+
+bool cd(char *path)
+{
+ char buf[256];
+ if(path==NULL)return setpwd(getenv("HOME"));
+ if(path[0]=='/')return setpwd(path);
+ sprintf(buf,"%s/%s",getenv("PWD"),path);
+ return setpwd(buf);
}
diff --git a/userspace/init.c b/userspace/init.c
index 3384edb..8530368 100644
--- a/userspace/init.c
+++ b/userspace/init.c
@@ -4,7 +4,7 @@
int main(int argc, char **argv)
{
char *argv1[]={"/bin/foolshell",0};
- char *env1[]={"PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0};
+ char *env1[]={"HOME=/home/miguel","PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0};
time_t ltime;
time(&ltime);