[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Mint 1.11 beta: ikill(), more diffs



ok i patched some more races. :)  i have also added ECHOCTL to sg_flags
(and termios) so e.g. mgetty can turn it off and won't echo the \r after
your login name as ^M...

1. use systemcall pc instead of flag to detect return from signal handler

Index: signal.c
@@ -528,10 +528,10 @@
  * is finished a handler, and we should not only restore the stack
  * frame but also the old context we were working in (which is on the
  * system call stack -- see handle_sig).
- * The "valid_return" variable is 0 in the first case, 1 in the second.
+ * The syscall pc is == pc_valid_return in the second case.
  */
 
-short valid_return;
+extern void *pc_valid_return;
 
 long ARGS_ON_STACK
 p_sigreturn()
@@ -558,14 +558,13 @@
 	curproc->sysstack = frame[1];	/* restore frame */
 	curproc->sigmask &= ~(1L<<sig); /* unblock signal */
 
-	if (!valid_return) {
+	if (curproc->ctxt[SYSCALL].pc != (long)&pc_valid_return) {
 /* here, the user is telling us that a longjmp out of a signal handler is
  * about to occur; so we should unwind *all* the signal frames
  */
 		goto top;
 	}
 	else {
-		valid_return = 0;
 		oldctxt = (CONTEXT *) (((long)&frame[2]) + 0x40);
 		if (oldctxt->regs[0] != CTXT_MAGIC) {
 			FATAL("p_sigreturn: corrupted context");
Index: syscall.spp
@@ -348,12 +348,12 @@
 ;    (sp)      (long) signal number -- was a parameter for user routine
 ;
 	XDEF	_sig_return
-	XREF	_valid_return
+	XDEF	_pc_valid_return
 _sig_return:
 	addq.w	#8,sp			; pop signal number and sfmt
 	move.w	#$11a,-(sp)		; Psigreturn() system call
-	move.w	#1,_valid_return	; tell kernel it's us!
 	trap	#1
+_pc_valid_return:			; tells kernel it's us
 ; we had better not come back; if we did, something terrible
 ; happened, and we might as well terminate
 	move.w	#-998,-(sp)
Index: dosmem.c
@@ -1399,7 +1399,7 @@
  * all signals.
  */
 	sigmask = curproc->sigmask;
-	curproc->sigmask = ~((unsigned long)1 << SIGKILL);
+	curproc->sigmask = ~(((unsigned long)1 << SIGKILL) | 1);
 
 	{ short sr = spl7();
 	add_q(READY_Q, p);		/* put it on the ready queue */

2. reload sp from curproc->sysstack before calling sleep or check_sigs
after unwound stack (p_sigreturn).  this may well be a reason for those
GEM/update crashes...  and move/add some spl7() because interrupts can
put a process on READY_Q anytime, and stay less time at ipl7 in sleep

Index: syscall.spp
@@ -57,6 +57,7 @@
 	XREF	_enter_kernel
 	XREF	_leave_kernel
 	XREF	_preempt
+	XREF	_unwound_stack
 
 	XREF	_curproc
 	XREF	_bios_tab,_bios_max
@@ -304,6 +305,11 @@
 	tst.w	($43e).w		; test floppy disk lock variable
 	bne.s	nosleep			; if locked, can't switch
 sleep:
+	tst.l	_unwound_stack		; did we unwind sysstack?
+	beq.s	noreload1
+	move.l	_curproc,a0		; then reload it before
+	move.l	(a0),sp			; doing anything further
+noreload1:
 	jsr	_preempt		; does a sleep(READY_Q)
 	bra.s	nosig
 
@@ -312,9 +318,20 @@
 	not.l	d0
 	and.l	P_SIGPENDING(a0),d0
 	beq.s	nosig
+	tst.l	_unwound_stack		; did we unwind sysstack?
+	beq.s	noreload2
+	move.l	_curproc,a0		; then reload it before
+	move.l	(a0),sp			; doing anything further
+noreload2:
 	jsr	_check_sigs
 nosig:
 	ori.w	#$0700,sr		; spl7()
+%ifdef ONLY030
+	clr.l	_unwound_stack
+%else
+	moveq	#0,d0
+	move.l	d0,_unwound_stack
+%endif
 	jsr	_leave_kernel		; restore vectors
 	move.l	_curproc,a0
 	pea	4(a0)
Index: signal.c
@@ -60,6 +60,7 @@
 	int sig;
 {
 	ulong sigm;
+	short sr;
 
 /* if process is ignoring this signal, do nothing
  * also: signal 0 is SIGNULL, and should never be delivered through
@@ -89,12 +90,12 @@
 		return;
 
 /* otherwise, make sure the process is awake */
+	sr = spl7();
 	if (p->wait_q && p->wait_q != READY_Q) {
-		short sr = spl7();
 		rm_q(p->wait_q, p);
 		add_q(READY_Q, p);
-		spl(sr);
 	}
+	spl(sr);
 }
 
 /*
@@ -305,7 +306,7 @@
  * handle_sig: do whatever is appropriate to handle a signal
  */
 
-static long unwound_stack = 0;
+long unwound_stack = 0;
 
 struct sigcontext
 {
@@ -492,6 +493,7 @@
  * so better set it up with interrupts off...  -nox */
 				stack = (long *) newstack;
 			spl7();
+			unwound_stack = 0;
 			curproc->sysstack = (long) stack;
 			++stack;
 			*stack++ = FRAME_MAGIC;
@@ -565,6 +567,7 @@
 		goto top;
 	}
 	else {
+		unwound_stack = 0;
 		oldctxt = (CONTEXT *) (((long)&frame[2]) + 0x40);
 		if (oldctxt->regs[0] != CTXT_MAGIC) {
 			FATAL("p_sigreturn: corrupted context");
Index: proc.c
@@ -321,11 +321,13 @@
 	PROC *p;
 	int slices;
 {
+	short sr = spl7();
 	p->slices = -slices;
 	p->curpri = MAX_NICE;
 	p->wait_q = READY_Q;
 	p->q_next = sys_q[READY_Q];
 	sys_q[READY_Q] = p;
+	spl(sr);
 }
 
 void
@@ -556,6 +558,10 @@
 		curproc->wait_cond = cond;
 	add_q(que, curproc);
 
+/* alright curproc is on que now...  maybe there's an interrupt pending
+ * that will wakeselect or signal someone
+ */
+	spl(sr);
 	if (!sys_q[READY_Q]) {
 /* hmm, no-one is ready to run. might be a deadlock, might not.
  * first, try waking up any napping processes; if that doesn't work,
@@ -563,12 +569,15 @@
  * to.
  */
 		wake(SELECT_Q, (long)nap);
+		sr = spl7();
 		if (!sys_q[READY_Q]) {
 			p = rootproc;		/* pid 0 */
 			rm_q(p->wait_q, p);
 			add_q(READY_Q, p);
 		}
+		spl(sr);
 	}
+	sr = spl7();
 
 /*
  * Walk through the ready list, to find what process should run next.
@@ -605,6 +614,8 @@
 
 	rm_q(READY_Q, p);
 
+	spl(sr);
+
 	if (save_context(&(curproc->ctxt[CURRENT]))) {
 /*
  * restore per-process variables here
@@ -628,11 +639,13 @@
 		curproc->logbase = *((void **)0x44eL);
 #endif
 
+#if 0
 /*
  * kay: We were at spl7 when doing the save_context(). Correct this.
  */
 	curproc->ctxt[CURRENT].sr &= ~0x0700;
 	curproc->ctxt[CURRENT].sr |= sr & 0x0700;
+#endif
 	curproc->ctxt[CURRENT].regs[0] = 1;
 	curproc = p;
 	proc_clock = TIME_SLICE;	/* fresh time */
@@ -664,14 +677,22 @@
 	if (sleepcond == cond)
 		sleepcond = 0;
 top:
-	for(p = sys_q[que]; p; p = p->q_next) {
-		if (p->wait_cond == cond) {
-			short s = spl7();
-			rm_q(que, p);
-			add_q(READY_Q, p);
+	for(p = sys_q[que]; p;) {
+		short s = spl7();
+		PROC *q;
+
+/* check p is still on the right queue, maybe an interrupt just woke it... */
+		if (p->wait_q != que) {
 			spl(s);
 			goto top;
 		}
+		q = p;
+		p = p->q_next;
+		if (q->wait_cond == cond) {
+			rm_q(que, q);
+			add_q(READY_Q, q);
+		}
+		spl(s);
 	}
 }
 
Index: dosmem.c
@@ -671,13 +671,13 @@
 			if (text) text->links--;
 			/* let our parent run, if it Vfork'd() */
 			if ( (p = pid2proc(curproc->ppid)) != 0 ) {
+				short sr = spl7();
 				if (p->wait_q == WAIT_Q && 
 				    p->wait_cond == (long)curproc) {
-					short sr = spl7();
 					rm_q(WAIT_Q, p);
 					add_q(READY_Q, p);
-					spl(sr);
 				}
+				spl(sr);
 			}
 
 		/* OK, let's run our new code */
@@ -766,6 +766,7 @@
 	virtaddr *hold_addr;
 	int  i, wakemint = 0;
 	DIR *dirh, *nexth;
+	short sr;
 	extern short bconbsiz;	/* in bios.c */
 
 	if (bconbsiz)
@@ -946,14 +947,15 @@
  * structure), and also processes that are ignoring SIGCHLD but are
  * waiting for us.
  */
+	sr = spl7();
 	if (p->wait_q == WAIT_Q && 
 	    (p->wait_cond == (long)curproc || p->wait_cond == (long)p_waitpid) ) {
-		short sr = spl7();
-		TRACE(("terminate: waking up parent"));
 		rm_q(WAIT_Q, p);
 		add_q(READY_Q, p);
 		spl(sr);
+		TRACE(("terminate: waking up parent"));
 	}
+	spl(sr);
 	if (curproc->ptracer && curproc->ptracer != p) {
 		/* BUG: should we ensure curproc->ptracer is awake ? */
 		post_sig(curproc->ptracer, SIGCHLD);	/* tell tracing process */
@@ -986,13 +988,13 @@
 	}
 
 	if (wakemint) {
+		short sr = spl7();
 		p = rootproc;		/* pid 0 */
 		if (p->wait_q == WAIT_Q) {
-			short sr = spl7();
 			rm_q(WAIT_Q, p);
 			add_q(READY_Q, p);
-			spl(sr);
 		}
+		spl(sr);
 	}
 
 /* this makes sure that our children are inherited by the system;
Index: main.c
@@ -551,12 +551,12 @@
 	for (p = proclist; p; p = p->gl_next) {
 		if (p->pid == 0) continue;
 		if (p->wait_q != ZOMBIE_Q && p->wait_q != TSR_Q) {
+			short sr = spl7();
 			if (p->wait_q != READY_Q) {
-				short sr = spl7();
 				rm_q(p->wait_q, p);
 				add_q(READY_Q, p);
-				spl(sr);
 			}
+			spl(sr);
 			post_sig(p, SIGTERM);
 			proc_left++;
 		}
Index: rendez.c
@@ -174,21 +174,22 @@
 	    p->mb_mode = 0;
 	}
 	else {
+	    short sr = spl7();
 	    /* The blocked write was in mode 1: writer wakes up */
 	    p->mb_writer = curproc->pid;	/* tell writer reader's pid */
 	    p->mb_mode = -1;			/* mark rendezvous */
 	    p->wait_cond = 0;			/* not necessary? */
 	    if (p->wait_q != READY_Q) {
-	        short sr = spl7();
 		/* wake up the writer if it is sleeping */
 		rm_q(p->wait_q,p);
 		add_q(READY_Q,p);
-		spl(sr);
 	    }
+	    spl(sr);
 	}
 	return 0;
     }
     else {
+	short sr = spl7();
 	/* curproc is writing */
 	p->mb_writer = curproc->pid;		/* provide the PID */
 	p->mb_long1 = *(long *)(ptr);		/* copy the message */
@@ -196,12 +197,11 @@
 	p->mb_mode = -1;			/* mark rendezvous */
 	p->wait_cond = 0;			/* not necessary? */
 	if (p->wait_q != READY_Q) {
-	    short sr = spl7();
 	    /* wake up the reader if it is sleeping */
 	    rm_q(p->wait_q,p);
 	    add_q(READY_Q,p);
-	    spl(sr);
 	}
+	spl(sr);
 	if (mode == 2) {
 	    /* now curproc becomes a reader */
 	    mbid = 0xFFFF0000L | curproc->pid;
@@ -306,15 +306,16 @@
 unsemame(p)
 PROC *p;
 {
+    short sr;
     /* take process P off the WAIT_Q and put it on the READY_Q */
     TRACE(("semaphore sleep ends for pid %d",p->pid));
+    sr = spl7();
     if (p->wait_q == WAIT_Q) {
-	    short sr = spl7();
 	    rm_q(WAIT_Q,p);
 	    add_q(READY_Q,p);
-	    spl(sr);
     }
     p->wait_cond = 0;
+    spl(sr);
 }
 
 long ARGS_ON_STACK
Index: timeout.c
@@ -428,13 +428,13 @@
 unnapme(p)
 	PROC *p;
 {
+	short sr = spl7();
 	if (p->wait_q == SELECT_Q && p->wait_cond == (long)nap) {
-		short sr = spl7();
 		rm_q(SELECT_Q, p);
 		add_q(READY_Q, p);
-		spl(sr);
 		p->wait_cond = 0;
 	}
+	spl(sr);
 }
 
 void ARGS_ON_STACK 

3. mint.cnf: let AUX really work like Bconmap

Index: main.c
@@ -1255,10 +1255,21 @@
 
 		f = do_open(val, O_RDWR|O_CREAT|O_TRUNC, 0, (XATTR *)0);
 		if (f) {
+			extern FILESYS bios_filesys;
+			extern DEVDRV bios_tdevice;
+
 			do_close (curproc->handle[2]);
 			do_close (curproc->aux);
 			curproc->aux = curproc->handle[2] = f;
 			f->links = 2;
+			if (is_terminal(f) && f->fc.fs == &bios_filesys &&
+			    f->dev == &bios_tdevice &&
+			    (has_bconmap ? (f->fc.aux>=6) : (f->fc.aux==1))) {
+				if (has_bconmap)
+					curproc->bconmap = f->fc.aux;
+				((struct tty *)f->devinfo)->aux_cnt++;
+				f->pos = 1;
+			}
 		}
 		return;
 	}

4. ECHOCTL, default is still on...  and fix TS_COOKED after echo reads

Index: file.h
@@ -493,7 +493,9 @@
 #define T_TOSTOP	0x0100
 #define T_XKEY		0x0200		/* Fread returns escape sequences for
 					   cursor keys, etc. */
-/* 0x0400 and 0x0800 still available */
+#define T_ECHOCTL	0x0400		/* echo ctl chars as ^x */
+
+/* 0x0800 still available */
 #define T_TANDEM	0x1000
 #define T_RTSCTS	0x2000
 #define T_EVENP		0x4000		/* EVENP and ODDP are mutually exclusive */
Index: tty.c
@@ -19,7 +19,7 @@
 #define TIOCSSOFTCAR	(('T'<< 8) | 101)
 #endif
 
-static void _erase P_((FILEPTR *, int));
+static void _erase P_((FILEPTR *, int, int));
 static int escseq P_((struct tty *, int));
 
 /* setting a special character to this value disables it */
@@ -42,7 +42,7 @@
 	13, 13,			/* input speed == output speed == 9600 baud */
 	CTRL('H'),		/* erase */
 	CTRL('U'),		/* kill */
-	T_ECHO|T_CRMOD|T_TOSTOP|T_XKEY, /* flags */
+	T_ECHO|T_CRMOD|T_TOSTOP|T_XKEY|T_ECHOCTL, /* flags */
 	},
 	{
 	CTRL('C'),		/* interrupt */
@@ -73,9 +73,9 @@
 #define _put(f, c) (tty_putchar((f), (c), RAW))
 
 static void
-_erase(f, c)
+_erase(f, c, mode)
 	FILEPTR *f;
-	int c;
+	int c, mode;
 {
 	_put(f, '\010');
 	_put(f, ' ');
@@ -84,13 +84,13 @@
 /* BUG: \t is messed up. We really need to keep track of the output
  * column
  */
-	if (c >= 0 && c < ' ' && c != '\t') {
+	if ((mode & T_ECHOCTL) && c >= 0 && c < ' ' && c != '\t') {
 		_put(f, '\010'); _put(f, ' '); _put(f, '\010');
 	}
 }
 
 #define put(f, c)   { if (mode & T_ECHO) _put(f, c); }
-#define erase(f, c) { if (mode & T_ECHO) _erase(f, c); }
+#define erase(f, c) { if (mode & T_ECHO) _erase(f, c, mode); }
 
 long
 tty_read(f, buf, nbytes)
@@ -122,7 +122,7 @@
 	}
 	else {
 		rdmode = COOKED|NOECHO;
-		mode = T_TOS | T_ECHO;
+		mode = T_TOS | T_ECHO | T_ECHOCTL;
 	}
 
 	if (nbytes == 0) return bytes_read;
@@ -248,9 +248,15 @@
 				continue;
 			}
 			else if ((char)ch == tty->ltc.t_lnextc) {
-				put(f, '^');
-				put(f, '\b');
+				if (mode & T_ECHOCTL) {
+					put(f, '^');
+					put(f, '\b');
+				}
 				r = tty_getchar(f, RAW);
+				if (rdmode & COOKED)
+					tty->state |= TS_COOKED;
+				else
+					tty->state &= ~TS_COOKED;
 				if (r < 0)
 					goto tty_error;
 				else if (r == MiNTEOF)
@@ -289,6 +295,10 @@
 					put(f, '\n');
 					bytes_read++;
 				}
+				if (rdmode & COOKED)
+					tty->state |= TS_COOKED;
+				else
+					tty->state &= ~TS_COOKED;
 				return bytes_read;
 			}
 
@@ -297,7 +307,8 @@
 /* do the following for both RAW and COOKED mode */
 stuff_it:
 		*ptr++ = ch;
-		if (ch < ' ' && ch != '\t') {	/* ch is unsigned */
+		if ((mode & T_ECHOCTL) &&
+		    ch < ' ' && ch != '\t') {	/* ch is unsigned */
 			put(f, '^'); put(f, ch+'@');
 		}
 		else
@@ -313,6 +324,10 @@
 		}	
 	}
 
+	if (rdmode & COOKED)
+		tty->state |= TS_COOKED;
+	else
+		tty->state &= ~TS_COOKED;
 	return bytes_read;
 }
 
and ECHOCTL for mintlib:

Index: usr/include/termios.h
@@ -21,6 +21,10 @@
 #define NCCS	(VFLUSHO + 1)
 
 /* Canonical values for control characters. */
+#ifndef _POSIX_VDISABLE
+#define _POSIX_VDISABLE ((unsigned char) 0)
+#endif
+
 #ifndef CEOF
 #define	CEOF	('d' & 0x1f)
 #endif
@@ -124,6 +128,7 @@
 #define IEXTEN	0x0080
 #ifndef _IOCTL_H
 #define TOSTOP	0x0100
+#define ECHOCTL	0x0400
 #endif /* _IOCTL_H */
 
 /* actions for tcflow() */
Index: usr/include/ioctl.h
@@ -190,6 +190,7 @@
 #define NOFLSH		0x0040
 #ifdef __MINT__
 #define TOSTOP		0x0100
+#define ECHOCTL		0x0400
 #endif /* __MINT__ */
 #endif /* _TERMIOS_H */
 #define TANDEM		0x1000
Index: tcattr.c
@@ -67,7 +67,7 @@
 			| ((sg.sg_flags & RTSCTS) ? CRTSCTS : 0)
 			| ((sg.sg_flags & EVENP) ? PARENB : 0)
 			| ((sg.sg_flags & ODDP) ? (PARENB | PARODD) : 0));
