diff options
author | Alexander Aring <alex.aring@gmail.com> | 2013-02-17 22:05:01 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-02-20 08:22:42 +0100 |
commit | 9d8a20592fdc55be56add1639606b65e3cc523d1 (patch) | |
tree | b00eca00c6930954f213443fb990631dd2dd1110 /fs/fs.c | |
parent | e48b1440715f7f25d664faf98f5afe0a787f7c68 (diff) | |
download | barebox-9d8a20592fdc55be56add1639606b65e3cc523d1.tar.gz barebox-9d8a20592fdc55be56add1639606b65e3cc523d1.tar.xz |
fs: add pread and pwrite functions
Add pread and pwrite functions.
Split read and write functions to save some space.
The functions pread and pwrite saves and sets the file
position to a given offset and restore them afterwards.
This also makes the nandtest command use these function
which is necessary to not break compilation for the nandtest
command.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'fs/fs.c')
-rw-r--r-- | fs/fs.c | 88 |
1 files changed, 74 insertions, 14 deletions
@@ -754,17 +754,12 @@ int ioctl(int fd, int request, void *buf) return ret; } -ssize_t read(int fd, void *buf, size_t count) +static ssize_t __read(FILE *f, void *buf, size_t count) { struct device_d *dev; struct fs_driver_d *fsdrv; - FILE *f; int ret; - if (check_fd(fd)) - return -errno; - - f = &files[fd]; dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -777,18 +772,33 @@ ssize_t read(int fd, void *buf, size_t count) ret = fsdrv->read(dev, f, buf, count); - if (ret > 0) - f->pos += ret; if (ret < 0) errno = -ret; return ret; } -EXPORT_SYMBOL(read); -ssize_t write(int fd, const void *buf, size_t count) +ssize_t pread(int fd, void *buf, size_t count, loff_t offset) +{ + loff_t pos; + FILE *f; + int ret; + + if (check_fd(fd)) + return -errno; + + f = &files[fd]; + + pos = f->pos; + f->pos = offset; + ret = __read(f, buf, count); + f->pos = pos; + + return ret; +} +EXPORT_SYMBOL(pread); + +ssize_t read(int fd, void *buf, size_t count) { - struct device_d *dev; - struct fs_driver_d *fsdrv; FILE *f; int ret; @@ -796,6 +806,21 @@ ssize_t write(int fd, const void *buf, size_t count) return -errno; f = &files[fd]; + + ret = __read(f, buf, count); + + if (ret > 0) + f->pos += ret; + return ret; +} +EXPORT_SYMBOL(read); + +static ssize_t __write(FILE *f, const void *buf, size_t count) +{ + struct device_d *dev; + struct fs_driver_d *fsdrv; + int ret; + dev = f->dev; fsdrv = dev_to_fs_driver(dev); @@ -812,13 +837,48 @@ ssize_t write(int fd, const void *buf, size_t count) } } ret = fsdrv->write(dev, f, buf, count); - if (ret > 0) - f->pos += ret; out: if (ret < 0) errno = -ret; return ret; } + +ssize_t pwrite(int fd, const void *buf, size_t count, loff_t offset) +{ + loff_t pos; + FILE *f; + int ret; + + if (check_fd(fd)) + return -errno; + + f = &files[fd]; + + pos = f->pos; + f->pos = offset; + ret = __write(f, buf, count); + f->pos = pos; + + return ret; +} +EXPORT_SYMBOL(pwrite); + +ssize_t write(int fd, const void *buf, size_t count) +{ + FILE *f; + int ret; + + if (check_fd(fd)) + return -errno; + + f = &files[fd]; + + ret = __write(f, buf, count); + + if (ret > 0) + f->pos += ret; + return ret; +} EXPORT_SYMBOL(write); int flush(int fd) |