fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / char / vt_ioctl.c
index 24011e7..60740a1 100644 (file)
@@ -10,7 +10,6 @@
  *  Check put/get_user, cleanups - acme@conectiva.com.br - Jun 2001
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
@@ -97,7 +96,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
                if (!perm)
                        return -EPERM;
                if (!i && v == K_NOSUCHMAP) {
-                       /* disallocate map */
+                       /* deallocate map */
                        key_map = key_maps[s];
                        if (s && key_map) {
                            key_maps[s] = NULL;
@@ -130,7 +129,7 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
                            !capable(CAP_SYS_RESOURCE))
                                return -EPERM;
 
-                       key_map = (ushort *) kmalloc(sizeof(plain_map),
+                       key_map = kmalloc(sizeof(plain_map),
                                                     GFP_KERNEL);
                        if (!key_map)
                                return -ENOMEM;
@@ -260,7 +259,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
                    sz = 256;
                    while (sz < funcbufsize - funcbufleft + delta)
                      sz <<= 1;
-                   fnw = (char *) kmalloc(sz, GFP_KERNEL);
+                   fnw = kmalloc(sz, GFP_KERNEL);
                    if(!fnw) {
                      ret = -ENOMEM;
                      goto reterr;
@@ -646,13 +645,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
         */
        case KDSIGACCEPT:
        {
-               extern int spawnpid, spawnsig;
                if (!perm || !capable(CAP_KILL))
                  return -EPERM;
                if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
                  return -EINVAL;
-               spawnpid = current->pid;
-               spawnsig = arg;
+
+               spin_lock_irq(&vt_spawn_con.lock);
+               put_pid(vt_spawn_con.pid);
+               vt_spawn_con.pid = get_pid(task_pid(current));
+               vt_spawn_con.sig = arg;
+               spin_unlock_irq(&vt_spawn_con.lock);
                return 0;
        }
 
@@ -670,7 +672,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                vc->vt_mode = tmp;
                /* the frsig is ignored, so we set it to 0 */
                vc->vt_mode.frsig = 0;
-               vc->vt_pid = current->pid;
+               put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current))));
                /* no switch is required -- saw@shade.msu.ru */
                vc->vt_newvt = -1;
                release_console_sem();
@@ -820,20 +822,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                if (arg > MAX_NR_CONSOLES)
                        return -ENXIO;
                if (arg == 0) {
-                   /* disallocate all unused consoles, but leave 0 */
+                   /* deallocate all unused consoles, but leave 0 */
                        acquire_console_sem();
                        for (i=1; i<MAX_NR_CONSOLES; i++)
                                if (! VT_BUSY(i))
-                                       vc_disallocate(i);
+                                       vc_deallocate(i);
                        release_console_sem();
                } else {
-                       /* disallocate a single console, if possible */
+                       /* deallocate a single console, if possible */
                        arg--;
                        if (VT_BUSY(arg))
                                return -EBUSY;
                        if (arg) {                            /* leave 0 */
                                acquire_console_sem();
-                               vc_disallocate(arg);
+                               vc_deallocate(arg);
                                release_console_sem();
                        }
                }
@@ -848,11 +850,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                if (get_user(ll, &vtsizes->v_rows) ||
                    get_user(cc, &vtsizes->v_cols))
                        return -EFAULT;
-               for (i = 0; i < MAX_NR_CONSOLES; i++) {
-                       acquire_console_sem();
-                       vc_resize(vc_cons[i].d, cc, ll);
-                       release_console_sem();
-               }
+               for (i = 0; i < MAX_NR_CONSOLES; i++)
+                       vc_lock_resize(vc_cons[i].d, cc, ll);
                return 0;
        }
 
@@ -1012,6 +1011,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                   return -EPERM;
                vt_dont_switch = 0;
                return 0;
+       case VT_GETHIFONTMASK:
+               return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg);
        default:
                return -ENOIOCTLCMD;
        }
@@ -1037,10 +1038,22 @@ int vt_waitactive(int vt)
 
        add_wait_queue(&vt_activate_queue, &wait);
        for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
                retval = 0;
-               if (vt == fg_console)
+
+               /*
+                * Synchronize with redraw_screen(). By acquiring the console
+                * semaphore we make sure that the console switch is completed
+                * before we return. If we didn't wait for the semaphore, we
+                * could return at a point where fg_console has already been
+                * updated, but the console switch hasn't been completed.
+                */
+               acquire_console_sem();
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (vt == fg_console) {
+                       release_console_sem();
                        break;
+               }
+               release_console_sem();
                retval = -EINTR;
                if (signal_pending(current))
                        break;
@@ -1062,7 +1075,7 @@ void reset_vc(struct vc_data *vc)
        vc->vt_mode.relsig = 0;
        vc->vt_mode.acqsig = 0;
        vc->vt_mode.frsig = 0;
-       vc->vt_pid = -1;
+       put_pid(xchg(&vc->vt_pid, NULL));
        vc->vt_newvt = -1;
        if (!in_interrupt())    /* Via keyboard.c:SAK() - akpm */
                reset_palette(vc);
@@ -1086,7 +1099,7 @@ static void complete_change_console(struct vc_data *vc)
        switch_screen(vc);
 
        /*
-        * This can't appear below a successful kill_proc().  If it did,
+        * This can't appear below a successful kill_pid().  If it did,
         * then the *blank_screen operation could occur while X, having
         * received acqsig, is waking up on another processor.  This
         * condition can lead to overlapping accesses to the VGA range
@@ -1109,11 +1122,11 @@ static void complete_change_console(struct vc_data *vc)
         */
        if (vc->vt_mode.mode == VT_PROCESS) {
                /*
-                * Send the signal as privileged - kill_proc() will
+                * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
                 * is awry
                 */
-               if (kill_proc(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
+               if (kill_pid(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
@@ -1169,11 +1182,11 @@ void change_console(struct vc_data *new_vc)
        vc = vc_cons[fg_console].d;
        if (vc->vt_mode.mode == VT_PROCESS) {
                /*
-                * Send the signal as privileged - kill_proc() will
+                * Send the signal as privileged - kill_pid() will
                 * tell us if the process has gone or something else
                 * is awry
                 */
-               if (kill_proc(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
+               if (kill_pid(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