1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-11-13     Shell        init ver.
9  */
10 
11 #define DBG_TAG "lwp.tty"
12 #define DBG_LVL DBG_INFO
13 #include <rtdbg.h>
14 
15 #include <terminal/terminal.h>
16 #include "lwp_internal.h"
17 
jobctrl_set_pgrp_orphaned(struct rt_processgroup * pgrp)18 static void jobctrl_set_pgrp_orphaned(struct rt_processgroup *pgrp)
19 {
20     rt_lwp_t proc, nx_proc;
21     PGRP_LOCK(pgrp);
22 
23     pgrp->is_orphaned = 1;
24     rt_list_for_each_entry(proc, &pgrp->process, pgrp_node)
25     {
26         LWP_LOCK(proc);
27         if (proc->jobctl_stopped)
28         {
29             LWP_UNLOCK(proc);
30             rt_list_for_each_entry_safe(proc, nx_proc, &pgrp->process, pgrp_node)
31             {
32                 LWP_LOCK(proc);
33                 lwp_signal_kill(proc, SIGHUP, SI_KERNEL, 0);
34                 lwp_signal_kill(proc, SIGCONT, SI_KERNEL, 0);
35                 LWP_UNLOCK(proc);
36             }
37         }
38         LWP_UNLOCK(proc);
39     }
40 
41     PGRP_UNLOCK(pgrp);
42 }
43 
lwp_jobctrl_on_exit(struct rt_lwp * lwp)44 void lwp_jobctrl_on_exit(struct rt_lwp *lwp)
45 {
46     rt_processgroup_t pgrp;
47     rt_session_t session;
48     lwp_tty_t tp;
49 
50     pgrp = lwp->pgrp;
51     RT_ASSERT(pgrp);
52     session = pgrp->session;
53     RT_ASSERT(session);
54 
55     /**
56      * as a session leader, we have to mark tty as freed. So others can race to
57      * take it before we actually close and released that tty
58      */
59     SESS_LOCK(session);
60     if (session->sid == lwp->pid)
61     {
62         tp = session->ctty;
63         session->leader = 0;
64 
65         /* signal to foreground group that modem is disconnected */
66         if (tp)
67         {
68             tty_lock(tp);
69             if (tp->t_session == session)
70                 lwp_tty_signal_pgrp(tp, SIGHUP);
71             tty_unlock(tp);
72         }
73 
74         /* revoke tty vnode ? */
75 
76         rt_list_for_each_entry(pgrp, &session->processgroup, pgrp_list_node)
77         {
78             jobctrl_set_pgrp_orphaned(pgrp);
79         }
80 
81     }
82     SESS_UNLOCK(session);
83 
84     /* release tty */
85     /* allow tty stolen? */
86 }
87