-  stp->c_lflag = (tcflag_t) ((sg.sg_flags & (TOSTOP | NOFLSH))
+  stp->c_lflag = (tcflag_t) ((sg.sg_flags & (TOSTOP | NOFLSH | ECHOCTL))
 			| ((sg.sg_flags & ECHO) ? (ECHO | ECHOE | ECHOK) : 0)
 			| ((sg.sg_flags & XKEY) ? IEXTEN : 0)
 			| ((sg.sg_flags & RAW)
@@ -124,7 +124,7 @@
     return -1;
   }
   sg.sg_flags &= ~(CRMOD | TANDEM | RTSCTS | EVENP | ODDP | TOSTOP 
-			| NOFLSH | RAW | CBREAK | ECHO | XKEY);
+			| NOFLSH | ECHOCTL | RAW | CBREAK | ECHO | XKEY);
   sg.sg_flags |= (((stp->c_iflag & ICRNL) ? CRMOD : 0)
 			| (((stp->c_iflag & (IXON | IXOFF)) == (IXON | IXOFF)) ? TANDEM : 0)
 			| ((stp->c_cflag & CRTSCTS) ? RTSCTS : 0));
@@ -136,7 +136,7 @@
   sg.sg_flags |= ((stp->c_cflag & PARENB)
 			? ((stp->c_cflag & PARODD) ? ODDP : EVENP)
 			: 0);
-  sg.sg_flags |= ((stp->c_lflag & (TOSTOP | NOFLSH | ECHO))
+  sg.sg_flags |= ((stp->c_lflag & (TOSTOP | NOFLSH | ECHOCTL | ECHO))
 			| ((stp->c_lflag & IEXTEN) ? XKEY : 0)
 			| ((stp->c_lflag & ISIG)
 			   ? (stp->c_lflag & ICANON ? 0 : CBREAK) : RAW));
-- 
J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
								...ohne Gewehr
PGP public key fingerprint =  8A 18 58 54 03 7B FC 12  1F 8B 63 C7 19 27 CF DA