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

Re: [Lost] [Patch] Bugfix für stat und fstat



Am Montag, 10. März 2008 22.41:55 schrieb Antoine Kaufmann:
> Am Montag, 10. März 2008 22.09:40 schrieb Kevin Wolf:
> > Am Montag, 10. März 2008 21:31:20 schrieb Antoine Kaufmann:
> > > ! libc: Bugfix in stat beim aufrufen mit einem Verzeichnis als Pfad
> > > (wurde bis jetzt nicht richtig erkannt)
> > > + libc: Implementation fuer fstat
> >
> > Gibt es einen Grund, warum du jetzt opendir statt dem nativen (und bisher
> > benutzten) directory_open benutzt?
>
> Nein, eigentlich nicht...
>
> > Außerdem denke ich, daß der Zusammenhang zwischen fstat und stat genau
> > falschrum implementiert ist. Wenn eine Datei schon geöffnet ist, sollte
> > man nicht den Pfad holen und die Datei ein zweites Mal öffnen, sondern
> > diesen Dateideskriptor eben benutzen. stat kann dann die Datei öffnen und
> > fstat aufrufen.
>
> Jo das denke ich auch. Da sollte ich LostIO mal mit einem RPC nachrüsten
> und da darf ich wieder alle Treiber nachbessern, deswegen habe ich das noch
> gelassen. Aber irgendwo habe ich eh noch eine Ladung LostIO-Patches am
> rumliegen...

So hier jetzt noch ein fstat, das direkt den Dateideskriptor benutzt.
=== stat.c
==================================================================
--- stat.c	(/lost/trunk/src/modules/lib/posix/stat.c)	(revision 1433)
+++ stat.c	(/lost/local/src/modules/lib/posix/stat.c)	(revision 1433)
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 #include <stdio.h>
 #include <dir.h>
+#include <errno.h>
 
 /**
  * Modus einer Datei Aendern. Der Modus entscheidet unter anderem ueber
@@ -68,51 +69,78 @@
 }
 
 /**
- * Informationen zu einer Datei auslesen
+ * Informationen zu einer Datei anhand des Handles auslesen
  *
- * @param filename Dateinamen
+ * @param f Handle
  * @param stat_buf Pointer auf die stat-Struktur in der die Informationen
- *                 abgespeichert werden sollen.
+ *        abgespeichert werden sollen.
  *
  * @return 0 bei Erfolg, -1 im Fehlerfall
  */
-int stat(const char* filename, struct stat* stat_buf)
+static int lost_stat(FILE* f, struct stat* stat_buf)
 {
+    long pos;
+
     // Zuerst die ganze Struktur auf 0 Setzen
     memset(stat_buf, 0, sizeof(struct stat));
 
-    FILE* file = fopen(filename, "r");
+    stat_buf->st_mode |= S_IFREG;
     
-    // Wenn die Datei nicht geoeffnet werden kann wird sofort abgebrochen
-    if (file == NULL) {
-        return -1;
-    }
+    pos = ftell(f);
 
     // TODO im Moment wird nur die Groesse eingetragen
+    fseek(f, 0, SEEK_END);
+    stat_buf->st_size = ftell(f);
+    
+    fseek(f, pos, SEEK_SET);
 
-    fseek(file, 0, SEEK_END);
-    stat_buf->st_size = ftell(file);
-
     stat_buf->st_blksize = 512;
     stat_buf->st_blocks = stat_buf->st_size / stat_buf->st_blksize;
     if (stat_buf->st_size % stat_buf->st_blksize != 0) {
         stat_buf->st_blocks++;
     }
+    stat_buf->st_uid = 0;
+    stat_buf->st_gid = 0;
+
+    return 0;
+}
+
+/**
+ * Informationen zu einer Datei auslesen
+ *
+ * @param filename Dateinamen
+ * @param stat_buf Pointer auf die stat-Struktur in der die Informationen
+ *                 abgespeichert werden sollen.
+ *
+ * @return 0 bei Erfolg, -1 im Fehlerfall
+ */
+int stat(const char* filename, struct stat* stat_buf)
+{
+    int status = 0;
+    FILE* file = fopen(filename, "r");
     
-    // Versuchen den Pfad als verzeichnis zu oeffen. Falls dies klappt wird der
-    // entsprehende Modus gesetzt
-    io_resource_t* dir = directory_open(filename);
-    if (dir != NULL) {
+    // Wenn die Datei nicht geoeffnet werden kann, koennte es sich um ein
+    // Verzeichnis handeln, falls nicht wird sofort abgebrochen
+    if (file == NULL) {
+        io_resource_t* dir = directory_open(filename);
+        if (dir == NULL) {
+            errno = ENOENT;
+            return -1;
+        }
         directory_close(dir);
+        
+        // Zuerst die ganze Struktur auf 0 Setzen
+        memset(stat_buf, 0, sizeof(struct stat));
+
         stat_buf->st_mode |= S_IFDIR;
+        stat_buf->st_uid = 0;
+        stat_buf->st_gid = 0;
     } else {
-        stat_buf->st_mode |= S_IFREG;
+        status = lost_stat(file, stat_buf);
+        fclose(file);
     }
 
-    stat_buf->st_uid = 0;
-    stat_buf->st_gid = 0;
-
-    return 0;
+    return status;
 }
 
 /**
@@ -141,8 +169,13 @@
  */
 int fstat(int file, struct stat* stat_buf)
 {
-    // TODO
-    return -1;
+    FILE* f = fdopen(file, "r");
+    if (f == NULL) {
+        errno = EBADF;
+        return -1;
+    }
+
+    return lost_stat(f, stat_buf);
 }
 
 /**