/* Write */ static ssize_t tun_chr_write(struct file * file, const char * buf, size_t count, loff_t *pos) { struct tun_struct *tun = (struct tun_struct *)file->private_data; DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count); if (!(tun->flags & TUN_IFF_SET)) return -EBUSY; if (verify_area(VERIFY_READ, buf, count)) return -EFAULT; return tun_get_user(tun, buf, count); }
/* Writev */ static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv, unsigned long count, loff_t *pos) { struct tun_struct *tun = (struct tun_struct *)file->private_data; unsigned long i; size_t len; if (!tun) return -EBADFD; DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count); for (i = 0, len = 0; i < count; i++) { if (verify_area(VERIFY_READ, iv[i].iov_base, iv[i].iov_len)) return -EFAULT; len += iv[i].iov_len; } return tun_get_user(tun, (struct iovec *) iv, len); }