diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2007-07-05 18:01:38 +0200 |
---|---|---|
committer | Sascha Hauer <sha@octopus.labnet.pengutronix.de> | 2007-07-05 18:01:38 +0200 |
commit | 9b4dfd79953ffb79685a53a0821bd0a205e15088 (patch) | |
tree | ddb8b85bc241fa46df900d8262f299e2455674b4 /fs/fs.c | |
parent | 189579188bf79e176cc57a3b6d68f8306cfc7c60 (diff) | |
download | barebox-9b4dfd79953ffb79685a53a0821bd0a205e15088.tar.gz barebox-9b4dfd79953ffb79685a53a0821bd0a205e15088.tar.xz |
svn_rev_272
more FS work
Diffstat (limited to 'fs/fs.c')
-rw-r--r-- | fs/fs.c | 70 |
1 files changed, 52 insertions, 18 deletions
@@ -5,6 +5,7 @@ #include <asm-generic/errno.h> #include <malloc.h> #include <linux/stat.h> +#include <fcntl.h> char *mkmodestr(unsigned long mode, char *str) { @@ -152,7 +153,7 @@ int creat(const char *pathname, mode_t mode) dev = e->dev; fsdrv = (struct fs_driver_d *)dev->driver->type_data; - errno = fsdrv->create(dev, pathname, mode); + errno = fsdrv->create(dev, pathname, S_IFREG); return errno; } @@ -163,32 +164,58 @@ int open(const char *pathname, int flags) struct fs_driver_d *fsdrv; struct mtab_entry *e; FILE *f; - int ret; + int exist; + struct stat s; + + exist = stat(pathname, &s) == 0 ? 1 : 0; + + if (!exist && !(flags & O_CREAT)) + return -EEXIST; f = get_file_by_pathname(pathname); - if (!f->dev) { - e = get_mtab_entry_by_path(pathname); - if (!e) { - errno = -ENOENT; - goto out; - } + if (f->dev) + return f->no; - if (e != mtab) - pathname += strlen(e->path); + e = get_mtab_entry_by_path(pathname); + if (!e) { + /* This can only happen when nothing is mounted */ + errno = -ENOENT; + goto out; + } - dev = e->dev; + /* Adjust the pathname to the root of the device */ + if (e != mtab) + pathname += strlen(e->path); - fsdrv = (struct fs_driver_d *)dev->driver->type_data; - f->dev = dev; + dev = e->dev; - ret = fsdrv->open(dev, f, pathname); - if (ret) { - errno = ret; + fsdrv = (struct fs_driver_d *)dev->driver->type_data; + f->dev = dev; + + if ((flags & O_ACCMODE) && !fsdrv->write) { + errno = -EROFS; + goto out; + } + + if (!exist) { + errno = fsdrv->create(dev, pathname, S_IFREG); + if (errno) goto out; - } } -printf("open: %d\n",f->no); + errno = fsdrv->open(dev, f, pathname); + if (errno) + goto out; + + if (flags & O_APPEND) + f->pos = f->size; + + if (flags & O_TRUNC) { + errno = fsdrv->truncate(dev, f, 0); + if (errno) + goto out; + } + return f->no; out: @@ -206,6 +233,7 @@ int read(int fd, void *buf, size_t count) printf("READ: dev: %p\n",dev); if (dev->type == DEVICE_TYPE_FS) { fsdrv = (struct fs_driver_d *)dev->driver->type_data; + printf("\nreading %d bytes at %d\n",count, f->pos); errno = fsdrv->read(dev, f, buf, count); } else { errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */ @@ -225,6 +253,12 @@ ssize_t write(int fd, const void *buf, size_t count) printf("WRITE: dev: %p\n",dev); if (dev->type == DEVICE_TYPE_FS) { fsdrv = (struct fs_driver_d *)dev->driver->type_data; + if (f->pos + count > f->size) { + errno = fsdrv->truncate(dev, f, f->pos + count); + if (errno) + return errno; + f->size = f->pos + count; + } errno = fsdrv->write(dev, f, buf, count); } else { errno = dev->driver->write(dev, buf, count, f->pos, 0); /* FIXME: flags */ |