This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: [PATCH RFC] libspe2 add opendir and related functions
- From: Patrick Mansfield <patmans at us dot ibm dot com>
- To: cbe-oss-dev at ozlabs dot org, newlib at sourceware dot org
- Date: Fri, 15 Jun 2007 10:56:19 -0700
- Subject: Re: [PATCH RFC] libspe2 add opendir and related functions
- References: <20070614150337.GA10320@us.ibm.com>
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__ */