Browse Source

tty 内添加一个存放lwp的链表,进行前后台切换

linzhenxing 2 years ago
parent
commit
93295b9838

+ 6 - 0
components/drivers/tty/console.c

@@ -295,6 +295,12 @@ rt_err_t console_register(const char *name, struct rt_device *iodev)
     console->type = TTY_DRIVER_TYPE_CONSOLE;
     console->subtype = SERIAL_TYPE_NORMAL;
     console->driver = iodev;
+    console->head = rt_calloc(1, sizeof(struct list_node));
+    if (!console->head)
+    {
+        return -RT_ENOMEM;
+    }
+    tty_initstack(console->head);
 
     console->pgrp = -1;
     console->session = -1;

+ 10 - 0
components/drivers/tty/include/tty.h

@@ -23,6 +23,15 @@
 #define current lwp_self()
 #define __DISABLED_CHAR '\0'
 
+struct list_node
+{
+    struct rt_lwp *p;
+    struct list_node *next;
+};
+
+void tty_initstack(struct list_node *node);
+int tty_push(struct list_node **head, struct rt_lwp *lwp);
+struct rt_lwp *tty_pop(struct list_node **head);
 /*
  * When a break, frame error, or parity error happens, these codes are
  * stuffed into the flags buffer.
@@ -144,6 +153,7 @@ struct tty_struct
     pid_t pgrp;
     pid_t session;
     struct rt_lwp *foreground;
+    struct list_node *head;
 
     struct tty_ldisc *ldisc;
     void *disc_data;

+ 4 - 1
components/drivers/tty/n_tty.c

@@ -534,6 +534,8 @@ static void __isig(int sig, struct tty_struct *tty)
     {
         if (sig == SIGTSTP)
         {
+            struct rt_lwp *old_lwp;
+            
             rt_memcpy(&old_termios, &(tty->init_termios), sizeof(struct termios));
             tty->init_termios = *new_termios;
             ld = tty->ldisc;
@@ -545,7 +547,8 @@ static void __isig(int sig, struct tty_struct *tty)
                 }
             }
             tty_sigaddset(&lwp->signal_mask, SIGTTOU);
-            tty->foreground = RT_NULL;  
+            old_lwp = tty_pop(&tty->head);
+            tty->foreground = old_lwp;  
         }
         else
         {

+ 7 - 1
components/drivers/tty/pty.c

@@ -341,7 +341,13 @@ static int ptmx_register(void)
 
     ptm_drv->type = TTY_DRIVER_TYPE_PTY;
     ptm_drv->subtype = PTY_TYPE_MASTER;
-
+    ptm_drv->head = rt_calloc(1, sizeof(struct list_node));
+    if (!ptm_drv->head)
+    {
+        return -RT_ENOMEM;
+    }
+    tty_initstack(ptm_drv->head);
+    
     ptm_drv->pgrp = -1;
     ptm_drv->session = -1;
     ptm_drv->foreground = RT_NULL;

+ 39 - 0
components/drivers/tty/tty.c

@@ -38,6 +38,45 @@ struct termios tty_std_termios = {  /* for the benefit of tty drivers  */
     .__c_ospeed = 38400
 };
 
+void tty_initstack(struct list_node *node)
+{
+    node->p = NULL;
+    node->next = node;
+}
+
+int tty_push(struct list_node **head, struct rt_lwp *lwp)
+{
+    struct list_node *s = rt_calloc(1, sizeof(struct list_node));
+    if (!s)
+    {
+        return -1;
+    }
+    s->p = lwp;
+    s->next = *head;
+    *head = s;
+
+    return 0;
+}
+
+struct rt_lwp *tty_pop(struct list_node **head)
+{
+    struct list_node *s;
+    struct rt_lwp *lwp;
+
+    if (!*head)
+    {
+        return RT_NULL;
+    }
+
+    lwp = (*head)->p;
+    s = *head;
+    *head = (*head)->next;
+    s->p = NULL;
+    rt_free(s);
+
+    return lwp;
+}
+
 rt_inline int tty_sigismember(lwp_sigset_t *set, int _sig)
 {
     unsigned long sig = _sig - 1;

+ 13 - 0
components/lwp/lwp.c

@@ -1097,6 +1097,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
     int bg = 0;
     struct process_aux *aux;
     int tid = 0;
+    int ret;
 
     if (filename == RT_NULL)
     {
@@ -1201,7 +1202,14 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
                 if (lwp->session == -1)
                 {
                     struct tty_struct *tty = RT_NULL;
+                    struct rt_lwp *old_lwp;
                     tty = (struct tty_struct *)console_tty_get();
+                    old_lwp = tty->foreground;
+                    ret = tty_push(&tty->head, old_lwp);
+                    if (ret < 0)
+                    {
+                        rt_kprintf("malloc fail!\n");
+                    }
                     lwp->tty = tty;
                     lwp->tty->pgrp = lwp->__pgrp;
                     lwp->tty->session = lwp->session;
@@ -1215,6 +1223,11 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
                 {
                     if (self_lwp != RT_NULL)
                     {
+                        ret = tty_push(&self_lwp->tty->head, self_lwp);
+                        if (ret < 0)
+                        {
+                            rt_kprintf("malloc fail!\n");
+                        }
                         lwp->tty = self_lwp->tty;
                         lwp->tty->pgrp = lwp->__pgrp;
                         lwp->tty->session = lwp->session;

+ 5 - 1
components/lwp/lwp_pid.c

@@ -438,6 +438,8 @@ void lwp_free(struct rt_lwp* lwp)
     {
         struct termios *old_stdin_termios = get_old_termios();
         struct rt_lwp *self_lwp = (struct rt_lwp *)lwp_self();
+        struct rt_lwp *old_lwp = NULL;
+
         if (lwp->session == -1)
         {
             tcsetattr(1, 0, old_stdin_termios);
@@ -445,9 +447,11 @@ void lwp_free(struct rt_lwp* lwp)
         level = rt_hw_interrupt_disable();
         if (lwp->tty != RT_NULL)
         {
+            old_lwp = tty_pop(&lwp->tty->head);
+
             if (lwp->tty->foreground == lwp)
             {
-                lwp->tty->foreground = self_lwp;
+                lwp->tty->foreground = old_lwp;
                 lwp->tty = RT_NULL;
             }
         }

+ 10 - 0
components/lwp/lwp_syscall.c

@@ -1725,6 +1725,16 @@ int _sys_fork(void)
     level = rt_hw_interrupt_disable();
     if (lwp->tty != RT_NULL)
     {
+        int ret;
+        struct rt_lwp *old_lwp;
+
+        old_lwp = lwp->tty->foreground;
+        ret = tty_push(&lwp->tty->head, old_lwp);
+        if (ret < 0)
+        {
+            rt_kprintf("malloc fail!\n");
+            goto fail;
+        }
         lwp->tty->foreground = lwp;
     }
     rt_hw_interrupt_enable(level);