diff options
Diffstat (limited to 'drivers/char/vt_ioctl.c')
-rw-r--r-- | drivers/char/vt_ioctl.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index f69a8258095c..6c7384afff13 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -23,6 +23,7 @@ #include <linux/major.h> #include <linux/fs.h> #include <linux/console.h> +#include <linux/consolemap.h> #include <linux/signal.h> #include <linux/timex.h> @@ -582,10 +583,27 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, case KDGKBDIACR: { struct kbdiacrs __user *a = up; + struct kbdiacr diacr; + int i; if (put_user(accent_table_size, &a->kb_cnt)) return -EFAULT; - if (copy_to_user(a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr))) + for (i = 0; i < accent_table_size; i++) { + diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr); + diacr.base = conv_uni_to_8bit(accent_table[i].base); + diacr.result = conv_uni_to_8bit(accent_table[i].result); + if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) + return -EFAULT; + } + return 0; + } + case KDGKBDIACRUC: + { + struct kbdiacrsuc __user *a = up; + + if (put_user(accent_table_size, &a->kb_cnt)) + return -EFAULT; + if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc))) return -EFAULT; return 0; } @@ -593,6 +611,30 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, case KDSKBDIACR: { struct kbdiacrs __user *a = up; + struct kbdiacr diacr; + unsigned int ct; + int i; + + if (!perm) + return -EPERM; + if (get_user(ct,&a->kb_cnt)) + return -EFAULT; + if (ct >= MAX_DIACR) + return -EINVAL; + accent_table_size = ct; + for (i = 0; i < ct; i++) { + if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) + return -EFAULT; + accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr); + accent_table[i].base = conv_8bit_to_uni(diacr.base); + accent_table[i].result = conv_8bit_to_uni(diacr.result); + } + return 0; + } + + case KDSKBDIACRUC: + { + struct kbdiacrsuc __user *a = up; unsigned int ct; if (!perm) @@ -602,7 +644,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (ct >= MAX_DIACR) return -EINVAL; accent_table_size = ct; - if (copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr))) + if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) return -EFAULT; return 0; } |