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