[PATCH RFC] libspe2 add opendir and related functions

Patrick Mansfield patmans@us.ibm.com
Fri Jun 15 17:57:00 GMT 2007


Modified to just always use 64 bits (for opendir DIR* result, and to get
the DIR* from the SPU), so we don't have to hash to a 32 bit value.

Add assist calls for:

	DIR *opendir(const char *name)
	int closedir(DIR *dir)
	struct dirent *readdir(DIR *dir)
	void rewinddir(DIR *dir)
	void seekdir(DIR *dir, off_t offset)
	off_t telldir(DIR *dir)

Signed-off-by: Patrick Mansfield <patmans@us.ibm.com>

Index: quilt-libspe2/spebase/default_posix1_handler.c
===================================================================
--- quilt-libspe2.orig/spebase/default_posix1_handler.c
+++ quilt-libspe2/spebase/default_posix1_handler.c
@@ -34,6 +34,9 @@
 #include <sys/wait.h>
 #include <fcntl.h>
 #include <linux/limits.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <dirent.h>
 
 #include "default_posix1_handler.h"
 #include "handler_utils.h"
@@ -142,6 +145,12 @@ enum {
 	SPE_POSIX1_TRUNCATE,
 	SPE_POSIX1_MKSTEMP,
 	SPE_POSIX1_MKTEMP,
+	SPE_POSIX1_OPENDIR,
+	SPE_POSIX1_CLOSEDIR,
+	SPE_POSIX1_READDIR,
+	SPE_POSIX1_REWINDDIR,
+	SPE_POSIX1_SEEKDIR,
+	SPE_POSIX1_TELLDIR,
 	SPE_POSIX1_LAST_OPCODE,
 };
 #define SPE_POSIX1_NR_OPCODES	\
@@ -207,6 +216,48 @@ struct spe_compat_timex {
         int  :32; int  :32; int  :32; int  :32;
 };
 
