tty: further chunks of work on the tty job control interfaces
authorAlan Cox <alan@linux.intel.com>
Sun, 27 Dec 2015 14:02:23 +0000 (14:02 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 27 Dec 2015 14:02:23 +0000 (14:02 +0000)
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
Kernel/level2.c
Kernel/syscall_level2.c
Kernel/tty.c

index e557b02..249a924 100644 (file)
@@ -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
index b25a5fb..1c8a1a3 100644 (file)
@@ -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;
+}
index 06b3fa3..43a2729 100644 (file)
@@ -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;
+}
+
index 264c0c3..4dc6833 100644 (file)
@@ -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;