diff options
author | Neal H. Walfield <neal@gnu.org> | 2008-12-12 20:40:13 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2008-12-12 20:40:13 +0100 |
commit | a5e75da5e8be80e82f55214e388a7c3ae2a32990 (patch) | |
tree | 7d04f766bc0c0465a21c95b989d52040c2b499ee | |
parent | fe97559f4391ba06821173613cd8cecdccd22e1d (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/ChangeLog | 34 | ||||
-rw-r--r-- | newlib/Makefile.am | 13 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/Makefile.am | 9 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/closer.c | 30 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/fcntlr.c | 21 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/lseekr.c | 55 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/openr.c | 64 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/readr.c | 33 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/writer.c | 57 |
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; } |