#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/syslog.h>
+#include <sys/user.h>
+#include <sys/signalvar.h>
#include <sys/signalvar.h>
#ifndef NeXT
#include <sys/resourcevar.h>
register struct tty *tp;
{
int s;
+ boolean_t funnel_state;
+ funnel_state = thread_funnel_set(kernel_flock, TRUE);
s = spltty();
tp->t_dev = device;
if (!ISSET(tp->t_state, TS_ISOPEN)) {
#endif /* !NeXT */
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
register struct proc *p = curproc; /* XXX */
#endif
int s, error;
+ struct uthread *ut;
+ ut = (struct uthread *)get_bsdthread_info(current_act());
/* If the ioctl involves modification, hang if in the background. */
switch (cmd) {
case TIOCFLUSH:
while (isbackground(p, tp) &&
(p->p_flag & P_PPWAIT) == 0 &&
(p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
- (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
+ (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
if (p->p_pgrp->pg_jobc == 0)
return (EIO);
pgsignal(p->p_pgrp, SIGTTOU, 1);
tp->t_pgrp = p->p_pgrp;
p->p_session->s_ttyp = tp;
p->p_flag |= P_CONTROLT;
+ /* The backgrounded process blocking on tty now
+ * could be foregound process. Wake such processes
+ */
+ tty_pgsignal(tp->t_pgrp, SIGCONT);
break;
case TIOCSPGRP: { /* set pgrp of tty */
register struct pgrp *pgrp = pgfind(*(int *)data);
else if (pgrp == NULL || pgrp->pg_session != p->p_session)
return (EPERM);
tp->t_pgrp = pgrp;
+ /* The backgrounded process blocking on tty now
+ * could be foregound process. Wake such processes
+ */
+ tty_pgsignal(tp->t_pgrp, SIGCONT);
break;
}
case TIOCSTAT: /* simulate control-T */
}
int
-ttyselect(tp, rw, p)
+ttyselect(tp, rw, wql, p)
struct tty *tp;
int rw;
+ void * wql;
struct proc *p;
{
int s;
case FREAD:
if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
goto win;
- selrecord(p, &tp->t_rsel);
+ selrecord(p, &tp->t_rsel, wql);
break;
case FWRITE:
if ((tp->t_outq.c_cc <= tp->t_lowat &&
win: splx(s);
return (1);
}
- selrecord(p, &tp->t_wsel);
+ selrecord(p, &tp->t_wsel, wql);
break;
}
splx(s);
* cdevsw. It relies on a proper xxxdevtotty routine.
*/
int
-ttselect(dev, rw, p)
+ttselect(dev, rw, wql, p)
dev_t dev;
int rw;
+ void * wql;
struct proc *p;
{
#ifndef NeXT
- return ttyselect((*cdevsw[major(dev)]->d_devtotty)(dev), rw, p);
+ return ttyselect((*cdevsw[major(dev)]->d_devtotty)(dev), rw, wql, p);
#else
- return ttyselect(cdevsw[major(dev)].d_ttys[minor(dev)], rw, p);
+ return ttyselect(cdevsw[major(dev)].d_ttys[minor(dev)], rw, wql, p);
#endif
}
ttstart(tp)
struct tty *tp;
{
+ boolean_t funnel_state;
+
+ funnel_state = thread_funnel_set(kernel_flock, TRUE);
if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
(*tp->t_oproc)(tp);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
struct tty *tp;
int flag;
{
+ boolean_t funnel_state;
+
+ funnel_state = thread_funnel_set(kernel_flock, TRUE);
if ( (flag & FNONBLOCK) || ttywflush(tp))
ttyflush(tp, FREAD | FWRITE);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
register struct tty *tp;
int flag;
{
+ boolean_t funnel_state;
+
+ funnel_state = thread_funnel_set(kernel_flock, TRUE);
if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
/*
if (tp->t_session && tp->t_session->s_leader)
psignal(tp->t_session->s_leader, SIGHUP);
ttyflush(tp, FREAD | FWRITE);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
} else {
ttwakeup(tp);
ttwwakeup(tp);
}
+ thread_funnel_set(kernel_flock, funnel_state);
return (1);
}
int s, first, error = 0;
int has_etime = 0, last_cc = 0;
long slp = 0; /* XXX this should be renamed `timo'. */
+ boolean_t funnel_state;
+ struct uthread *ut;
+
+ funnel_state = thread_funnel_set(kernel_flock, TRUE);
+
+ ut = (struct uthread *)get_bsdthread_info(current_act());
loop:
s = spltty();
if (isbackground(p, tp)) {
splx(s);
if ((p->p_sigignore & sigmask(SIGTTIN)) ||
- (p->p_sigmask & sigmask(SIGTTIN)) ||
- p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
+ (ut->uu_sigmask & sigmask(SIGTTIN)) ||
+ p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0) {
+ thread_funnel_set(kernel_flock, funnel_state);
return (EIO);
+ }
pgsignal(p->p_pgrp, SIGTTIN, 1);
error = ttysleep(tp, &lbolt, TTIPRI | PCATCH | PTTYBLOCK, "ttybg2", 0);
- if (error)
+ if (error){
+ thread_funnel_set(kernel_flock, funnel_state);
return (error);
+ }
goto loop;
}
if (ISSET(tp->t_state, TS_ZOMBIE)) {
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0); /* EOF */
}
goto read;
if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (EWOULDBLOCK);
}
if (!ISSET(lflag, ICANON)) {
/* m, t and qp->c_cc are all 0. 0 is enough input. */
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
t *= 100000; /* time in us */
if (timercmp(&etime, &timecopy, <=)) {
/* Timed out, but 0 is enough input. */
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
slp = diff(etime, timecopy);
splx(s);
if (error == EWOULDBLOCK)
error = 0;
- else if (error)
+ else if (error) {
+ thread_funnel_set(kernel_flock, funnel_state);
return (error);
+ }
/*
* XXX what happens if another process eats some input
* while we are asleep (not just here)? It would be
ttyunblock(tp);
splx(s);
+ thread_funnel_set(kernel_flock, funnel_state);
return (error);
}
int wait;
{
int hiwat, s, oldsig;
+ struct uthread *ut;
+
+ ut = (struct uthread *)get_bsdthread_info(current_act());
hiwat = tp->t_hiwat;
s = spltty();
- oldsig = wait ? current_proc()->p_siglist : 0;
+ oldsig = wait ? ut->uu_siglist : 0;
if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
while (tp->t_outq.c_cc > hiwat) {
ttstart(tp);
if (tp->t_outq.c_cc <= hiwat)
break;
- if (wait == 0 || current_proc()->p_siglist != oldsig) {
+ if (wait == 0 || ut->uu_siglist != oldsig) {
splx(s);
return (0);
}
register struct proc *p;
int i, hiwat, cnt, error, s;
char obuf[OBUFSIZ];
+ boolean_t funnel_state;
+ struct uthread *ut;
+ funnel_state = thread_funnel_set(kernel_flock, TRUE);
+
+ ut = (struct uthread *)get_bsdthread_info(current_act());
hiwat = tp->t_hiwat;
cnt = uio->uio_resid;
error = 0;
if (isbackground(p, tp) &&
ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
(p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
- (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
+ (ut->uu_sigmask & sigmask(SIGTTOU)) == 0) {
if (p->p_pgrp->pg_jobc == 0) {
error = EIO;
goto out;
while (uio->uio_resid > 0 || cc > 0) {
if (ISSET(tp->t_lflag, FLUSHO)) {
uio->uio_resid = 0;
+ thread_funnel_set(kernel_flock, funnel_state);
return (0);
}
if (tp->t_outq.c_cc > hiwat)
* (the call will either return short or restart with a new uio).
*/
uio->uio_resid += cc;
+ thread_funnel_set(kernel_flock, funnel_state);
return (error);
#ifdef NeXT
if (flag & IO_NDELAY) {
splx(s);
uio->uio_resid += cc;
+ thread_funnel_set(kernel_flock, funnel_state);
return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
}
SET(tp->t_state, TS_SO_OLOWAT);