summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2008-12-12 20:40:36 +0100
committerNeal H. Walfield <neal@gnu.org>2008-12-12 20:40:36 +0100
commite14c083e9edf8632fe35647ef82f104433029405 (patch)
tree52bb8cf8d98648998328a893afb609afb2207609
parenta5e75da5e8be80e82f55214e388a7c3ae2a32990 (diff)
Introduce a basic file descriptor abstraction and memory file support.
2008-12-12 Neal H. Walfield <neal@gnu.org> * addon/newlib/libc/sys/hurd/access.c: New file. * addon/newlib/libc/sys/hurd/fd.h: Likewise. * addon/newlib/libc/sys/hurd/fsync.c: Likewise. * addon/newlib/libc/sys/hurd/ftruncate.c: Likewise. * addon/newlib/libc/sys/hurd/getcwd.c: Likewise. * addon/newlib/libc/sys/hurd/getpwuid.c: Likewise. * addon/newlib/libc/sys/hurd/getrusage.c: Likewise. * addon/newlib/libc/sys/hurd/getuid.c: Likewise. * addon/newlib/libc/sys/hurd/memfile.c: Likewise. * addon/newlib/libc/sys/hurd/memfile.h: Likewise. * addon/newlib/libc/sys/hurd/pipefile.c: Likewise. * addon/newlib/libc/sys/hurd/sleep.c: Likewise. * Makefile.am (addon): Add newlib/libc/sys/hurd/access.c, newlib/libc/sys/hurd/fsync.c, newlib/libc/sys/hurd/ftruncate.c, newlib/libc/sys/hurd/getcwd.c, newlib/libc/sys/hurd/getpwuid.c, newlib/libc/sys/hurd/getrusage.c, newlib/libc/sys/hurd/getuid.c, newlib/libc/sys/hurd/sleep.c, newlib/libc/sys/hurd/fd.h, newlib/libc/sys/hurd/pipefile.c and newlib/libc/sys/hurd/memfile.c. * addon/newlib/libc/sys/hurd/Makefile.am (GENERAL_SOURCES): Add access.c, fsync.c, ftruncate.c, getcwd.c, getpwuid.c, getrusage.c, getuid.c, sleep.c, pipefile.c, memfile.c and fd.h. * addon/newlib/libc/sys/hurd/closer.c (close): Reimplement using the descriptor abstraction. * addon/newlib/libc/sys/hurd/lseekr.c (lseek): Likewise. * addon/newlib/libc/sys/hurd/openr.c (open): Likewise. * addon/newlib/libc/sys/hurd/readr.c (read): Likewise. * addon/newlib/libc/sys/hurd/writer.c (write): Likewise. * addon/newlib/libc/sys/hurd/fcntlr.c (fcntl): Return true for valid file descriptors.
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/access.c8
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/fd.h37
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/fsync.c26
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/ftruncate.c40
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/getcwd.c16
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/getpwuid.c20
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/getrusage.c9
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/getuid.c32
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/memfile.c118
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/memfile.h1
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/pipefile.c93
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/sleep.c10
12 files changed, 410 insertions, 0 deletions
diff --git a/newlib/addon/newlib/libc/sys/hurd/access.c b/newlib/addon/newlib/libc/sys/hurd/access.c
new file mode 100644
index 0000000..dc94955
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/access.c
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <errno.h>
+
+int
+access (const char *filename, int how)
+{
+ return 0;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/fd.h b/newlib/addon/newlib/libc/sys/hurd/fd.h
new file mode 100644
index 0000000..c342459
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/fd.h
@@ -0,0 +1,37 @@
+#ifndef HURD_FD
+
+#include <hurd/mutex.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+struct _fd;
+
+struct _fileops
+{
+ void (*close) (struct _fd *fd);
+ _ssize_t (*pread) (struct _fd *fd, void *buf, size_t size, off_t offset);
+ _ssize_t (*pwrite) (struct _fd *fd, void *buf, size_t size, off_t offset);
+ int (*ftruncate) (struct _fd *fd, off_t length);
+};
+
+struct _fd
+{
+ ss_mutex_t lock;
+ int pos;
+ /* -1 if its a pipe. */
+ int size;
+ struct _fileops *ops;
+};
+
+extern ss_mutex_t _fd_lock;
+extern struct _fd **_fds;
+/* Number of elements in _FILES. */
+extern int _fd_size;
+
+
+extern struct _fd *memfile_open (const char *filename, int access);
+extern struct _fd *pipefile_open (const char *filename, int access);
+
+extern struct _fd _stdio;
+
+#endif
diff --git a/newlib/addon/newlib/libc/sys/hurd/fsync.c b/newlib/addon/newlib/libc/sys/hurd/fsync.c
new file mode 100644
index 0000000..11be92b
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/fsync.c
@@ -0,0 +1,26 @@
+#include <unistd.h>
+#include <errno.h>
+
+#include "fd.h"
+
+int
+fsync (int fdi)
+{
+ if (fdi < 0 || fdi >= _fd_size)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ ss_mutex_lock (&_fd_lock);
+
+ struct _fd *fd = _fds[fdi];
+ ss_mutex_unlock (&_fd_lock);
+ if (! fd)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/ftruncate.c b/newlib/addon/newlib/libc/sys/hurd/ftruncate.c
new file mode 100644
index 0000000..6db91da
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/ftruncate.c
@@ -0,0 +1,40 @@
+#include <unistd.h>
+#include <errno.h>
+
+#include "fd.h"
+
+int
+ftruncate (int fdi, off_t length)
+{
+ if (fdi < 0 || fdi >= _fd_size)
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ ss_mutex_lock (&_fd_lock);
+
+ struct _fd *fd = _fds[fdi];
+ if (! fd)
+ {
+ errno = EBADF;
+ ss_mutex_unlock (&_fd_lock);
+ return -1;
+ }
+
+ ss_mutex_lock (&fd->lock);
+ ss_mutex_unlock (&_fd_lock);
+
+ int ret;
+ if (fd->ops->ftruncate)
+ ret = fd->ops->ftruncate (fd, length);
+ else
+ {
+ ret = -1;
+ errno = EPIPE;
+ }
+
+ ss_mutex_unlock (&fd->lock);
+
+ return ret;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/getcwd.c b/newlib/addon/newlib/libc/sys/hurd/getcwd.c
new file mode 100644
index 0000000..cbad3a8
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/getcwd.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+#include <errno.h>
+
+char *
+getcwd (char *buffer, size_t size)
+{
+ if (size < 2)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ buffer[0] = '/';
+ buffer[1] = 0;
+ return buffer;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/getpwuid.c b/newlib/addon/newlib/libc/sys/hurd/getpwuid.c
new file mode 100644
index 0000000..92c20bf
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/getpwuid.c
@@ -0,0 +1,20 @@
+#include <pwd.h>
+
+struct passwd *
+getpwuid (uid_t uid)
+{
+ if (uid != 0)
+ return NULL;
+
+ static struct passwd passwd;
+
+ passwd.pw_name = "root";
+ passwd.pw_passwd = "root";
+ passwd.pw_uid = 0;
+ passwd.pw_gid = 0;
+ passwd.pw_gecos = "root";
+ passwd.pw_dir = "/";
+ passwd.pw_shell = NULL;
+
+ return &passwd;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/getrusage.c b/newlib/addon/newlib/libc/sys/hurd/getrusage.c
new file mode 100644
index 0000000..926a997
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/getrusage.c
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <sys/resource.h>
+
+int
+getrusage (int processes, struct rusage *rusage)
+{
+ memset (rusage, 0, sizeof (*rusage));
+ return 0;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/getuid.c b/newlib/addon/newlib/libc/sys/hurd/getuid.c
new file mode 100644
index 0000000..8072937
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/getuid.c
@@ -0,0 +1,32 @@
+#include <sys/types.h>
+#include <unistd.h>
+
+uid_t
+getuid (void)
+{
+ return 0;
+}
+
+gid_t
+getgid (void)
+{
+ return 0;
+}
+
+uid_t
+geteuid (void)
+{
+ return 0;
+}
+
+gid_t
+getegid (void)
+{
+ return 0;
+}
+
+int
+getgroups (int count, gid_t *groups)
+{
+ return 0;
+}
diff --git a/newlib/addon/newlib/libc/sys/hurd/memfile.c b/newlib/addon/newlib/libc/sys/hurd/memfile.c
new file mode 100644
index 0000000..0e9f9ad
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/memfile.c
@@ -0,0 +1,118 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "fd.h"
+
+struct memfile
+{
+ struct _fd fd;
+
+ /* Bytes allocated. */
+ _ssize_t alloced;
+ void *data;
+ char *filename;
+};
+
+static _ssize_t
+mem_pread (struct _fd *fd, void *buf, size_t size, off_t offset)
+{
+ struct memfile *memfile = (void *) fd;
+
+ debug (5, "%s(%d) (%p, %d, %d)",
+ memfile->filename, fd->size, buf, size, offset);
+
+ if (offset >= fd->size)
+ return 0;
+
+ if (offset + size > fd->size)
+ size = fd->size - offset;
+
+ memcpy (buf, memfile->data + offset, size);
+
+ return size;
+}
+
+static int
+mem_ftruncate (struct _fd *fd, off_t length)
+{
+ struct memfile *memfile = (void *) fd;
+
+ debug (5, "%s(%d) (%d)", memfile->filename, fd->size, length);
+
+ if (length > memfile->alloced)
+ {
+ int a = memfile->alloced;
+
+ if (memfile->alloced == 0)
+ memfile->alloced = PAGESIZE;
+ while (length > memfile->alloced)
+ memfile->alloced *= 2;
+
+ debug (5, "Growing from %d to %d bytes", a, memfile->alloced);
+
+ memfile->data = realloc (memfile->data, memfile->alloced);
+ if (! memfile->data)
+ {
+ debug (0, "Out of memory");
+ abort ();
+ }
+
+ memset (memfile->data + a, 0, memfile->alloced - a);
+ }
+
+ fd->size = length;
+
+ return 0;
+}
+
+static _ssize_t
+mem_pwrite (struct _fd *fd, void *buf, size_t size, off_t offset)
+{
+ struct memfile *memfile = (void *) fd;
+
+ debug (5, "%s(%d) (%p, %d, %d)",
+ memfile->filename, fd->size, buf, size, offset);
+
+ if (offset + size > fd->size)
+ mem_ftruncate (fd, offset + size);
+
+ memcpy (memfile->data + offset, buf, size);
+
+ return size;
+}
+
+static void
+mem_close (struct _fd *fd)
+{
+ struct memfile *memfile = (void *) fd;
+
+ debug (0, "%s(%d)", memfile->filename, fd->size);
+
+ free (memfile->data);
+ free (memfile->filename);
+ free (memfile);
+}
+
+static struct _fileops ops =
+ {
+ .pread = mem_pread,
+ .pwrite = mem_pwrite,
+ .ftruncate = mem_ftruncate,
+ .close = mem_close,
+ };
+
+struct _fd *
+memfile_open (const char *filename, int access)
+{
+ struct memfile *memfile = calloc (sizeof (struct memfile), 1);
+
+ memfile->fd.ops = &ops;
+
+ memfile->filename = strdup (filename);
+
+ return &memfile->fd;
+}
+
diff --git a/newlib/addon/newlib/libc/sys/hurd/memfile.h b/newlib/addon/newlib/libc/sys/hurd/memfile.h
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/memfile.h
@@ -0,0 +1 @@
+
diff --git a/newlib/addon/newlib/libc/sys/hurd/pipefile.c b/newlib/addon/newlib/libc/sys/hurd/pipefile.c
new file mode 100644
index 0000000..1d01beb
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/pipefile.c
@@ -0,0 +1,93 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <hurd/rm.h>
+
+#include "fd.h"
+
+struct pipefile
+{
+ struct _fd fd;
+};
+
+static _ssize_t
+pipe_pread (struct _fd *fd, void *buf, size_t size, off_t offset)
+{
+ struct io_buffer buffer;
+ rm_read (ADDR_VOID, ADDR_VOID, size, &buffer);
+
+ memcpy (buf, buffer.data, buffer.len);
+ return buffer.len;
+}
+
+static int
+pipe_ftruncate (struct _fd *fd, off_t length)
+{
+ errno = EPIPE;
+ return -1;
+}
+
+static void
+io_buffer_flush (struct io_buffer *buffer)
+{
+ if (buffer->len == 0)
+ return;
+
+ rm_write (ADDR_VOID, ADDR_VOID, *buffer);
+ buffer->len = 0;
+}
+
+static void
+io_buffer_append (struct io_buffer *buffer, int chr)
+{
+ if (buffer->len == sizeof (buffer->data))
+ io_buffer_flush (buffer);
+
+ buffer->data[buffer->len ++] = chr;
+}
+
+static _ssize_t
+pipe_pwrite (struct _fd *fd, void *buf, size_t size, off_t offset)
+{
+ struct io_buffer buffer;
+ buffer.len = 0;
+
+ int i;
+ for (i = 0; i < size; i ++)
+ io_buffer_append (&buffer, ((char *) buf)[i]);
+ io_buffer_flush (&buffer);
+
+ return size;
+}
+
+static void
+pipe_close (struct _fd *fd)
+{
+ struct pipefile *pipefile = (void *) fd;
+
+ if (fd != &_stdio)
+ free (pipefile);
+}
+
+static struct _fileops ops =
+ {
+ .pread = pipe_pread,
+ .pwrite = pipe_pwrite,
+ .ftruncate = pipe_ftruncate,
+ .close = pipe_close,
+ };
+
+struct _fd _stdio = { 0, 0, -1, &ops };
+
+struct _fd *
+pipefile_open (const char *filename, int access)
+{
+ if (strcmp (filename, "/dev/stdin") != 0
+ && strcmp (filename, "/dev/stdout") != 0
+ && strcmp (filename, "/dev/stderr") != 0)
+ return NULL;
+
+ return &_stdio;
+}
+
diff --git a/newlib/addon/newlib/libc/sys/hurd/sleep.c b/newlib/addon/newlib/libc/sys/hurd/sleep.c
new file mode 100644
index 0000000..fecb5b3
--- /dev/null
+++ b/newlib/addon/newlib/libc/sys/hurd/sleep.c
@@ -0,0 +1,10 @@
+#include <unistd.h>
+#include <l4.h>
+
+unsigned int
+sleep (unsigned int seconds)
+{
+ /* XXX: This should be interrupted if a signal is received. */
+ l4_sleep (l4_time_period (seconds * 1000 * 1000));
+ return 0;
+}