+struct spe_compat_dirent {
+        uint32_t d_ino;
+        char d_name[256];
+};
+
+#ifdef __powerpc64__
+static inline void *spe_reg128toptr(struct spe_reg128 *reg)
+{
+    addr64 a64;
+
+    a64.by32[0] = reg->slot[0];
+    a64.by32[1] = reg->slot[1];
+    return (void *) a64.all64;
+}
+
+static inline uint64_t spe_ptrto64 (void *ptr)
+{
+    return (uint64_t) ptr;
+}
+
+#else
+static inline void *spe_reg128toptr(struct spe_reg128 *reg)
+{
+    return (void *) reg->slot[1];
+}
+
+static inline uint64_t spe_ptrto64 (void *ptr)
+{
+    addr64 a64;
+
+    a64.by32[0] = 0; /* never used */
+    a64.by32[1] = (unsigned int) ptr;
+    return a64.all64;
+}
+#endif
+
+static void spe_copy_dirent(struct spe_compat_dirent *spe_ent,
+                            struct dirent *ent)
+{
+    spe_ent->d_ino = ent->d_ino;
+    memcpy(spe_ent->d_name, ent->d_name, sizeof(spe_ent->d_name));
+}
 
 /**
  * default_posix1_handler_stat
@@ -1765,6 +1816,149 @@ int default_posix1_handler_mktemp(char *
     return 0;
 }
 
+/**
+ * default_posix1_handler_opendir
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data.
+ *
+ * Implement:
+ *       DIR *opendir(const char *dirname);
+ */
+int default_posix1_handler_opendir(char *ls, unsigned long opdata)
+{
+    DECL_1_ARGS();
+    DECL_RET();
+    char *name;
+    addr64 dir64;
+    DIR *dir;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    name = GET_LS_PTR(arg0->slot[0]);
+    dir = opendir(name);
+    dir64.all64 = spe_ptrto64(dir);
+    PUT_LS_RC(dir64.by32[0], dir64.by32[1], 0, errno);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_closedir
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data.
+ *
+ * Implement:
+ *       DIR *closedir(const char *dirname);
+ */
+int default_posix1_handler_closedir(char *ls, unsigned long opdata)
+{
+    DECL_1_ARGS();
+    DECL_RET();
+    DIR *dir;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    dir = spe_reg128toptr(arg0);
+    rc = closedir(dir);
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_readdir
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data, plus a secondary argument pass the
+ * location of the dirent.
+ *
+ * Implement:
+ *       struct dirent *readdir(DIR *dir)
+ */
+int default_posix1_handler_readdir(char *ls, unsigned long opdata)
+{
+    DECL_2_ARGS();
+    DECL_RET();
+    DIR *dir;
+    struct dirent *ent;
+    struct spe_compat_dirent *spe_ent;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    dir = spe_reg128toptr(arg0);
+    spe_ent = GET_LS_PTR(arg1->slot[0]);
+    ent = readdir(dir);
+    if (ent) {
+        spe_copy_dirent(spe_ent, ent);
+        rc = arg1->slot[0]; /* LS address of spe_ent */
+    } else {
+        rc = 0;
+    }
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_rewinddir
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data
+ *
+ * Implement:
+ *      void rewinddir(DIR *dir)
+ */
+int default_posix1_handler_rewinddir(char *ls, unsigned long opdata)
+{
+    DECL_1_ARGS();
+    DECL_RET();
+    DIR *dir;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    dir = spe_reg128toptr(arg0);
+    rewinddir(dir);
+    PUT_LS_RC(0, 0, 0, 0);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_seekdir
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data
+ *
+ * Implement:
+ *      void seekdir(DIR *dir)
+ */
+int default_posix1_handler_seekdir(char *ls, unsigned long opdata)
+{
+    DECL_2_ARGS();
+    DECL_RET();
+    DIR *dir;
+    off_t offset;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    dir = spe_reg128toptr(arg0);
+    offset = arg1->slot[0];
+    seekdir(dir, offset);
+    PUT_LS_RC(0, 0, 0, 0);
+    return 0;
+}
+
+/**
+ * default_posix1_handler_telldir
+ * @ls: base pointer to local store area.
+ * @opdata: POSIX.1 call opcode & data
+ *
+ * Implement:
+ */
+int default_posix1_handler_telldir(char *ls, unsigned long opdata)
+{
+    DECL_1_ARGS();
+    DECL_RET();
+    DIR *dir;
+    int rc;
+
+    DEBUG_PRINTF("%s\n", __func__);
+    dir = spe_reg128toptr(arg0);
+    rc = telldir(dir);
+    PUT_LS_RC(rc, 0, 0, errno);
+    return 0;
+}
+
 int (*default_posix1_funcs[SPE_POSIX1_NR_OPCODES]) (char *, unsigned long) = {
 	[SPE_POSIX1_UNUSED]		= NULL,
 	[SPE_POSIX1_ADJTIMEX]		= default_posix1_handler_adjtimex,
@@ -1821,6 +2015,12 @@ int (*default_posix1_funcs[SPE_POSIX1_NR
 	[SPE_POSIX1_TRUNCATE]		= default_posix1_handler_truncate,
 	[SPE_POSIX1_MKSTEMP]		= default_posix1_handler_mkstemp,
 	[SPE_POSIX1_MKTEMP]		= default_posix1_handler_mktemp,
+	[SPE_POSIX1_OPENDIR]		= default_posix1_handler_opendir,
+	[SPE_POSIX1_CLOSEDIR]		= default_posix1_handler_closedir,
+	[SPE_POSIX1_READDIR]		= default_posix1_handler_readdir,
+	[SPE_POSIX1_REWINDDIR]		= default_posix1_handler_rewinddir,
+	[SPE_POSIX1_SEEKDIR]		= default_posix1_handler_seekdir,
+	[SPE_POSIX1_TELLDIR]		= default_posix1_handler_telldir,
 };
 
 /**
Index: quilt-libspe2/spebase/default_posix1_handler.h
===================================================================
--- quilt-libspe2.orig/spebase/default_posix1_handler.h
+++ quilt-libspe2/spebase/default_posix1_handler.h
@@ -77,5 +77,11 @@ extern int default_posix1_handler_lockf(
 extern int default_posix1_handler_truncate(char *ls, unsigned long args);
 extern int default_posix1_handler_mkstemp(char *ls, unsigned long args);
 extern int default_posix1_handler_mktemp(char *ls, unsigned long args);
+extern int default_posix1_handler_opendir(char *ls, unsigned long args);
+extern int default_posix1_handler_closedir(char *ls, unsigned long args);
+extern int default_posix1_handler_readdir(char *ls, unsigned long args);
+extern int default_posix1_handler_rewinddir(char *ls, unsigned long args);
+extern int default_posix1_handler_seekdir(char *ls, unsigned long args);
+extern int default_posix1_handler_telldir(char *ls, unsigned long args);
 
 #endif /* __DEFAULT_POSIX1_HANDLER_H__ */



More information about the Newlib mailing list