]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
skypopen: OSS driver, added some code from /dev/zero to read(), and performances...
authorGiovanni Maruzzelli <gmaruzz@gmail.com>
Mon, 27 Dec 2010 13:49:24 +0000 (07:49 -0600)
committerGiovanni Maruzzelli <gmaruzz@gmail.com>
Mon, 27 Dec 2010 13:49:38 +0000 (07:49 -0600)
src/mod/endpoints/mod_skypopen/oss/main.c

index a96e38d68a62a61ffa37de5c802153eafacbdbb4..10a210a574f0bc344ad1467ce8c541042ee8316c 100644 (file)
@@ -249,6 +249,7 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
                loff_t *f_pos)
 {
        DEFINE_WAIT(wait);
+        size_t written;
        struct skypopen_dev *dev = filp->private_data;
 
        if(unload)
@@ -273,8 +274,31 @@ static ssize_t skypopen_read(struct file *filp, char __user *buf, size_t count,
        prepare_to_wait(&dev->inq, &wait, TASK_INTERRUPTIBLE);
        schedule();
        finish_wait(&dev->inq, &wait);
-       return count;
 
+        if (!count)
+                return 0;
+
+        if (!access_ok(VERIFY_WRITE, buf, count))
+                return -EFAULT;
+
+        written = 0;
+        while (count) {
+                unsigned long unwritten;
+                size_t chunk = count;
+
+                if (chunk > PAGE_SIZE)
+                        chunk = PAGE_SIZE;      /* Just for latency reasons */
+                unwritten = __clear_user(buf, chunk);
+                written += chunk - unwritten;
+                if (unwritten)
+                        break;
+                if (signal_pending(current))
+                        return written ? written : -ERESTARTSYS;
+                buf += chunk;
+                count -= chunk;
+                cond_resched();
+        }
+        return written ? written : -EFAULT;
 }
 
 static ssize_t skypopen_write(struct file *filp, const char __user *buf, size_t count,