aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Benedict Torvalds <torvalds@klaava.Helsinki.FI>1992-05-24 11:46:43 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:04 -0400
commit46d255794351e97e7b06958d2859b6ec7c373f73 (patch)
treee05f50c73ea148da4276f0343999a3038f913ddb
parent8404560378fc29692399a65c34d39d80699f7288 (diff)
downloadarchive-46d255794351e97e7b06958d2859b6ec7c373f73.tar.gz
linux-0.96a.patch1v0.96a-pl1
Here is the patch to 0.96a that corrects the harddisk error bug, dup2() and X11 text-mode restoration. Thanks to Rick Sladkey for finding the dup2() bug. This patch has also been sent to the ftp-archives. Linus
-rw-r--r--fs/fcntl.c2
-rw-r--r--include/linux/tty.h2
-rw-r--r--kernel/blk_drv/blk.h42
-rw-r--r--kernel/blk_drv/hd.c14
-rw-r--r--kernel/chr_drv/console.c15
-rw-r--r--kernel/chr_drv/vt.c13
6 files changed, 54 insertions, 34 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 952bf8c..bf2861d 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -37,6 +37,8 @@ static int dupfd(unsigned int fd, unsigned int arg)
int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
+ if (oldfd >= NR_OPEN || !current->filp[oldfd])
+ return -EBADF;
if (newfd == oldfd)
return newfd;
sys_close(newfd);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 57c3b58..82dd517 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -195,6 +195,8 @@ extern void serial_open(unsigned int line);
void copy_to_cooked(struct tty_struct * tty);
void update_screen(int new_console);
+void blank_screen(void);
+void unblank_screen(void);
int kill_pg(int pgrp, int sig, int priv);
diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h
index 40a5925..1bc455c 100644
--- a/kernel/blk_drv/blk.h
+++ b/kernel/blk_drv/blk.h
@@ -149,26 +149,6 @@ extern inline void unlock_buffer(struct buffer_head * bh)
wake_up(&bh->b_wait);
}
-extern inline void next_buffer(int uptodate)
-{
- struct buffer_head *tmp;
-
- CURRENT->bh->b_uptodate = uptodate;
- unlock_buffer(CURRENT->bh);
- if (!uptodate) {
- printk(DEVICE_NAME " I/O error\n\r");
- printk("dev %04x, block %d\n\r",CURRENT->dev,
- CURRENT->bh->b_blocknr);
- }
- tmp = CURRENT->bh;
- CURRENT->bh = CURRENT->bh->b_reqnext;
- tmp->b_reqnext = NULL;
- if (!CURRENT->bh)
- panic("next_buffer: request buffer list destroyed\r\n");
- CURRENT->buffer = CURRENT->bh->b_data;
- CURRENT->errors = 0;
-}
-
extern inline void end_request(int uptodate)
{
struct request * tmp;
@@ -190,6 +170,28 @@ extern inline void end_request(int uptodate)
wake_up(&wait_for_request);
}
+extern inline void next_buffer(int uptodate)
+{
+ struct buffer_head *tmp;
+
+ tmp = CURRENT->bh;
+ CURRENT->bh = tmp->b_reqnext;
+ tmp->b_reqnext = NULL;
+ tmp->b_uptodate = uptodate;
+ unlock_buffer(tmp);
+ if (!uptodate) {
+ printk(DEVICE_NAME " I/O error\n\r");
+ printk("dev %04x, block %d\n\r",tmp->b_dev, tmp->b_blocknr);
+ }
+ if (!CURRENT->bh) {
+ printk("next_buffer: request buffer list destroyed\r\n");
+ end_request(0);
+ return;
+ }
+ CURRENT->buffer = CURRENT->bh->b_data;
+ CURRENT->errors = 0;
+}
+
#ifdef DEVICE_INTR
#define CLEAR_INTR SET_INTR(NULL)
#else
diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c
index 43ce9b7..6244567 100644
--- a/kernel/blk_drv/hd.c
+++ b/kernel/blk_drv/hd.c
@@ -424,7 +424,12 @@ static void bad_rw_intr(void)
return;
if (++CURRENT->errors >= MAX_ERRORS)
if (CURRENT->bh && CURRENT->nr_sectors > 2) {
- CURRENT->nr_sectors &= ~1;
+ CURRENT->nr_sectors--;
+ CURRENT->sector++;
+ if (CURRENT->nr_sectors & 1) {
+ CURRENT->nr_sectors--;
+ CURRENT->sector++;
+ }
next_buffer(0);
} else
end_request(0);
@@ -530,7 +535,12 @@ static void hd_times_out(void)
cli();
if (++CURRENT->errors >= MAX_ERRORS)
if (CURRENT->bh && CURRENT->nr_sectors > 2) {
- CURRENT->nr_sectors &= ~1;
+ CURRENT->nr_sectors--;
+ CURRENT->sector++;
+ if (CURRENT->nr_sectors & 1) {
+ CURRENT->nr_sectors--;
+ CURRENT->sector++;
+ }
next_buffer(0);
} else
end_request(0);
diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c
index 824f1ad..8709a22 100644
--- a/kernel/chr_drv/console.c
+++ b/kernel/chr_drv/console.c
@@ -56,9 +56,6 @@
INIT_C_CC \
}
-static void blank_screen(void);
-static void unblank_screen(void);
-
/*
* These are set up by the setup-routine at boot-time:
*/
@@ -223,7 +220,7 @@ static inline void set_origin(int currcons)
{
if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
return;
- if (currcons != fg_console)
+ if (currcons != fg_console || vt_cons[currcons].vt_mode == KD_GRAPHICS)
return;
cli();
outb_p(12, video_port_reg);
@@ -584,10 +581,6 @@ void con_write(struct tty_struct * tty)
printk("con_write: illegal tty\n\r");
return;
}
- if (vt_cons[currcons].vt_mode == KD_GRAPHICS) {
- flush(tty->write_q);
- return; /* no output in graphics mode */
- }
while (!tty->stopped && (c = GETCH(tty->write_q)) >= 0) {
if (c == 24 || c == 26)
state = ESnormal;
@@ -834,8 +827,10 @@ void con_write(struct tty_struct * tty)
state = ESnormal;
}
}
- set_cursor(currcons);
timer_active &= ~(1<<BLANK_TIMER);
+ if (vt_cons[currcons].vt_mode == KD_GRAPHICS)
+ return;
+ set_cursor(currcons);
if (currcons == fg_console)
if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0;
@@ -1129,8 +1124,6 @@ void console_print(const char * b)
if (currcons<0 || currcons>=NR_CONSOLES)
currcons = 0;
- if (vt_cons[currcons].vt_mode == KD_GRAPHICS)
- return; /* no output in graphics mode */
while (c = *(b++)) {
if (c == 10) {
cr(currcons);
diff --git a/kernel/chr_drv/vt.c b/kernel/chr_drv/vt.c
index 8bac0fe..0514601 100644
--- a/kernel/chr_drv/vt.c
+++ b/kernel/chr_drv/vt.c
@@ -15,6 +15,7 @@
#include <linux/sched.h>
#include <linux/tty.h>
+#include <linux/timer.h>
#include <linux/kernel.h>
#include "vt_kern.h"
@@ -121,7 +122,17 @@ vt_ioctl(struct tty_struct *tty, int dev, int cmd, int arg)
default:
return -EINVAL;
}
- vt_cons[console].vt_mode = arg;
+ if (vt_cons[console].vt_mode == (unsigned char) arg)
+ return 0;
+ vt_cons[console].vt_mode = (unsigned char) arg;
+ if (console != fg_console)
+ return 0;
+ if (arg == KD_TEXT)
+ unblank_screen();
+ else {
+ timer_active &= 1<<BLANK_TIMER;
+ blank_screen();
+ }
return 0;
case KDGETMODE:
verify_area((void *) arg, sizeof(unsigned long));