[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 4/5] 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 794a125..d610f7d 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 f474132..f9db4e5 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);
@@ -74,6 +95,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 1 Kb gelesen werden soll, 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 9f47e13..eb4b127 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
  *
@@ -202,11 +181,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) {
@@ -237,58 +217,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