X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fvt_ioctl.c;h=8971484b956b11c8b6072ab163aaeb87d5945117;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=dd8e2f7817f5e9203b742e4c7f7866bcfae7eaf8;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index dd8e2f781..8971484b9 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -33,11 +34,11 @@ #include #include -char vt_dont_switch; +static char vt_dont_switch; extern struct tty_driver *console_driver; #define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count) -#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || i == sel_cons) +#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons) /* * Console (vt and kd) routines, as defined by USL SVR4 manual, and by @@ -52,17 +53,12 @@ extern struct tty_driver *console_driver; * to the current console is done by the main ioctl code. */ -struct vt_struct *vt_cons[MAX_NR_CONSOLES]; - -/* Keyboard type: Default is KB_101, but can be set by machine - * specific code. - */ -unsigned char keyboard_type = KB_101; - #ifdef CONFIG_X86 #include #endif +static void complete_change_console(struct vc_data *vc); + /* * these are the valid i/o ports we're allowed to change. they map all the * video ports @@ -311,7 +307,7 @@ do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struc op->height = cfdarg.charheight; op->charcount = cfdarg.charcount; op->data = cfdarg.chardata; - return con_font_op(fg_console, op); + return con_font_op(vc_cons[fg_console].d, op); case GIO_FONTX: { op->op = KD_FONT_OP_GET; op->flags = KD_FONT_FLAG_OLD; @@ -319,7 +315,7 @@ do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struc op->height = cfdarg.charheight; op->charcount = cfdarg.charcount; op->data = cfdarg.chardata; - i = con_font_op(fg_console, op); + i = con_font_op(vc_cons[fg_console].d, op); if (i) return i; cfdarg.charheight = op->height; @@ -333,27 +329,25 @@ do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struc } static inline int -do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, unsigned int console) +do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc) { struct unimapdesc tmp; - int i = 0; if (copy_from_user(&tmp, user_ud, sizeof tmp)) return -EFAULT; - if (tmp.entries) { - i = verify_area(VERIFY_WRITE, tmp.entries, - tmp.entry_ct*sizeof(struct unipair)); - if (i) return i; - } + if (tmp.entries) + if (!access_ok(VERIFY_WRITE, tmp.entries, + tmp.entry_ct*sizeof(struct unipair))) + return -EFAULT; switch (cmd) { case PIO_UNIMAP: if (!perm) return -EPERM; - return con_set_unimap(console, tmp.entry_ct, tmp.entries); + return con_set_unimap(vc, tmp.entry_ct, tmp.entries); case GIO_UNIMAP: - if (!perm && fg_console != console) + if (!perm && fg_console != vc->vc_num) return -EPERM; - return con_get_unimap(console, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries); + return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries); } return 0; } @@ -365,8 +359,7 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, unsigned i int vt_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { - struct vt_struct *vt = (struct vt_struct *)tty->driver_data; - struct vc_data *vc = vc_cons[vt->vc_num].d; + struct vc_data *vc = (struct vc_data *)tty->driver_data; struct console_font_op op; /* used in multiple places here */ struct kbd_struct * kbd; unsigned int console; @@ -374,7 +367,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, void __user *up = (void __user *)arg; int i, perm; - console = vt->vc_num; + console = vc->vc_num; if (!vc_cons_allocated(console)) /* impossible? */ return -ENOIOCTLCMD; @@ -419,7 +412,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, /* * this is naive. */ - ucval = keyboard_type; + ucval = KB_101; goto setchar; /* @@ -487,9 +480,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, default: return -EINVAL; } - if (vt_cons[console]->vc_mode == (unsigned char) arg) + if (vc->vc_mode == (unsigned char) arg) return 0; - vt_cons[console]->vc_mode = (unsigned char) arg; + vc->vc_mode = (unsigned char) arg; if (console != fg_console) return 0; /* @@ -504,7 +497,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, return 0; case KDGETMODE: - ucval = vt_cons[console]->vc_mode; + ucval = vc->vc_mode; goto setint; case KDMAPDISP: @@ -649,7 +642,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, extern int spawnpid, spawnsig; if (!perm || !capable(CAP_KILL)) return -EPERM; - if (arg < 1 || arg > _NSIG || arg == SIGKILL) + if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) return -EINVAL; spawnpid = current->pid; spawnsig = arg; @@ -667,12 +660,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) return -EINVAL; acquire_console_sem(); - vt_cons[console]->vt_mode = tmp; + vc->vt_mode = tmp; /* the frsig is ignored, so we set it to 0 */ - vt_cons[console]->vt_mode.frsig = 0; - vt_cons[console]->vt_pid = current->pid; + vc->vt_mode.frsig = 0; + vc->vt_pid = current->pid; /* no switch is required -- saw@shade.msu.ru */ - vt_cons[console]->vt_newvt = -1; + vc->vt_newvt = -1; release_console_sem(); return 0; } @@ -683,7 +676,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, int rc; acquire_console_sem(); - memcpy(&tmp, &vt_cons[console]->vt_mode, sizeof(struct vt_mode)); + memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode)); release_console_sem(); rc = copy_to_user(up, &tmp, sizeof(struct vt_mode)); @@ -761,31 +754,29 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, case VT_RELDISP: if (!perm) return -EPERM; - if (vt_cons[console]->vt_mode.mode != VT_PROCESS) + if (vc->vt_mode.mode != VT_PROCESS) return -EINVAL; /* * Switching-from response */ - if (vt_cons[console]->vt_newvt >= 0) - { + if (vc->vt_newvt >= 0) { if (arg == 0) /* * Switch disallowed, so forget we were trying * to do it. */ - vt_cons[console]->vt_newvt = -1; + vc->vt_newvt = -1; - else - { + else { /* * The current vt has been released, so * complete the switch. */ int newvt; acquire_console_sem(); - newvt = vt_cons[console]->vt_newvt; - vt_cons[console]->vt_newvt = -1; + newvt = vc->vt_newvt; + vc->vt_newvt = -1; i = vc_allocate(newvt); if (i) { release_console_sem(); @@ -796,7 +787,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, * make sure we are atomic with respect to * other console switches.. */ - complete_change_console(newvt); + complete_change_console(vc_cons[newvt].d); release_console_sem(); } } @@ -852,7 +843,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, return -EFAULT; for (i = 0; i < MAX_NR_CONSOLES; i++) { acquire_console_sem(); - vc_resize(i, cc, ll); + vc_resize(vc_cons[i].d, cc, ll); release_console_sem(); } return 0; @@ -864,7 +855,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ushort ll,cc,vlin,clin,vcol,ccol; if (!perm) return -EPERM; - if (verify_area(VERIFY_READ, vtconsize, + if (!access_ok(VERIFY_READ, vtconsize, sizeof(struct vt_consize))) return -EFAULT; __get_user(ll, &vtconsize->v_rows); @@ -900,7 +891,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, vc_cons[i].d->vc_scan_lines = vlin; if (clin) vc_cons[i].d->vc_font.height = clin; - vc_resize(i, cc, ll); + vc_resize(vc_cons[i].d, cc, ll); release_console_sem(); } return 0; @@ -915,7 +906,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, op.height = 0; op.charcount = 256; op.data = up; - return con_font_op(fg_console, &op); + return con_font_op(vc_cons[fg_console].d, &op); } case GIO_FONT: { @@ -925,7 +916,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, op.height = 32; op.charcount = 256; op.data = up; - return con_font_op(fg_console, &op); + return con_font_op(vc_cons[fg_console].d, &op); } case PIO_CMAP: @@ -953,9 +944,10 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, { op.op = KD_FONT_OP_SET_DEFAULT; op.data = NULL; - i = con_font_op(fg_console, &op); - if (i) return i; - con_set_default_unimap(fg_console); + i = con_font_op(vc_cons[fg_console].d, &op); + if (i) + return i; + con_set_default_unimap(vc_cons[fg_console].d); return 0; } #endif @@ -966,7 +958,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, return -EFAULT; if (!perm && op.op != KD_FONT_OP_GET) return -EPERM; - i = con_font_op(console, &op); + i = con_font_op(vc, &op); if (i) return i; if (copy_to_user(up, &op, sizeof(op))) return -EFAULT; @@ -995,13 +987,13 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, return -EPERM; i = copy_from_user(&ui, up, sizeof(struct unimapinit)); if (i) return -EFAULT; - con_clear_unimap(console, &ui); + con_clear_unimap(vc, &ui); return 0; } case PIO_UNIMAP: case GIO_UNIMAP: - return do_unimap_ioctl(cmd, up, perm, console); + return do_unimap_ioctl(cmd, up, perm, vc); case VT_LOCKSWITCH: if (!capable(CAP_SYS_TTY_CONFIG)) @@ -1054,25 +1046,25 @@ int vt_waitactive(int vt) #define vt_wake_waitactive() wake_up(&vt_activate_queue) -void reset_vc(unsigned int new_console) +void reset_vc(struct vc_data *vc) { - vt_cons[new_console]->vc_mode = KD_TEXT; - kbd_table[new_console].kbdmode = VC_XLATE; - vt_cons[new_console]->vt_mode.mode = VT_AUTO; - vt_cons[new_console]->vt_mode.waitv = 0; - vt_cons[new_console]->vt_mode.relsig = 0; - vt_cons[new_console]->vt_mode.acqsig = 0; - vt_cons[new_console]->vt_mode.frsig = 0; - vt_cons[new_console]->vt_pid = -1; - vt_cons[new_console]->vt_newvt = -1; + vc->vc_mode = KD_TEXT; + kbd_table[vc->vc_num].kbdmode = VC_XLATE; + vc->vt_mode.mode = VT_AUTO; + vc->vt_mode.waitv = 0; + vc->vt_mode.relsig = 0; + vc->vt_mode.acqsig = 0; + vc->vt_mode.frsig = 0; + vc->vt_pid = -1; + vc->vt_newvt = -1; if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */ - reset_palette(new_console) ; + reset_palette(vc); } /* * Performs the back end of a vt switch */ -void complete_change_console(unsigned int new_console) +static void complete_change_console(struct vc_data *vc) { unsigned char old_vc_mode; @@ -1083,8 +1075,8 @@ void complete_change_console(unsigned int new_console) * KD_TEXT mode or vice versa, which means we need to blank or * unblank the screen later. */ - old_vc_mode = vt_cons[fg_console]->vc_mode; - switch_screen(new_console); + old_vc_mode = vc_cons[fg_console].d->vc_mode; + switch_screen(vc); /* * This can't appear below a successful kill_proc(). If it did, @@ -1096,9 +1088,8 @@ void complete_change_console(unsigned int new_console) * To account for this we duplicate this code below only if the * controlling process is gone and we've called reset_vc. */ - if (old_vc_mode != vt_cons[new_console]->vc_mode) - { - if (vt_cons[new_console]->vc_mode == KD_TEXT) + if (old_vc_mode != vc->vc_mode) { + if (vc->vc_mode == KD_TEXT) do_unblank_screen(1); else do_blank_screen(1); @@ -1109,17 +1100,13 @@ void complete_change_console(unsigned int new_console) * telling it that it has acquired. Also check if it has died and * clean up (similar to logic employed in change_console()) */ - if (vt_cons[new_console]->vt_mode.mode == VT_PROCESS) - { + if (vc->vt_mode.mode == VT_PROCESS) { /* * Send the signal as privileged - kill_proc() will * tell us if the process has gone or something else * is awry */ - if (kill_proc(vt_cons[new_console]->vt_pid, - vt_cons[new_console]->vt_mode.acqsig, - 1) != 0) - { + if (kill_proc(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) { /* * The controlling process has died, so we revert back to * normal operation. In this case, we'll also change back @@ -1129,11 +1116,10 @@ void complete_change_console(unsigned int new_console) * this outside of VT_PROCESS but there is no single process * to account for and tracking tty count may be undesirable. */ - reset_vc(new_console); + reset_vc(vc); - if (old_vc_mode != vt_cons[new_console]->vc_mode) - { - if (vt_cons[new_console]->vc_mode == KD_TEXT) + if (old_vc_mode != vc->vc_mode) { + if (vc->vc_mode == KD_TEXT) do_unblank_screen(1); else do_blank_screen(1); @@ -1151,11 +1137,11 @@ void complete_change_console(unsigned int new_console) /* * Performs the front-end of a vt switch */ -void change_console(unsigned int new_console) +void change_console(struct vc_data *new_vc) { - if ((new_console == fg_console) || (vt_dont_switch)) - return; - if (!vc_cons_allocated(new_console)) + struct vc_data *vc; + + if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch) return; /* @@ -1173,23 +1159,20 @@ void change_console(unsigned int new_console) * the user waits just the right amount of time :-) and revert the * vt to auto control. */ - if (vt_cons[fg_console]->vt_mode.mode == VT_PROCESS) - { + vc = vc_cons[fg_console].d; + if (vc->vt_mode.mode == VT_PROCESS) { /* * Send the signal as privileged - kill_proc() will * tell us if the process has gone or something else * is awry */ - if (kill_proc(vt_cons[fg_console]->vt_pid, - vt_cons[fg_console]->vt_mode.relsig, - 1) == 0) - { + if (kill_proc(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { /* * It worked. Mark the vt to switch to and * return. The process needs to send us a * VT_RELDISP ioctl to complete the switch. */ - vt_cons[fg_console]->vt_newvt = new_console; + vc->vt_newvt = new_vc->vc_num; return; } @@ -1202,7 +1185,7 @@ void change_console(unsigned int new_console) * this outside of VT_PROCESS but there is no single process * to account for and tracking tty count may be undesirable. */ - reset_vc(fg_console); + reset_vc(vc); /* * Fall through to normal (VT_AUTO) handling of the switch... @@ -1212,8 +1195,8 @@ void change_console(unsigned int new_console) /* * Ignore all switches in KD_GRAPHICS+VT_AUTO mode */ - if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS) + if (vc->vc_mode == KD_GRAPHICS) return; - complete_change_console(new_console); + complete_change_console(new_vc); }