[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH v2 4/6] libc: lio_compat_read()
* libc: lio_compat_read() aus fread herausgesplittet, so dass nur noch
das Pufferzeug in fread bleibt
! libc: Das müsste auch einen Bug mit dem Dateizeiger beheben, der
danebengelegen haben dürfte, wenn ein Request teilweise aus dem
ungetc-Puffer beantwortet wird. Dazu wird jetz ein einziger Block mit
großer Blockgröße angefordert.
! libc: fflush() wird auch aufgerufen, wenn Daten per SHM übertragen
werden
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/modules/include/lostio.h | 4 ++
src/modules/lib/lostio/client/file.c | 73 +++++++++++++++++++++++++++++
src/modules/lib/stdlibc/file.c | 84 +++++-----------------------------
3 files changed, 89 insertions(+), 72 deletions(-)
diff --git a/src/modules/include/lostio.h b/src/modules/include/lostio.h
index 00576b0..d94488c 100644
--- a/src/modules/include/lostio.h
+++ b/src/modules/include/lostio.h
@@ -195,6 +195,10 @@ io_resource_t* lio_compat_open(const char* filename, uint8_t attr);
/// Stream schliessen
int lio_compat_close(io_resource_t* io_res);
+/// Von einem Stream lesen
+size_t lio_compat_read(void* dest, size_t blocksize, size_t blockcount,
+ io_resource_t* io_res);
+
/// In einen Stream schreiben
size_t lio_compat_write(const void* src, size_t blocksize, size_t blockcount,
io_resource_t* io_res);
diff --git a/src/modules/lib/lostio/client/file.c b/src/modules/lib/lostio/client/file.c
index 701e30e..6140f6a 100644
--- a/src/modules/lib/lostio/client/file.c
+++ b/src/modules/lib/lostio/client/file.c
@@ -33,6 +33,27 @@
#include <rpc.h>
#include <syscall.h>
+static void* shm_ptr;
+static uint32_t shm_id;
+static size_t shm_size;
+
+static void* get_shm(size_t size)
+{
+ if (shm_size >= size) {
+ return shm_ptr;
+ }
+
+ if (shm_id != 0) {
+ close_shared_memory(shm_id);
+ }
+
+ shm_size = size;
+ shm_id = create_shared_memory(size);
+ shm_ptr = open_shared_memory(shm_id);
+
+ return shm_ptr;
+}
+
io_resource_t* lio_compat_open(const char* filename, uint8_t attr)
{
char* full_path = io_get_absolute_path(filename);
@@ -77,6 +98,58 @@ int lio_compat_close(io_resource_t* io_res)
return result;
}
+size_t lio_compat_read(void* dest, size_t blocksize, size_t blockcount,
+ io_resource_t* io_res)
+{
+ io_read_request_t read_request = {
+ .id = io_res->id,
+ .blocksize = blocksize,
+ .blockcount = blockcount,
+ };
+
+ // Wenn mehr als 256 Bytes gelesen werden sollen, wird SHM benutzt
+ if ((blocksize * blockcount) > 256) {
+
+ get_shm(blocksize * blockcount);
+ read_request.shared_mem_id = shm_id;
+
+ response_t* resp = rpc_get_response(io_res->pid, "IO_READ ",
+ sizeof(read_request), (char*) &(read_request));
+ size_t size = *((size_t*) resp->data);
+
+ // Wenn zuviele Daten gekommen sind, wird nur der notwendige Teil
+ // kopiert.
+ if (size > blocksize * blockcount) {
+ size = blocksize * blockcount;
+ }
+
+ memcpy(dest, shm_ptr, size);
+
+ free(resp->data);
+ free(resp);
+
+ return size;
+ } else {
+ read_request.shared_mem_id = 0;
+
+ response_t* resp = rpc_get_response(io_res->pid, "IO_READ ",
+ sizeof(read_request), (char*) &(read_request));
+ size_t size = resp->data_length;
+
+ // Wenn zuviele Daten gekommen sind, wird nur der notwendige Teil
+ // kopiert.
+ if (size > blocksize * blockcount) {
+ size = blocksize * blockcount;
+ }
+ memcpy(dest, resp->data, size);
+
+ free(resp->data);
+ free(resp);
+
+ return size;
+ }
+}
+
size_t lio_compat_write(const void* src, size_t blocksize, size_t blockcount,
io_resource_t* io_res)
{
diff --git a/src/modules/lib/stdlibc/file.c b/src/modules/lib/stdlibc/file.c
index beda758..b1b9aec 100644
--- a/src/modules/lib/stdlibc/file.c
+++ b/src/modules/lib/stdlibc/file.c
@@ -42,27 +42,6 @@
extern char* io_get_absolute_path(const char* path);
-static void* shm_ptr;
-static uint32_t shm_id;
-static size_t shm_size;
-
-static void* get_shm(size_t size)
-{
- if (shm_size >= size) {
- return shm_ptr;
- }
-
- if (shm_id != 0) {
- close_shared_memory(shm_id);
- }
-
- shm_size = size;
- shm_id = create_shared_memory(size);
- shm_ptr = open_shared_memory(shm_id);
-
- return shm_ptr;
-}
-
/**
* Datei oeffnen
*
@@ -204,11 +183,12 @@ int fclose (FILE* io_res)
*/
size_t fread(void* dest, size_t blocksize, size_t blockcount, FILE* io_res)
{
+ int ret;
+ size_t read_bytes = 0;
+
if ((io_res == NULL) || (io_res->res->pid == 0)) {
return 0;
}
-
- size_t read_bytes = 0;
// Wenn Daten im ungetc-Buffer sind, werden die zuerst ausgelesen.
if (io_res->ungetc_count != 0) {
@@ -239,58 +219,18 @@ size_t fread(void* dest, size_t blocksize, size_t blockcount, FILE* io_res)
return read_bytes;
}
}
-
- io_read_request_t read_request;
- read_request.id = io_res->res->id;
- read_request.blocksize = blocksize;
- read_request.blockcount = blockcount;
-
- // Wenn mehr als 1 Kb gelesen werden soll, wird SHM benutzt
- if ((blocksize * blockcount) - read_bytes > 256) {
-
- get_shm(blocksize * blockcount);
- read_request.shared_mem_id = shm_id;
- response_t* resp = rpc_get_response(io_res->res->pid, "IO_READ ",
- sizeof(read_request), (char*) &(read_request));
- size_t size = *((size_t*) resp->data);
-
- // Wenn zuviele Daten gekommen sind, wird nur der notwendige Teil
- // kopiert.
- if (size + read_bytes > (blocksize * blockcount)) {
- size = (blocksize * blockcount) - read_bytes;
- }
-
- memcpy((void*) ((uintptr_t) dest + read_bytes), shm_ptr, size);
-
- free(resp->data);
- free(resp);
-
- return size + read_bytes;
- } else {
- read_request.shared_mem_id = 0;
-
- // Der Buffer wird noch geleert, damit auch wirklich die Aktuellsten
- // Daten gelesen werden.
- fflush(io_res);
+ // Der Buffer wird noch geleert, damit auch wirklich die Aktuellsten
+ // Daten gelesen werden.
+ fflush(io_res);
- response_t* resp = rpc_get_response(io_res->res->pid, "IO_READ ",
- sizeof(read_request), (char*) &(read_request));
- size_t size = resp->data_length;
-
- // Wenn zuviele Daten gekommen sind, wird nur der notwendige Teil
- // kopiert.
- if (size + read_bytes > (blocksize * blockcount)) {
- size = (blocksize * blockcount) - read_bytes;
- }
- memcpy((void*) ((uintptr_t) dest + read_bytes), resp->data, size);
-
-
- free(resp->data);
- free(resp);
-
- return size + read_bytes;
+ ret = lio_compat_read(dest + read_bytes,
+ (blocksize * blockcount) - read_bytes, 1, io_res->res);
+ if (ret < 0) {
+ return 0;
}
+
+ return read_bytes + ret;
}
--
1.6.0.2