[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