summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2007-07-05 18:01:40 +0200
committerSascha Hauer <sha@octopus.labnet.pengutronix.de>2007-07-05 18:01:40 +0200
commit700983e486bbaadcb1ba76a61d286da7e8647254 (patch)
tree22cf2c3c77ea3a80150396abd05cfbcd26449a78 /fs
parent17fda95040e20f1a263ef8278ccc48f6e631faed (diff)
downloadbarebox-700983e486bbaadcb1ba76a61d286da7e8647254.tar.gz
barebox-700983e486bbaadcb1ba76a61d286da7e8647254.tar.xz
svn_rev_287
add lseek implementation, remove special handling of /dev/ (is now implemented as devfs)
Diffstat (limited to 'fs')
-rw-r--r--fs/fs.c147
1 files changed, 70 insertions, 77 deletions
diff --git a/fs/fs.c b/fs/fs.c
index 22fcbd554f..a626e6ffc4 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -128,10 +128,6 @@ static FILE* get_file_by_pathname(const char *pathname)
return NULL;
}
- if (!strncmp(pathname, "/dev/", 5)) {
- f->dev = get_device_by_id(pathname + 5);
- }
-
return f;
}
@@ -174,9 +170,6 @@ int open(const char *pathname, int flags)
f = get_file_by_pathname(pathname);
- if (f->dev)
- return f->no;
-
e = get_mtab_entry_by_path(pathname);
if (!e) {
/* This can only happen when nothing is mounted */
@@ -192,6 +185,7 @@ int open(const char *pathname, int flags)
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
f->dev = dev;
+ f->flags = flags;
if ((flags & O_ACCMODE) && !fsdrv->write) {
errno = -EROFS;
@@ -231,17 +225,13 @@ int read(int fd, void *buf, size_t count)
dev = f->dev;
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);
- if (f->pos + count > f->size)
- count = f->size - f->pos;
- errno = fsdrv->read(dev, f, buf, count);
- } else {
- if (f->pos + count > dev->size)
- count = dev->size - f->pos;
- errno = dev->driver->read(dev, buf, count, f->pos, 0); /* FIXME: flags */
- }
+
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+ printf("\nreading %d bytes at %d\n",count, f->pos);
+ if (f->pos + count > f->size)
+ count = f->size - f->pos;
+ errno = fsdrv->read(dev, f, buf, count);
+
if (errno > 0)
f->pos += errno;
return errno;
@@ -255,25 +245,51 @@ ssize_t write(int fd, const void *buf, size_t count)
dev = f->dev;
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 {
- if (f->pos + count > dev->size)
- count = dev->size - f->pos;
- errno = dev->driver->write(dev, buf, count, f->pos, 0); /* FIXME: flags */
+ 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);
+
if (errno > 0)
f->pos += errno;
return errno;
}
+off_t lseek(int fildes, off_t offset, int whence)
+{
+ FILE *f = &files[fildes];
+ errno = 0;
+
+ switch(whence) {
+ case SEEK_SET:
+ if (offset > f->size)
+ goto out;
+ f->pos = offset;
+ break;
+ case SEEK_CUR:
+ if (offset + f->pos > f->size)
+ goto out;
+ f->pos += offset;
+ break;
+ case SEEK_END:
+ if (offset)
+ goto out;
+ f->pos = f->size;
+ break;
+ default:
+ goto out;
+ }
+
+ return 0;
+out:
+ errno = -EINVAL;
+ return errno;
+}
+
int close(int fd)
{
struct device_d *dev;
@@ -282,16 +298,14 @@ int close(int fd)
dev = f->dev;
- if (dev->type == DEVICE_TYPE_FS) {
- fsdrv = (struct fs_driver_d *)dev->driver->type_data;
- errno = fsdrv->close(dev, f);
- }
+ fsdrv = (struct fs_driver_d *)dev->driver->type_data;
+ errno = fsdrv->close(dev, f);
put_file(f);
return errno;
}
-int mount (struct device_d *dev, char *fsname, char *path)
+int mount(struct device_d *dev, char *fsname, char *path)
{
struct driver_d *drv;
struct fs_driver_d *fs_drv;
@@ -420,14 +434,18 @@ struct dir *opendir(const char *pathname)
{
struct device_d *dev;
struct fs_driver_d *fsdrv;
- struct dir *dir;
+ struct dir *dir = NULL;
struct mtab_entry *e;
+ char *p = strdup(pathname);
+ char *freep = p;
- e = get_mtab_entry_by_path(pathname);
+ normalise_path(p);
+
+ e = get_mtab_entry_by_path(p);
if (!e)
- return NULL;
+ goto out;
if (e != mtab)
- pathname += strlen(e->path);
+ p += strlen(e->path);
dev = e->dev;
// printf("opendir: dev: %p\n",dev);
@@ -435,12 +453,14 @@ struct dir *opendir(const char *pathname)
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
// printf("opendir: fsdrv: %p\n",fsdrv);
- dir = fsdrv->opendir(dev, pathname);
+ dir = fsdrv->opendir(dev, p);
if (dir) {
dir->dev = dev;
dir->fsdrv = fsdrv;
}
+out:
+ free(freep);
return dir;
}
@@ -471,10 +491,12 @@ int stat(const char *filename, struct stat *s)
errno = -ENOENT;
goto out;
}
- if (e != mtab)
- f += strlen(e->path);
- dev = e->dev;
+ if (e != mtab && strcmp(f, e->path)) {
+ f += strlen(e->path);
+ dev = e->dev;
+ } else
+ dev = mtab->dev;
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
@@ -487,37 +509,6 @@ out:
return errno;
}
-int ls(const char *path)
-{
- struct dir *dir;
- struct dirent *d;
- char modestr[11];
- char tmp[PATH_MAX];
- struct stat s;
-
- dir = opendir(path);
- if (!dir) {
- errno = -ENOENT;
- return -ENOENT;
- }
-
- while ((d = readdir(dir))) {
- unsigned long namelen = strlen(d->name);
- sprintf(tmp, "%s/%s", path, d->name);
- if (stat(tmp, &s)) {
- perror("stat");
- return errno;
- }
-
- mkmodestr(s.st_mode, modestr);
- printf("%s %8d %*.*s\n",modestr, s.st_size, namelen, namelen, d->name);
- }
-
- closedir(dir);
-
- return 0;
-}
-
int mkdir (const char *pathname)
{
struct fs_driver_d *fsdrv;
@@ -537,8 +528,10 @@ int mkdir (const char *pathname)
fsdrv = (struct fs_driver_d *)dev->driver->type_data;
- if (fsdrv->mkdir)
- return fsdrv->mkdir(dev, pathname);
+ if (fsdrv->mkdir) {
+ errno = fsdrv->mkdir(dev, pathname);
+ return errno;
+ }
errno = -EROFS;
return -EROFS;