summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2008-12-12 20:40:13 +0100
committerNeal H. Walfield <neal@gnu.org>2008-12-12 20:40:13 +0100
commita5e75da5e8be80e82f55214e388a7c3ae2a32990 (patch)
tree7d04f766bc0c0465a21c95b989d52040c2b499ee
parentfe97559f4391ba06821173613cd8cecdccd22e1d (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/ChangeLog34
-rw-r--r--newlib/Makefile.am13
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/Makefile.am9
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/closer.c30
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/fcntlr.c21
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/lseekr.c55
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/openr.c64
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/readr.c33
-rw-r--r--newlib/addon/newlib/libc/sys/hurd/writer.c57
9 files changed, 266 insertions, 50 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 2d594cd..16dcb24 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,37 @@
+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.
+
2008-11-03 Neal H. Walfield <neal@gnu.org>
* headers.m4: Don't create an empty newlib/libc.a or an empty
diff --git a/newlib/Makefile.am b/newlib/Makefile.am
index a4a9dd8..346dc68 100644
--- a/newlib/Makefile.am
+++ b/newlib/Makefile.am
@@ -67,7 +67,18 @@ addon = \
newlib/libc/sys/hurd/include/signal.h \
newlib/libc/sys/hurd/sys/lock.h \
newlib/libc/sys/hurd/sys/config.h \
- newlib/libc/sys/hurd/sys/errno.h
+ newlib/libc/sys/hurd/sys/errno.h \
+ 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 \
+ newlib/libc/sys/hurd/memfile.c
EXTRA_DIST = $(addprefix patches/, $(patch_files)) \
$(addprefix addon/, $(addon))
diff --git a/newlib/addon/newlib/libc/sys/hurd/Makefile.am b/newlib/addon/newlib/libc/sys/hurd/Makefile.am
index 57fe11d..5b62495 100644
--- a/newlib/addon/newlib/libc/sys/hurd/Makefile.am
+++ b/newlib/addon/newlib/libc/sys/hurd/Makefile.am
@@ -50,6 +50,15 @@ GENERAL_SOURCES = \
malloc.c \
mallocr.c \
crt0.c \
+ access.c \
+ fsync.c \
+ ftruncate.c \
+ getcwd.c \
+ getpwuid.c \
+ getrusage.c \
+ getuid.c \
+ sleep.c \
+ pipefile.c memfile.c fd.h \
$(addprefix $(machine_dir)/,$(MACHINE_SOURCES))
if USE_LIBTOOL
diff --git a/newlib/addon/newlib/libc/sys/hurd/closer.c b/newlib/addon/newlib/libc/sys/hurd/closer.c
index b497780..83f1f74 100644
--- a/newlib/addon/newlib/libc/sys/hurd/closer.c
+++ b/newlib/addon/newlib/libc/sys/hurd/closer.c
@@ -2,12 +2,36 @@
#include <reent.h>
#include <errno.h>
+#include "fd.h"
int
-close (int fd)
+close (int fdi)
{
- errno = EOPNOTSUPP;
- return -1;
+ 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);
+
+ fd->ops->close (fd);
+ _fds[fdi] = NULL;
+
+ ss_mutex_unlock (&fd->lock);
+
+ return 0;
}
int
diff --git a/newlib/addon/newlib/libc/sys/hurd/fcntlr.c b/newlib/addon/newlib/libc/sys/hurd/fcntlr.c
index 10b26d1..735a802 100644
--- a/newlib/addon/newlib/libc/sys/hurd/fcntlr.c
+++ b/newlib/addon/newlib/libc/sys/hurd/fcntlr.c
@@ -3,11 +3,26 @@
#include <sys/stat.h>
#include <errno.h>
+#include "fd.h"
+
int
-fcntl (int fd, int cmd, ...)
+fcntl (int fdi, int cmd, ...)
{
- errno = EOPNOTSUPP;
- return -1;
+ 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);
+
+ /* XXX: Just say that we support it for now. */
+
+ return 0;
}
int
diff --git a/newlib/addon/newlib/libc/sys/hurd/lseekr.c b/newlib/addon/newlib/libc/sys/hurd/lseekr.c
index 3e2c94a..a33f728 100644
--- a/newlib/addon/newlib/libc/sys/hurd/lseekr.c
+++ b/newlib/addon/newlib/libc/sys/hurd/lseekr.c
@@ -2,11 +2,60 @@
#include <unistd.h>
#include <errno.h>
+#include "fd.h"
+
_off_t
-lseek (int fd, _off_t pos, int whence)
+lseek (int fdi, _off_t pos, int whence)
{
- errno = EOPNOTSUPP;
- return -1;
+ 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);
+
+ if (fd->size == -1)
+ {
+ errno = EPIPE;
+ ss_mutex_unlock (&_fd_lock);
+ return -1;
+ }
+
+ switch (whence)
+ {
+ case SEEK_SET:
+ fd->pos = pos;
+ break;
+ case SEEK_CUR:
+ fd->pos += pos;
+ break;
+ case SEEK_END:
+ fd->pos = fd->size - pos;
+ break;
+ default:
+ break;
+ }
+
+ if (fd->pos < 0)
+ fd->pos = 0;
+
+ pos = fd->pos;
+
+ ss_mutex_unlock (&fd->lock);
+
+ return pos;
}
_off_t
diff --git a/newlib/addon/newlib/libc/sys/hurd/openr.c b/newlib/addon/newlib/libc/sys/hurd/openr.c
index ca18038..e701a43 100644
--- a/newlib/addon/newlib/libc/sys/hurd/openr.c
+++ b/newlib/addon/newlib/libc/sys/hurd/openr.c
@@ -4,12 +4,72 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <hurd/mutex.h>
+
+#include "fd.h"
+
+ss_mutex_t _fd_lock;
+
+static struct _fd *static_fds[] = { &_stdio, &_stdio, &_stdio, 0, 0, 0 };
+
+struct _fd **_fds = static_fds;
+int _fd_size = sizeof (static_fds) / sizeof (static_fds[0]);
int
open (const char *file, int flags, ...)
{
- errno = EOPNOTSUPP;
- return -1;
+ struct _fd *fd;
+ fd = pipefile_open (file, flags);
+ if (! fd)
+ fd = memfile_open (file, flags);
+ if (! fd)
+ {
+ errno = ENOENT;
+ return -1;
+ }
+
+ ss_mutex_lock (&_fd_lock);
+
+ int i;
+ for (i = 0; i < _fd_size; i ++)
+ if (_fds[i] == NULL)
+ break;
+
+ if (i == _fd_size)
+ /* Not large enough. */
+ {
+ debug (5, "Growing fd array (%d)", _fd_size);
+
+ if (_fds == static_fds)
+ {
+ _fds = malloc (sizeof (_fds[0]) * _fd_size * 2);
+ if (_fds)
+ memcpy (_fds, static_fds, sizeof (static_fds));
+ }
+ else
+ _fds = realloc (_fds, sizeof (_fds[0]) * _fd_size * 2);
+
+ if (! _fds)
+ {
+ debug (0, "Out of memory.");
+ abort ();
+ }
+
+ memset (&_fds[_fd_size], 0, sizeof (_fds[0]) * _fd_size);
+
+ _fd_size *= 2;
+ }
+
+ debug (5, "Allocating fd %d", i);
+
+ _fds[i] = fd;
+
+ ss_mutex_unlock (&_fd_lock);
+
+ return i;
}
int
diff --git a/newlib/addon/newlib/libc/sys/hurd/readr.c b/newlib/addon/newlib/libc/sys/hurd/readr.c
index 1177a41..dea3143 100644
--- a/newlib/addon/newlib/libc/sys/hurd/readr.c
+++ b/newlib/addon/newlib/libc/sys/hurd/readr.c
@@ -4,25 +4,42 @@
#include <unistd.h>
#include <errno.h>
-#include <hurd/rm.h>
+#include "fd.h"
_ssize_t
-read (int fd, void *buf, size_t cnt)
+read (int fdi, void *buf, size_t cnt)
{
- if (fd != 0)
+ if (fdi < 0 || fdi >= _fd_size)
{
errno = EBADF;
return -1;
}
+ ss_mutex_lock (&_fd_lock);
+
+ struct _fd *fd = _fds[fdi];
+ if (! fd || ! fd->ops->pread)
+ {
+ errno = EBADF;
+ ss_mutex_unlock (&_fd_lock);
+ return -1;
+ }
+
if (cnt == 0)
- return 0;
+ {
+ ss_mutex_unlock (&_fd_lock);
+ return 0;
+ }
+
+ ss_mutex_lock (&fd->lock);
+ ss_mutex_unlock (&_fd_lock);
+
+ _ssize_t len = fd->ops->pread (fd, buf, cnt, fd->pos);
+ fd->pos += len;
- struct io_buffer buffer;
- rm_read (cnt, &buffer);
+ ss_mutex_unlock (&fd->lock);
- memcpy (buf, buffer.data, buffer.len);
- return buffer.len;
+ return len;
}
_ssize_t
diff --git a/newlib/addon/newlib/libc/sys/hurd/writer.c b/newlib/addon/newlib/libc/sys/hurd/writer.c
index d9198de..b8b4cc8 100644
--- a/newlib/addon/newlib/libc/sys/hurd/writer.c
+++ b/newlib/addon/newlib/libc/sys/hurd/writer.c
@@ -2,45 +2,42 @@
#include <unistd.h>
#include <errno.h>
-#include <hurd/rm.h>
+#include "fd.h"
-static void
-io_buffer_flush (struct io_buffer *buffer)
+_ssize_t
+write (int fdi, const void *buf, size_t cnt)
{
- if (buffer->len == 0)
- return;
-
- rm_write (*buffer);
- buffer->len = 0;
-}
+ if (fdi < 0 || fdi >= _fd_size)
+ {
+ errno = EBADF;
+ return -1;
+ }
-static void
-io_buffer_append (struct io_buffer *buffer, int chr)
-{
- if (buffer->len == sizeof (buffer->data))
- io_buffer_flush (buffer);
+ ss_mutex_lock (&_fd_lock);
- buffer->data[buffer->len ++] = chr;
-}
+ struct _fd *fd = _fds[fdi];
+ if (! fd || ! fd->ops->pwrite)
+ {
+ errno = EBADF;
+ ss_mutex_unlock (&_fd_lock);
+ return -1;
+ }
-_ssize_t
-write (int fd, const void *buf, size_t cnt)
-{
- if (fd == 1 || fd == 2)
+ if (cnt == 0)
{
- struct io_buffer buffer;
- buffer.len = 0;
+ ss_mutex_unlock (&_fd_lock);
+ return 0;
+ }
- int i;
- for (i = 0; i < cnt; i ++)
- io_buffer_append (&buffer, ((char *) buf)[i]);
- io_buffer_flush (&buffer);
+ ss_mutex_lock (&fd->lock);
+ ss_mutex_unlock (&_fd_lock);
- return cnt;
- }
+ _ssize_t len = fd->ops->pwrite (fd, buf, cnt, fd->pos);
+ fd->pos += len;
+
+ ss_mutex_unlock (&fd->lock);
- errno = EOPNOTSUPP;
- return -1;
+ return len;
}