mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58:22 +00:00
jobctl: allow tty stealing
This commit is contained in:
@@ -11,7 +11,7 @@ void jobctl_addproc(proc_t *parent, proc_t *proc);
|
|||||||
void jobctl_procremove(proc_t *proc);
|
void jobctl_procremove(proc_t *proc);
|
||||||
pid_t jobctl_getpgid(proc_t *proc);
|
pid_t jobctl_getpgid(proc_t *proc);
|
||||||
pid_t jobctl_getsid(proc_t *proc);
|
pid_t jobctl_getsid(proc_t *proc);
|
||||||
void jobctl_setctty(proc_t *proc, void *ctty);
|
int jobctl_setctty(proc_t *proc, void *ctty, bool steal);
|
||||||
void *jobctl_getctty(proc_t *proc);
|
void *jobctl_getctty(proc_t *proc);
|
||||||
int jobctl_signal(proc_t *proc, int signal);
|
int jobctl_signal(proc_t *proc, int signal);
|
||||||
proc_t *jobctl_getforeground(proc_t *proc);
|
proc_t *jobctl_getforeground(proc_t *proc);
|
||||||
|
|||||||
+2
-13
@@ -320,19 +320,8 @@ int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result) {
|
|||||||
case TCSETS:
|
case TCSETS:
|
||||||
return USERCOPY_POSSIBLY_FROM_USER(&tty->termios, arg, sizeof(termios_t));
|
return USERCOPY_POSSIBLY_FROM_USER(&tty->termios, arg, sizeof(termios_t));
|
||||||
case TIOCSCTTY: {
|
case TIOCSCTTY: {
|
||||||
if (arg) {
|
|
||||||
int steal;
|
|
||||||
int e = USERCOPY_POSSIBLY_FROM_USER(&steal, arg, sizeof(int));
|
|
||||||
if (e)
|
|
||||||
return e;
|
|
||||||
|
|
||||||
if (steal == 1) {
|
|
||||||
printf("tty: stealing not supported\n");
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// set as controlling tty
|
// set as controlling tty
|
||||||
jobctl_setctty(_cpu()->thread->proc, tty);
|
return jobctl_setctty(_cpu()->thread->proc, tty, (uintptr_t)arg == 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TIOCGPGRP: {
|
case TIOCGPGRP: {
|
||||||
@@ -399,7 +388,7 @@ static int open(int minor, vnode_t **vnode, int flags) {
|
|||||||
return ENODEV;
|
return ENODEV;
|
||||||
} else if ((flags & V_FFLAGS_NOCTTY) == 0) {
|
} else if ((flags & V_FFLAGS_NOCTTY) == 0) {
|
||||||
// set as controlling tty
|
// set as controlling tty
|
||||||
jobctl_setctty(_cpu()->thread->proc, tty);
|
jobctl_setctty(_cpu()->thread->proc, tty, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+35
-20
@@ -33,9 +33,9 @@ static void removefromlist(proc_t *pgrp, proc_t *proc) {
|
|||||||
spinlock_release(&pgrp->pgrp.lock);
|
spinlock_release(&pgrp->pgrp.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jobctl_setctty(proc_t *proc, void *_ctty) {
|
int jobctl_setctty(proc_t *proc, void *_ctty, bool steal) {
|
||||||
tty_t *tty = _ctty;
|
tty_t *tty = _ctty;
|
||||||
|
int error = 0;
|
||||||
bool intstatus = interrupt_set(false);
|
bool intstatus = interrupt_set(false);
|
||||||
spinlock_acquire(&proc->jobctllock);
|
spinlock_acquire(&proc->jobctllock);
|
||||||
|
|
||||||
@@ -45,21 +45,38 @@ void jobctl_setctty(proc_t *proc, void *_ctty) {
|
|||||||
if (proc->session.leader)
|
if (proc->session.leader)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
if (tty == NULL && proc->session.controllingtty) {
|
tty_t *checktty = proc->session.controllingtty;
|
||||||
unholdtty = proc->session.controllingtty;
|
if (tty == NULL && checktty) {
|
||||||
proc->session.controllingtty = NULL;
|
if (checktty)
|
||||||
spinlock_acquire(&unholdtty->sessionlock);
|
spinlock_acquire(&checktty->sessionlock);
|
||||||
unholdtty->session = NULL;
|
|
||||||
spinlock_release(&unholdtty->sessionlock);
|
// check if it was stolen
|
||||||
|
if (checktty->session == proc) {
|
||||||
|
// not stolen, unset it
|
||||||
|
// TODO SIGHUP and SIGCONT to foregroup group
|
||||||
|
unholdtty = checktty;
|
||||||
|
proc->session.controllingtty = NULL;
|
||||||
|
checktty->session = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinlock_release(&checktty->sessionlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tty && proc->session.controllingtty == NULL) {
|
if (tty && proc->session.controllingtty == NULL) {
|
||||||
spinlock_acquire(&tty->sessionlock);
|
spinlock_acquire(&tty->sessionlock);
|
||||||
|
|
||||||
if (tty->session == NULL) {
|
if (tty->session == NULL) {
|
||||||
VOP_HOLD(tty->mastervnode);
|
VOP_HOLD(tty->mastervnode);
|
||||||
proc->session.controllingtty = tty;
|
proc->session.controllingtty = tty;
|
||||||
tty->session = proc;
|
tty->session = proc;
|
||||||
|
} else if (steal) {
|
||||||
|
// vnode reference gets transferred over to the new proc
|
||||||
|
tty->session->session.controllingtty = NULL;
|
||||||
|
tty->session = proc;
|
||||||
|
} else {
|
||||||
|
error = EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_release(&tty->sessionlock);
|
spinlock_release(&tty->sessionlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +87,8 @@ void jobctl_setctty(proc_t *proc, void *_ctty) {
|
|||||||
if (unholdtty) {
|
if (unholdtty) {
|
||||||
VOP_RELEASE(unholdtty->mastervnode);
|
VOP_RELEASE(unholdtty->mastervnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *jobctl_getctty(proc_t *proc) {
|
void *jobctl_getctty(proc_t *proc) {
|
||||||
@@ -77,23 +96,19 @@ void *jobctl_getctty(proc_t *proc) {
|
|||||||
|
|
||||||
bool intstatus = interrupt_set(false);
|
bool intstatus = interrupt_set(false);
|
||||||
spinlock_acquire(&proc->jobctllock);
|
spinlock_acquire(&proc->jobctllock);
|
||||||
|
proc_t *session = proc->session.leader ? proc->session.leader : proc;
|
||||||
|
|
||||||
if (proc->session.leader) {
|
if (session != proc)
|
||||||
proc_t *session = proc->session.leader;
|
|
||||||
spinlock_acquire(&session->jobctllock);
|
spinlock_acquire(&session->jobctllock);
|
||||||
|
|
||||||
tty = session->session.controllingtty;
|
tty = session->session.controllingtty;
|
||||||
if (tty) {
|
if (tty) {
|
||||||
VOP_HOLD(tty->mastervnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_release(&session->jobctllock);
|
|
||||||
} else if (proc->session.controllingtty){
|
|
||||||
// is the session leader
|
|
||||||
tty = proc->session.controllingtty;
|
|
||||||
VOP_HOLD(tty->mastervnode);
|
VOP_HOLD(tty->mastervnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session != proc)
|
||||||
|
spinlock_release(&session->jobctllock);
|
||||||
|
|
||||||
spinlock_release(&proc->jobctllock);
|
spinlock_release(&proc->jobctllock);
|
||||||
interrupt_set(intstatus);
|
interrupt_set(intstatus);
|
||||||
return tty;
|
return tty;
|
||||||
@@ -262,7 +277,7 @@ void jobctl_detach(proc_t *proc) {
|
|||||||
if (unholdsession) {
|
if (unholdsession) {
|
||||||
PROC_RELEASE(unholdsession);
|
PROC_RELEASE(unholdsession);
|
||||||
} else {
|
} else {
|
||||||
jobctl_setctty(proc, NULL);
|
jobctl_setctty(proc, NULL, 0);
|
||||||
jobctl_signal(foreground, SIGHUP);
|
jobctl_signal(foreground, SIGHUP);
|
||||||
jobctl_signal(foreground, SIGCONT);
|
jobctl_signal(foreground, SIGCONT);
|
||||||
PROC_RELEASE(foreground);
|
PROC_RELEASE(foreground);
|
||||||
|
|||||||
Reference in New Issue
Block a user