From ef95d56394db7600023c99e8f01102c347d3433d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 27 Dec 2015 14:02:23 +0000 Subject: [PATCH] tty: further chunks of work on the tty job control interfaces There is a fair bit left to do, in particular all the silly signal handling funnies BSD job control does and the signal handling special cases it causes. --- Kernel/include/tty.h | 3 ++ Kernel/level2.c | 32 +++++++++++++++ Kernel/syscall_level2.c | 88 +++++++++++++++++++++++++++++++++++++++++ Kernel/tty.c | 11 ++++++ 4 files changed, 134 insertions(+) diff --git a/Kernel/include/tty.h b/Kernel/include/tty.h index e557b02e..249a924b 100644 --- a/Kernel/include/tty.h +++ b/Kernel/include/tty.h @@ -142,6 +142,9 @@ struct termios { #define TIOCGWINSZ 10 #define TIOCSWINSZ 11 +#define TIOCGPGRP 12 +#define TIOCSPGRP 13 + #define KBMAPSIZE 0x20 #define KBMAPGET 0x21 #define VTSIZE 0x22 diff --git a/Kernel/level2.c b/Kernel/level2.c index b25a5fb6..1c8a1a31 100644 --- a/Kernel/level2.c +++ b/Kernel/level2.c @@ -16,6 +16,8 @@ void jobcontrol_in(struct tty *t) { if (udata.u_proc->p_pgrp == t->pgrp) return; + /* We probably want to special case a helper here because we need + to handle the funnier side effects ? */ ssig(udata.u_proc, SIGTTIN); /* So we halt */ pause(0); @@ -31,3 +33,33 @@ void jobcontrol_out(struct tty *t) /* So we halt */ pause(0); } + +int tcsetpgrp(struct tty *t, char *data) /* data is user pointer */ +{ + uint16_t grp = ugetw(data); + uint16_t ses = udata.u_ptab->p_session; + ptptr p; + uint8_t found = 0; + + /* Controlling tty check is done by caller */ + + /* No change -> ok */ + if (grp == tty->pgrp) + return 0; + + for (p = ptab; p < ptab_end; ++p) { + /* The group exists */ + if (p->p_pgrp == grp) { + /* but not within our session */ + if (p->p_session != ses) { + udata.u_error = EPERM; + return -1; + } + /* So it's a valid group and in our session */ + tty->pgrp = grp; + return 0; + } + } + udata.u_error = EINVAL; + return -1; +} diff --git a/Kernel/syscall_level2.c b/Kernel/syscall_level2.c index 06b3fa3c..43a27291 100644 --- a/Kernel/syscall_level2.c +++ b/Kernel/syscall_level2.c @@ -111,3 +111,91 @@ bad: #undef res #undef rlim +/******************************************* + setpgid (pid, pgid) Function ?? + uint16_t npid; + uint16_t npgid; + *******************************************/ + +#define npid (uint16_t)udata.u_argn +#define npgid (uint16_t)udata.u_argn1 + +arg_t _setpgid(void) +{ + ptptr p, t; + uint16_t ses = udata.u_ptab->p_session; + + /* pid 0 means "self" */ + if (npid == 0) + t = udata.u_ptab; + else { + for (p = ptab; p < ptab_end; ++p) { + if (p->p_pid == npid) + t = p; + } + } + if (t == NULL) { + udata.u_error = ESRCH; + return -1; + } + + if (t->p_session != udata.u_ptab->p_session) + goto invalid; + + if (npgid == 0) + npgid = t->p_pid; + + /* Check if the group is in use with a different session */ + for (p = ptab; p < ptab_end; ++p) + if (p->p_pgrp == npgid && p->p_session != ses) + goto invalid; + + t->p_pgrp = npgid; + return 0; + +invalid: + udata.u_error = EPERM; + return -1; +} + +#undef npid +#undef npgid + +/******************************************* + setsid (void) Function ?? + *******************************************/ + +arg_t _setsid(void) +{ + ptptr p; + uint16_t pid = udata.u_ptab->p_pid; + + for (p = ptab; p < ptab_end; ++p) { + if (p->p_pgid == pid || p->p_session == pid) { + udata.u_error = EPERM; + return -1; + } + } + p = udata.u_ptab; + p->p_pgrp = pid; + p->p_session = pid; + udata.u_ctty = NULL; + return 0; +} + +/******************************************* + getsid (pid) Function ?? + uint16_t pid; + *******************************************/ + +arg_t _getsid(void) +{ + ptptr p; + for (p = ptab; p < ptab_end; ++p) { + if (p->p_pid == pid) + return p->p_session; + } + udata.u_error = ESRCH; + return -1; +} + diff --git a/Kernel/tty.c b/Kernel/tty.c index 264c0c37..4dc68334 100644 --- a/Kernel/tty.c +++ b/Kernel/tty.c @@ -267,6 +267,17 @@ int tty_ioctl(uint8_t minor, uarg_t request, char *data) return -1; sgrpsig(t->pgrp, SIGWINCH); return 0; + case TIOCGPGRP: + return uputw(t->pgrp, data); +#ifdef CONFIG_LEVEL_2 + case TIOCSPGRP: + /* Only applicable via controlling terminal */ + if (minor != udata.u_ptab->p_tty) { + udata.u_error = ENOTTY; + return -1; + } + return tcsetpgrp(minor, t, data); +#endif default: udata.u_error = ENOTTY; return -1; -- 2.34.1