aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/core/thread.c2
-rw-r--r--src/kernel/include/ipc.h2
-rw-r--r--src/kernel/user/ipc.c55
-rw-r--r--src/lib/libkogata/stdio.c9
-rw-r--r--src/sysbin/shell/main.c32
5 files changed, 75 insertions, 25 deletions
diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c
index 4a3722d..fab4eef 100644
--- a/src/kernel/core/thread.c
+++ b/src/kernel/core/thread.c
@@ -421,7 +421,7 @@ void kill_thread(thread_t *thread) {
enqueue_thread(thread, false);
}
yield();
- if (i++ > 100) dbg_printf("Thread 0x%p must be killed but will not exit.\n", thread);
+ if (i++ == 100) dbg_printf("Thread 0x%p must be killed but will not exit.\n", thread);
}
exit_critical(st);
diff --git a/src/kernel/include/ipc.h b/src/kernel/include/ipc.h
index 4f8573c..5be6d48 100644
--- a/src/kernel/include/ipc.h
+++ b/src/kernel/include/ipc.h
@@ -6,7 +6,7 @@
// ---- Communication channels
-#define CHANNEL_BUFFER_SIZE 1000 // 1000 + other channel_t fields = 1024 - epsilon
+#define CHANNEL_BUFFER_SIZE 200 // 1000 + other channel_t fields = 1024 - epsilon
typedef struct {
fs_handle_t *a, *b;
diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c
index 0287793..3643eb2 100644
--- a/src/kernel/user/ipc.c
+++ b/src/kernel/user/ipc.c
@@ -128,11 +128,23 @@ size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_bu
c->buf_used -= len;
if (c->buf_used == 0) c->buf_use_begin = 0;
- }
- ret += len;
+ resume_on(c);
+
+ mutex_unlock(&c->lock);
+
+ ret += len;
+ } else if (h->mode & FM_BLOCKING) {
+ int st = enter_critical(CL_NOINT);
+
+ mutex_unlock(&c->lock);
- mutex_unlock(&c->lock);
+ wait_on(c);
+
+ exit_critical(st);
+ } else {
+ mutex_unlock(&c->lock);
+ }
} while ((h->mode & FM_BLOCKING) && ret < req_len);
return ret;
@@ -158,22 +170,37 @@ size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char*
if (c->buf_used + len > CHANNEL_BUFFER_SIZE) len = CHANNEL_BUFFER_SIZE - c->buf_used;
if (len) {
- size_t len0 = len, len1 = 0;
-
- if (c->buf_use_begin + c->buf_used + len > CHANNEL_BUFFER_SIZE) {
- len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin - c->buf_used;
- len1 = len - len0;
+ if (c->buf_use_begin + c->buf_used >= CHANNEL_BUFFER_SIZE) {
+ memcpy(c->buf + c->buf_use_begin + c->buf_used - CHANNEL_BUFFER_SIZE, buf, len);
+ } else {
+ size_t len0 = len, len1 = 0;
+
+ if (c->buf_use_begin + c->buf_used + len > CHANNEL_BUFFER_SIZE) {
+ len0 = CHANNEL_BUFFER_SIZE - c->buf_use_begin - c->buf_used;
+ len1 = len - len0;
+ }
+ memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0);
+ if (len1) memcpy(c->buf, buf + len0, len1);
}
- memcpy(c->buf + c->buf_use_begin + c->buf_used, buf, len0);
- if (len1) memcpy(c->buf, buf + len0, len1);
c->buf_used += len;
- }
- mutex_unlock(&c->lock);
+ resume_on(c); // notify other side
+
+ mutex_unlock(&c->lock);
+
+ ret += len;
+ } else if (h->mode & FM_BLOCKING) {
+ int st = enter_critical(CL_NOINT);
- if (len) resume_on(c); // notify processes that may be waiting for data
- ret += len;
+ mutex_unlock(&c->lock);
+
+ wait_on(c);
+
+ exit_critical(st);
+ } else {
+ mutex_unlock(&c->lock);
+ }
} while ((h->mode & FM_BLOCKING) && ret < req_len);
return ret;
diff --git a/src/lib/libkogata/stdio.c b/src/lib/libkogata/stdio.c
index 1c298ad..e62aa30 100644
--- a/src/lib/libkogata/stdio.c
+++ b/src/lib/libkogata/stdio.c
@@ -1,4 +1,5 @@
#include <syscall.h>
+#include <string.h>
#include <printf.h>
#include <stdio.h>
@@ -7,12 +8,6 @@
fd_t stdio = 1;
int getc() {
- sel_fd_t fd;
- fd.fd = stdio;
- fd.req_flags = SEL_READ;
- ASSERT(select(&fd, 1, -1));
- ASSERT(fd.got_flags & SEL_READ);
-
char chr;
size_t sz = read(stdio, 0, 1, &chr);
ASSERT(sz == 1);
@@ -26,7 +21,7 @@ void putc(int c) {
}
void puts(char* s) {
- while (*s) putc(*(s++));
+ write(stdio, 0, strlen(s), s);
}
void getline(char* buf, size_t l) {
diff --git a/src/sysbin/shell/main.c b/src/sysbin/shell/main.c
index 1929025..2eb2c6c 100644
--- a/src/sysbin/shell/main.c
+++ b/src/sysbin/shell/main.c
@@ -14,7 +14,10 @@ void ls(char* dir) {
dirent_t i;
int ent_no = 0;
while (readdir(f, ent_no++, &i)) {
- printf("%s\n", i.name);
+ if (i.st.type & FT_DIR)
+ printf("%s/\n", i.name);
+ else
+ printf("%s\n", i.name);
}
close(f);
} else {
@@ -22,10 +25,28 @@ void ls(char* dir) {
}
}
+void cat(char* file) {
+ fd_t f = open(file, FM_READ);
+ if (f) {
+ char buf[129];
+ size_t p = 0;
+ while (true) {
+ size_t r = read(f, p, 128, buf);
+ p += r;
+ buf[r] = 0;
+ puts(buf);
+ if (r < 128) break;
+ }
+ close(f);
+ } else {
+ printf("Could not open file '%s'\n", file);
+ }
+}
+
int main(int argc, char **argv) {
dbg_printf("[shell] Starting\n");
- /*fctl(stdio, FC_SET_BLOCKING, 0);*/
+ fctl(1, FC_SET_BLOCKING, 0);
puts("Kogata shell.\n");
@@ -49,6 +70,13 @@ int main(int argc, char **argv) {
ls(buf2);
}
}
+ } else if (!strncmp(buf, "cat ", 4)) {
+ char buf2[256];
+ if (getcwd(buf2, 256)) {
+ if (pathncat(buf2, buf+4, 256)) {
+ cat(buf2);
+ }
+ }
} else if (!strcmp(buf, "exit")) {
break;
} else {