include/asm-um/module.h is generated
[linux-2.6.git] / fs / read_write.c
index bf99867..3109424 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/dnotify.h>
 #include <linux/security.h>
 #include <linux/module.h>
+#include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -113,9 +114,12 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
 {
        loff_t (*fn)(struct file *, loff_t, int);
 
-       fn = default_llseek;
-       if (file->f_op && file->f_op->llseek)
-               fn = file->f_op->llseek;
+       fn = no_llseek;
+       if (file->f_mode & FMODE_LSEEK) {
+               fn = default_llseek;
+               if (file->f_op && file->f_op->llseek)
+                       fn = file->f_op->llseek;
+       }
        return fn(file, offset, origin);
 }
 EXPORT_SYMBOL(vfs_llseek);
@@ -266,6 +270,16 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
 
 EXPORT_SYMBOL(vfs_write);
 
+static inline loff_t file_pos_read(struct file *file)
+{
+       return file->f_pos;
+}
+
+static inline void file_pos_write(struct file *file, loff_t pos)
+{
+       file->f_pos = pos;
+}
+
 asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
 {
        struct file *file;
@@ -274,12 +288,15 @@ asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_read(file, buf, count, &file->f_pos);
+               loff_t pos = file_pos_read(file);
+               ret = vfs_read(file, buf, count, &pos);
+               file_pos_write(file, pos);
                fput_light(file, fput_needed);
        }
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(sys_read);
 
 asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count)
 {
@@ -289,13 +306,17 @@ asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t co
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_write(file, buf, count, &file->f_pos);
+               loff_t pos = file_pos_read(file);
+               ret = vfs_write(file, buf, count, &pos);
+               file_pos_write(file, pos);
                fput_light(file, fput_needed);
        }
 
        return ret;
 }
 
+EXPORT_SYMBOL_GPL(sys_write);
+
 asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf,
                             size_t count, loff_t pos)
 {
@@ -308,7 +329,9 @@ asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf,
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_read(file, buf, count, &pos);
+               ret = -ESPIPE;
+               if (file->f_mode & FMODE_PREAD)
+                       ret = vfs_read(file, buf, count, &pos);
                fput_light(file, fput_needed);
        }
 
@@ -327,7 +350,9 @@ asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf,
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_write(file, buf, count, &pos);
+               ret = -ESPIPE;
+               if (file->f_mode & FMODE_PWRITE)  
+                       ret = vfs_write(file, buf, count, &pos);
                fput_light(file, fput_needed);
        }
 
@@ -511,7 +536,9 @@ sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_readv(file, vec, vlen, &file->f_pos);
+               loff_t pos = file_pos_read(file);
+               ret = vfs_readv(file, vec, vlen, &pos);
+               file_pos_write(file, pos);
                fput_light(file, fput_needed);
        }
 
@@ -527,7 +554,9 @@ sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
 
        file = fget_light(fd, &fput_needed);
        if (file) {
-               ret = vfs_writev(file, vec, vlen, &file->f_pos);
+               loff_t pos = file_pos_read(file);
+               ret = vfs_writev(file, vec, vlen, &pos);
+               file_pos_write(file, pos);
                fput_light(file, fput_needed);
        }
 
@@ -558,8 +587,12 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
                goto fput_in;
        if (!in_file->f_op || !in_file->f_op->sendfile)
                goto fput_in;
+       retval = -ESPIPE;
        if (!ppos)
                ppos = &in_file->f_pos;
+       else
+               if (!(in_file->f_mode & FMODE_PREAD))
+                       goto fput_in;
        retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, *ppos, count);
        if (retval)
                goto fput_in;