diff options
author | Neal H. Walfield <neal@gnu.org> | 2008-12-12 20:40:36 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2008-12-12 20:40:36 +0100 |
commit | e14c083e9edf8632fe35647ef82f104433029405 (patch) | |
tree | 52bb8cf8d98648998328a893afb609afb2207609 | |
parent | a5e75da5e8be80e82f55214e388a7c3ae2a32990 (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.c | 8 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/fd.h | 37 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/fsync.c | 26 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/ftruncate.c | 40 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/getcwd.c | 16 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/getpwuid.c | 20 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/getrusage.c | 9 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/getuid.c | 32 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/memfile.c | 118 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/memfile.h | 1 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/pipefile.c | 93 | ||||
-rw-r--r-- | newlib/addon/newlib/libc/sys/hurd/sleep.c | 10 |
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; +} |