From: <jsi...@us...> - 2007-04-11 20:19:39
|
Revision: 2372 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2372&view=rev Author: jsimmons Date: 2007-04-11 13:19:34 -0700 (Wed, 11 Apr 2007) Log Message: ----------- more updates Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c 2007-04-11 19:53:20 UTC (rev 2371) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c 2007-04-11 20:19:34 UTC (rev 2372) @@ -21,13 +21,10 @@ * - making it shorter - scr_readw are macros which expand in PRETTY long code */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/major.h> #include <linux/errno.h> #include <linux/tty.h> -#include <linux/devfs_fs_kernel.h> -#include <linux/sched.h> #include <linux/interrupt.h> #include <linux/mm.h> #include <linux/init.h> @@ -87,7 +84,7 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct vc_data *vc = file->private_data; long attr = iminor(inode) & 128; int size; @@ -115,10 +112,11 @@ return file->f_pos; } + static ssize_t vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct vc_data *vc = file->private_data; long attr = iminor(inode) & 128; unsigned short *org = NULL; @@ -284,7 +282,7 @@ static ssize_t vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct vc_data *vc = file->private_data; long viewed, size, written, pos; long attr = iminor(inode) & 128; @@ -472,43 +470,36 @@ return 0; } -static struct file_operations vcs_fops = { +static const struct file_operations vcs_fops = { .llseek = vcs_lseek, .read = vcs_read, .write = vcs_write, .open = vcs_open, }; -static struct class_simple *vc_class; +static struct class *vc_class; -void vcs_make_devfs(struct tty_struct *tty) +void vcs_make_sysfs(struct tty_struct *tty) { - devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 1), - S_IFCHR|S_IRUSR|S_IWUSR, - "vcc/%u", tty->index + 1); - devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129), - S_IFCHR|S_IRUSR|S_IWUSR, - "vcc/a%u", tty->index + 1); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1); + device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), + "vcs%u", tty->index + 1); + device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), + "vcsa%u", tty->index + 1); } -void vcs_remove_devfs(struct tty_struct *tty) + +void vcs_remove_sysfs(struct tty_struct *tty) { - devfs_remove("vcc/%u", tty->index + 1); - devfs_remove("vcc/a%u", tty->index + 1); - class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 1)); - class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 129)); + device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); + device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); } int __init vcs_init(void) { if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); - vc_class = class_simple_create(THIS_MODULE, "vc"); + vc_class = class_create(THIS_MODULE, "vc"); - devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0"); - devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0"); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), "vcs"); + device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), "vcsa"); return 0; } Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-11 19:53:20 UTC (rev 2371) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-11 20:19:34 UTC (rev 2372) @@ -1054,7 +1054,7 @@ vc->vt_mode.relsig = 0; vc->vt_mode.acqsig = 0; vc->vt_mode.frsig = 0; - vc->vt_pid = -1; + put_pid(vc->vt_pid); vc->vt_newvt = -1; if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */ reset_palette(vc) ; @@ -1163,6 +1163,28 @@ return 0; } +void vc_SAK(struct work_struct *work) +{ + struct vc *vc_con = + container_of(work, struct vc, SAK_work); + struct tty_struct *tty; + struct vc_data *vc; + + acquire_console_sem(); + vc = vc_con->d; + if (vc) { + tty = vc->vc_tty; + /* + * SAK should also work in all raw modes and reset + * them properly. + */ + if (tty) + __do_SAK(tty); + reset_vc(vc); + } + release_console_sem(); +} + /* * Selection stuff for GPM. */ Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c 2007-04-11 19:53:20 UTC (rev 2371) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c 2007-04-11 20:19:34 UTC (rev 2372) @@ -11,7 +11,6 @@ * Check put/get_user, cleanups - ac...@co... - Jun 2001 */ -#include <linux/config.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/sched.h> @@ -82,10 +81,22 @@ add_wait_queue(&vt_activate_queue, &wait); for (;;) { + retval = 0; + + /* + * 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); - retval = 0; - if (IS_VISIBLE) + if (IS_VISIBLE) { + release_console_sem(); break; + } + release_console_sem(); retval = -EINTR; if (signal_pending(current)) break; @@ -108,6 +119,9 @@ if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry))) return -EFAULT; + if (!capable(CAP_SYS_TTY_CONFIG)) + perm = 0; + switch (cmd) { case KDGKBENT: key_map = key_maps[s]; @@ -122,7 +136,7 @@ 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; @@ -154,7 +168,7 @@ !capable(CAP_SYS_RESOURCE)) return -EPERM; - key_map = (ushort *) kmalloc(sizeof(plain_map), GFP_KERNEL); + key_map = kmalloc(sizeof(plain_map), GFP_KERNEL); if (!key_map) return -ENOMEM; key_maps[s] = key_map; @@ -214,6 +228,9 @@ u_char __user *up; u_char *q; + if (!capable(CAP_SYS_TTY_CONFIG)) + perm = 0; + kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); if (!kbs) { ret = -ENOMEM; @@ -275,7 +292,7 @@ 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; @@ -657,11 +674,11 @@ */ if (old_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(old_vc->vt_pid, old_vc->vt_mode.relsig, 1) == 0) { + if (kill_pid(old_vc->vt_pid, old_vc->vt_mode.relsig, 1) == 0) { /* * It worked. Mark the vt to switch to and * return. The process needs to send us a @@ -714,7 +731,7 @@ switch_screen(new_vc, old_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 @@ -739,11 +756,11 @@ */ if (new_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(new_vc->vt_pid,new_vc->vt_mode.acqsig, 1) != 0) { + if (kill_pid(new_vc->vt_pid,new_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 @@ -1054,13 +1071,16 @@ */ 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; } @@ -1078,7 +1098,8 @@ 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(vc->vt_pid); + vc->vt_pid = get_pid(task_pid(current)); /* no switch is required -- sa...@sh... */ vc->vt_newvt = -1; release_console_sem(); @@ -1248,13 +1269,13 @@ if (arg > MAX_NR_CONSOLES) return -ENXIO; if (arg == 0) { - /* disallocate all unused consoles, but leave visible VC */ + /* deallocate all unused consoles, but leave visible VC */ acquire_console_sem(); for (i = 1; i < vt->vc_count; i++) { tmp = find_vc(i + vt->first_vc); if (tmp && !VT_BUSY(tmp)) - vc_disallocate(tmp); + vc_deallocate(tmp); } release_console_sem(); } else { @@ -1263,7 +1284,7 @@ if (!tmp || VT_BUSY(tmp)) return -EBUSY; acquire_console_sem(); - vc_disallocate(tmp); + vc_deallocate(tmp); release_console_sem(); } return 0; @@ -1280,9 +1301,7 @@ for (i = 0; i < vc->display_fg->vc_count; i++) { struct vc_data *tmp = vc->display_fg->vc_cons[i]; - acquire_console_sem(); - vc_resize(tmp, cc, ll); - release_console_sem(); + vc_lock_resize(tmp, cc, ll); } return 0; } @@ -1441,6 +1460,8 @@ return -EPERM; vc->display_fg->vt_dont_switch = 0; return 0; + case VT_GETHIFONTMASK: + return put_user(vc->vc_hi_font_mask, (unsigned short __user *)arg); default: return -ENOIOCTLCMD; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jsi...@us...> - 2007-04-14 23:31:35
|
Revision: 2373 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2373&view=rev Author: jsimmons Date: 2007-04-14 16:31:33 -0700 (Sat, 14 Apr 2007) Log Message: ----------- merged to 2.6.21. Missing the new sysfs. Need to merge to what we have Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c 2007-04-11 20:19:34 UTC (rev 2372) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vc_screen.c 2007-04-14 23:31:33 UTC (rev 2373) @@ -52,6 +52,7 @@ void putconsxy(struct vc_data *vc, unsigned char *p) { + hide_cursor(vc); gotoxy(vc, p[0], p[1]); set_cursor(vc); } Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-11 20:19:34 UTC (rev 2372) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-14 23:31:33 UTC (rev 2373) @@ -72,6 +72,13 @@ * * Removed console_lock, enabled interrupts across all console operations * 13 March 2001, Andrew Morton + * + * Fixed UTF-8 mode so alternate charset modes always work according + * to control sequences interpreted in do_con_trol function + * preserving backward VT100 semigraphics compatibility, + * malformed UTF sequences represented as sequences of replacement glyphs, + * original codes or '?' as a last resort if replacement glyph is undefined + * by Adam Tla/lka <at...@pg...>, Aug 2006 */ #include <linux/module.h> @@ -87,14 +94,12 @@ #include <linux/mm.h> #include <linux/console.h> #include <linux/init.h> -#include <linux/devfs_fs_kernel.h> #include <linux/vt_kern.h> #include <linux/selection.h> #include <linux/tiocl.h> #include <linux/consolemap.h> #include <linux/timer.h> #include <linux/interrupt.h> -#include <linux/config.h> #include <linux/workqueue.h> #include <linux/bootmem.h> #include <linux/pm.h> @@ -113,8 +118,6 @@ #define CTRL_ACTION 0x0d00ff81 #define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */ -extern void vcs_make_devfs(struct tty_struct *tty); -extern void vcs_remove_devfs(struct tty_struct *tty); extern void console_map_init(void); #ifdef CONFIG_VGA_CONSOLE @@ -677,19 +680,24 @@ void complement_pos(struct vc_data *vc, int offset) { static unsigned short oldx, oldy, old; - static unsigned short *p; + static int old_offset = -1; WARN_CONSOLE_UNLOCKED(); - if (p) { - scr_writew(old, p); + if (old_offset != -1 && old_offset >= 0 && + old_offset < vc->vc_screenbuf_size) { + scr_writew(old, screenpos(vc, old_offset, 1)); if (DO_UPDATE) sw->con_putc(vc, old, oldy, oldx); } - if (offset == -1) - p = NULL; - else { + + old_offset = offset; + + if (offset != -1 && offset >= 0 && + offset < vc->vc_screenbuf_size) { unsigned short new; + unsigned short *p; + p = screenpos(vc, offset, 1); old = scr_readw(p); new = old ^ vc->vc_complement_mask; @@ -738,7 +746,7 @@ if (vt->vt_blanked) { if (vt->blank_state == blank_vesa_wait) { vt->blank_state = blank_off; - powerdown_screen((unsigned long)vt); + vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0); } return; } @@ -768,14 +776,14 @@ save_screen(vc); /* In case we need to reset origin, blanking hook returns 1 */ - i = sw->con_blank(vc, 1, 0); + i = sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0); vt->vt_blanked = 1; if (i) set_origin(vc); if (console_blank_hook && console_blank_hook(1)) return; - if (vt->off_interval) { + if (vt->off_interval && vt->blank_mode) { vt->blank_state = blank_vesa_wait; mod_timer(&vt->timer, jiffies + vt->off_interval); } @@ -785,9 +793,9 @@ EXPORT_SYMBOL(do_blank_screen); /* - * We defer the timer blanking to work queue so it can take the console semaphore + * We defer the timer blanking to work queue so it can take the console mutex * (console operations can still happen at irq time, but only from printk which - * has the console semaphore. Not perfect yet, but better than no locking + * has the console mutex. Not perfect yet, but better than no locking */ static void blank_screen_t(unsigned long dummy) { @@ -874,9 +882,9 @@ * with other console code and prevention of re-entrancy is * ensured with the console semaphore. */ -static void vt_callback(void *private) +static void vt_callback(struct work_struct *work) { - struct vt_struct *vt = (struct vt_struct *) private; + struct vt_struct *vt = container_of(work, struct vt_struct, SAK_work); if (!vt || !vt->want_vc || !vt->want_vc->vc_tty) return; @@ -908,10 +916,24 @@ release_console_sem(); } -inline void set_console(struct vc_data *vc) +int set_console(struct vc_data *vc) { + if (!vc || vc->display_fg->vt_dont_switch || + (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) { + + /* + * Console switch will fail in console_callback() or + * change_console() so there is no point scheduling + * the callback + * + * Existing set_console() users don't check the return + * value so this shouldn't break anything + */ + return -EINVAL; + } vc->display_fg->want_vc = vc; schedule_work(&vc->display_fg->vt_work); + return 0; } /* @@ -1003,6 +1025,7 @@ vc->vc_num = currcons; vc->display_fg = vt; + INIT_WORK(&vc->SAK_work, vc_SAK); visual_init(vc, 1); if (vt->kmalloced || !((vt->first_vc) == currcons)) { vc->vc_screenbuf = (unsigned short *) kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); @@ -1029,14 +1052,26 @@ return vc; } -int vc_disallocate(struct vc_data *vc) +int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) { + int rc; + + acquire_console_sem(); + rc = vc_resize(vc, cols, lines); + release_console_sem(); + return rc; +} + +int vc_deallocate(struct vc_data *vc) +{ struct vt_struct *vt = vc->display_fg; WARN_CONSOLE_UNLOCKED(); if (vc && vc->vc_num > MIN_NR_CONSOLES) { sw->con_deinit(vc); + put_pid(vc->vt_pid); + module_put(sw->owner); vt->vc_cons[vc->vc_num - vt->first_vc] = NULL; if (vt->kmalloced) kfree(screenbuf); @@ -1071,15 +1106,16 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) { - unsigned int old_cols, old_rows, old_screenbuf_size, old_row_size; - unsigned long ol, nl, nlend, rlth, rrem; - unsigned int new_cols, new_rows, ss, new_row_size, err = 0; + unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; + unsigned int old_cols, old_rows, old_row_size, old_screen_size; + unsigned int new_cols, new_rows, new_row_size, new_screen_size; + unsigned int end; unsigned short *newscreen; WARN_CONSOLE_UNLOCKED(); if (!vc) - return 0; + return -ENXIO; if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW) return -EINVAL; @@ -1087,23 +1123,22 @@ new_cols = (cols ? cols : vc->vc_cols); new_rows = (lines ? lines : vc->vc_rows); new_row_size = new_cols << 1; - ss = new_row_size * new_rows; + new_screen_size = new_row_size * new_rows; if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) return 0; - newscreen = (unsigned short *) kmalloc(ss, GFP_USER); + newscreen = kmalloc(new_screen_size, GFP_USER); if (!newscreen) return -ENOMEM; old_rows = vc->vc_rows; old_cols = vc->vc_cols; old_row_size = vc->vc_size_row; - old_screenbuf_size = vc->vc_screenbuf_size; + old_screen_size = vc->vc_screenbuf_size; err = resize_screen(vc, new_cols, new_rows); if (err) { - resize_screen(vc, old_cols, old_rows); kfree(newscreen); return err; } @@ -1111,32 +1146,57 @@ vc->vc_rows = new_rows; vc->vc_cols = new_cols; vc->vc_size_row = new_row_size; - vc->vc_screenbuf_size = ss; + vc->vc_screenbuf_size = new_screen_size; rlth = min(old_row_size, new_row_size); rrem = new_row_size - rlth; - ol = vc->vc_origin; - nl = (long) newscreen; - nlend = nl + ss; - if (new_rows < old_rows) - ol += (old_rows - new_rows) * old_row_size; + old_origin = vc->vc_origin; + new_origin = (long) newscreen; + new_scr_end = new_origin + new_screen_size; + if (vc->vc_y > new_rows) { + if (old_rows - vc->vc_y < new_rows) { + /* + * Cursor near the bottom, copy contents from the + * bottom of buffer + */ + old_origin += (old_rows - new_rows) * old_row_size; + end = vc->vc_scr_end; + } else { + /* + * Cursor is in no man's land, copy 1/2 screenful + * from the top and bottom of cursor position + */ + old_origin += (vc->vc_y - new_rows/2) * old_row_size; + end = old_origin + (old_row_size * new_rows); + } + } else + /* + * Cursor near the top, copy contents from the top of buffer + */ + end = (old_rows > new_rows) ? old_origin + + (old_row_size * new_rows) : + vc->vc_scr_end; + update_attr(vc); - while (ol < vc->vc_scr_end) { - scr_memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth); + while (old_origin < end) { + scr_memcpyw((unsigned short *) new_origin, + (unsigned short *) old_origin, rlth); if (rrem) - scr_memsetw((void *)(nl + rlth), vc->vc_video_erase_char, rrem); - ol += old_row_size; - nl += new_row_size; + scr_memsetw((void *)(new_origin + rlth), + vc->vc_video_erase_char, rrem); + old_origin += old_row_size; + new_origin += new_row_size; } - if (nlend > nl) - scr_memsetw((void *) nl, vc->vc_video_erase_char, nlend - nl); + if (new_scr_end > new_origin) + scr_memsetw((void *)new_origin, vc->vc_video_erase_char, + new_scr_end - new_origin); if (vc->display_fg->kmalloced) kfree(vc->vc_screenbuf); vc->vc_screenbuf = newscreen; vc->display_fg->kmalloced = 1; - vc->vc_screenbuf_size = ss; + vc->vc_screenbuf_size = new_screen_size; set_origin(vc); /* do part of a reset_terminal() */ @@ -1153,8 +1213,8 @@ ws.ws_col = vc->vc_cols; ws.ws_ypixel = vc->vc_scan_lines; if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && - vc->vc_tty->pgrp > 0) - kill_pg(vc->vc_tty->pgrp, SIGWINCH, 1); + vc->vc_tty->pgrp) + kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); *cws = ws; } @@ -1163,6 +1223,16 @@ return 0; } +int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) +{ + int rc; + + acquire_console_sem(); + rc = vc_resize(vc, cols, lines); + release_console_sem(); + return rc; +} + void vc_SAK(struct work_struct *work) { struct vc *vc_con = @@ -1273,17 +1343,23 @@ /* Do no translation at all in control states */ if (!vc->vc_state) { tc = c; - } else if (vc->vc_utf) { + } else if (vc->vc_utf && !vc->vc_disp_ctrl) { /* Combine UTF-8 into Unicode */ - /* Incomplete characters silently ignored */ + /* Malformed sequences as sequences of replacement glyphs */ +rescan_last_byte: if(c > 0x7f) { - if (vc->vc_utf_count > 0 && (c & 0xc0) == 0x80) { - vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); - vc->vc_utf_count--; - if (vc->vc_utf_count == 0) - tc = c = vc->vc_utf_char; - else continue; + if (vc->vc_utf_count > 0) + if ((c & 0xc0) == 0x80) { + vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); + if (--vc->vc_utf_count) { + vc->vc_npar++; + continue; + } + tc = c = vc->vc_utf_char; + else + goto replacement; } else { + vc->vc_npar = 0; if ((c & 0xe0) == 0xc0) { vc->vc_utf_count = 1; vc->vc_utf_char = (c & 0x1f); @@ -1300,15 +1376,16 @@ vc->vc_utf_count = 5; vc->vc_utf_char = (c & 0x01); } else - vc->vc_utf_count = 0; + goto replacement_glyph; continue; } } else { + if (vc->vc_utf_count) + goto replacement_glyph; tc = c; - vc->vc_utf_count = 0; } - } else { /* no utf */ - tc = vc->vc_translate[vc->vc_toggle_meta ? (c|0x80) : c]; + } else { /* no utf or alternate charset mode */ + tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; } /* If the original code was a control character we @@ -1322,31 +1399,33 @@ * direct-to-font zone in UTF-8 mode. */ ok = tc && (c >= 32 || - (!vc->vc_utf && !(((vc->vc_disp_ctrl ? CTRL_ALWAYS - : CTRL_ACTION) >> c) & 1))) + !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 : + vc->vc_utf || ((CTRL_ACTION >> c) & 1))) && (c != 127 || vc->vc_disp_ctrl) && (c != 128+27); if (!vc->vc_state && ok) { /* Now try to find out how to display it */ tc = conv_uni_to_pc(vc, tc); - if ( tc == -4 ) { + if (tc & ~charmask) { + if ( tc == -4 ) { /* If we got -4 (not found) then see if we have defined a replacement character (U+FFFD) */ - tc = conv_uni_to_pc(vc, 0xfffd); - - /* One reason for the -4 can be that we just - did a clear_unimap(); - try at least to show something. */ - if (tc == -4) - tc = c; - } else if ( tc == -3 ) { - /* Bad hash table -- hope for the best */ - tc = c; +replacement_glyph: + tc = conv_uni_to_pc(vc, 0xfffd); + if (!(tc & ~charmask)) + goto display_glyph; + } else if ( tc != -3 ) + continue; /* nothing to display */ + /* no hash table or no replacement -- + * hope for the best */ + if ( c & ~charmask ) + tc = '?'; + else + tc = c; } - if (tc & ~charmask) - continue; /* Conversion failed */ +display_glyph: if (vc->vc_need_wrap || vc->vc_irm) FLUSH if (vc->vc_need_wrap) { @@ -1368,6 +1447,15 @@ vc->vc_x++; draw_to = (vc->vc_pos += 2); } + if (vc->vc_utf_count) { + if (vc->vc_npar) { + vc->vc_npar--; + goto display_glyph; + } + vc->vc_utf_count = 0; + c = orig; + goto rescan_last_byte; + } continue; } FLUSH @@ -1376,6 +1464,8 @@ FLUSH console_conditional_schedule(); release_console_sem(); + +out: return n; #undef FLUSH } @@ -1390,7 +1480,7 @@ struct vc_data *vc = tty->driver_data; int ret = 0; - if (tty->count == 1) { + if (tty->driver_data == NULL) { acquire_console_sem(); ret = tty->index; vc = vc_allocate(ret); @@ -1402,7 +1492,7 @@ tty->winsize.ws_row = vc->vc_rows; tty->winsize.ws_col = vc->vc_cols; } - vcs_make_devfs(tty); + vcs_make_sysfs(tty); } release_console_sem(); } @@ -1410,15 +1500,15 @@ } /* - * We take tty_sem in here to prevent another thread from coming in via init_dev + * We take tty_mutex in here to prevent another thread from coming in via init_dev * and taking a ref against the tty while we're in the process of forgetting * about it and cleaning things up. * - * This is because vcs_remove_devfs() can sleep and will drop the BKL. + * This is because vcs_remove_sysfs() can sleep and will drop the BKL. */ static void vt_close(struct tty_struct *tty, struct file * filp) { - down(&tty_sem); + mutex_lock(&tty_mutex); acquire_console_sem(); if (tty && tty->count == 1) { struct vc_data *vc = tty->driver_data; @@ -1426,16 +1516,16 @@ vc->vc_tty = NULL; tty->driver_data = NULL; release_console_sem(); - vcs_remove_devfs(tty); - up(&tty_sem); + vcs_remove_sysfs(tty); + mutex_unlock(&tty_mutex); /* - * tty_sem is released, but we still hold BKL, so there is + * tty_mutex is released, but we still hold BKL, so there is * still exclusion against init_dev() */ return; } release_console_sem(); - up(&tty_sem); + mutex_unlock(&tty_mutex); } static int vt_write(struct tty_struct * tty, const unsigned char *buf, int count) @@ -1676,7 +1766,9 @@ ret = paste_selection(tty); break; case TIOCL_UNBLANKSCREEN: + acquire_console_sem(); unblank_screen(); + release_console_sem(); break; case TIOCL_SELLOADLUT: ret = sel_loadlut(p); @@ -1701,6 +1793,10 @@ return -EFAULT; vc->display_fg->blank_mode = (data < 4) ? data : 0; break; + case TIOCL_GETKMSGREDIRECT: + data = kmsg_redirect; + ret = __put_user(data, p); + break; case TIOCL_SETKMSGREDIRECT: if (!capable(CAP_SYS_ADMIN)) { ret = -EPERM; @@ -1723,8 +1819,10 @@ } break; case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */ + acquire_console_sem(); ignore_poke = 1; do_blank_screen(vc->display_fg, 0); + release_console_sem(); break; case TIOCL_BLANKEDSCREEN: ret = vc->display_fg->vt_blanked; @@ -1822,7 +1920,7 @@ console_initcall(vt_console_init); -static struct tty_operations vt_ops = { +static const struct tty_operations vt_ops = { .open = vt_open, .close = vt_close, .write = vt_write, @@ -1848,7 +1946,6 @@ if (!console_driver) panic("Couldn't allocate VT console driver\n"); console_driver->owner = THIS_MODULE; - console_driver->devfs_name = "vc/"; console_driver->name = "tty"; console_driver->name_base = 1; console_driver->major = TTY_MAJOR; @@ -1881,14 +1978,13 @@ * and become default driver for newly opened ones. */ -int take_over_console(struct vt_struct *vt, const struct consw *csw) +static int bind_vt_driver(struct vt_struct *vt, const struct consw *csw) { struct vc_data *vc = vt->fg_console; - struct module *owner; - const char *desc; + struct module *owner = csw->owner; + const char *desc = NULL; int i; - owner = csw->owner; if (!try_module_get(owner)) return -ENODEV; @@ -1930,7 +2026,9 @@ vc->vc_visible_origin = vc->vc_origin; vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size; vc->vc_pos = vc->vc_origin + vc->vc_size_rows * vc->vc_y + 2 * vc->vc_x; + INIT_WORK(&vc->SAK_work, vc_SAK); visual_init(vc, 0); + set_origin(vc); update_attr(vc); /* If the console changed between mono <-> color, then @@ -1962,6 +2060,7 @@ EXPORT_SYMBOL(default_grn); EXPORT_SYMBOL(default_blu); EXPORT_SYMBOL(vc_resize); +EXPORT_SYMBOL(vc_lock_resize); EXPORT_SYMBOL(console_blank_hook); EXPORT_SYMBOL(vt_list); EXPORT_SYMBOL(take_over_console); Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c 2007-04-11 20:19:34 UTC (rev 2372) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_ioctl.c 2007-04-14 23:31:33 UTC (rev 2373) @@ -236,7 +236,7 @@ ret = -ENOMEM; goto reterr; } - + /* we mostly copy too much here (512bytes), but who cares ;) */ if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) { ret = -EFAULT; @@ -254,9 +254,9 @@ if (p) for ( ; *p && sz; p++, sz--) if (put_user(*p, up++)) { - ret = -EFAULT; + ret = -EFAULT; goto reterr; - } + } if (put_user('\0', up)) { ret = -EFAULT; goto reterr; @@ -271,7 +271,7 @@ q = func_table[i]; first_free = funcbufptr + (funcbufsize - funcbufleft); for (j = i + 1; j < MAX_NR_FUNC && !func_table[j]; j++); - + if (j < MAX_NR_FUNC) fj = func_table[j]; else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jsi...@us...> - 2007-05-11 13:14:42
|
Revision: 2379 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2379&view=rev Author: jsimmons Date: 2007-05-11 06:14:40 -0700 (Fri, 11 May 2007) Log Message: ----------- Move from proc to sysfs only Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/drivers/char/Makefile branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/Makefile =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/Makefile 2007-05-11 13:14:20 UTC (rev 2378) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/Makefile 2007-05-11 13:14:40 UTC (rev 2379) @@ -13,7 +13,7 @@ obj-$(CONFIG_UNIX98_PTYS) += pty.o obj-y += misc.o obj-$(CONFIG_VT) += vt_ioctl.o decvte.o vc_screen.o consolemap.o \ - consolemap_deftbl.o selection.o keyboard.o vt_proc.o vt_sysfs.o + consolemap_deftbl.o selection.o keyboard.o vt_sysfs.o obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o obj-$(CONFIG_ESPSERIAL) += esp.o Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-05-11 13:14:20 UTC (rev 2378) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-05-11 13:14:40 UTC (rev 2379) @@ -129,9 +129,6 @@ #if defined (CONFIG_PROM_CONSOLE) extern void prom_con_init(void); #endif -#ifdef CONFIG_PROC_FS -extern int vt_proc_init(void); -#endif struct tty_driver *console_driver; /* TTY driver for all VT consoles */ static unsigned int current_vc; /* Which /dev/vc/X to allocate next */ @@ -1851,9 +1848,6 @@ current_vt += 1; if (vt->kmalloced) { vt_init_device(vt); -#ifdef CONFIG_PROC_FS - vt_proc_attach(vt); -#endif } return display_desc; } @@ -1924,9 +1918,6 @@ panic("Couldn't register console driver\n"); vt_sysfs_init(); -#ifdef CONFIG_PROC_FS - vt_proc_init(); -#endif #if defined (CONFIG_PROM_CONSOLE) prom_con_init(); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |