Cygwin: pty, console: Encapsulate spawn.cc code related to pty/console.
- The codes related to pty and console in spawn.cc have been moved into the new class fhandler_termios::spawn_worker, and make spawn.cc call them. The functionality has not been changed at all.
This commit is contained in:
parent
c03f0c3062
commit
32d6a6cb5f
|
@ -692,6 +692,29 @@ fhandler_termios::tcgetsid ()
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_console_app (const WCHAR *filename)
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
const int id_offset = 92;
|
||||||
|
h = CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
char buf[1024];
|
||||||
|
DWORD n;
|
||||||
|
ReadFile (h, buf, sizeof (buf), &n, 0);
|
||||||
|
CloseHandle (h);
|
||||||
|
char *p = (char *) memmem (buf, n, "PE\0\0", 4);
|
||||||
|
if (p && p + id_offset < buf + n)
|
||||||
|
return p[id_offset] == '\003'; /* 02: GUI, 03: console */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wchar_t *e = wcsrchr (filename, L'.');
|
||||||
|
if (e && (wcscasecmp (e, L".bat") == 0 || wcscasecmp (e, L".cmd") == 0))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_termios::ioctl (int cmd, void *varg)
|
fhandler_termios::ioctl (int cmd, void *varg)
|
||||||
{
|
{
|
||||||
|
@ -718,3 +741,79 @@ fhandler_termios::ioctl (int cmd, void *varg)
|
||||||
myself->set_ctty (this, 0);
|
myself->set_ctty (this, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_termios::spawn_worker::setup (bool iscygwin, HANDLE h_stdin,
|
||||||
|
const WCHAR *runpath, bool nopcon,
|
||||||
|
bool reset_sendsig,
|
||||||
|
const WCHAR *envblock)
|
||||||
|
{
|
||||||
|
fhandler_pty_slave *ptys_primary = NULL;
|
||||||
|
fhandler_console *cons_native = NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i ++)
|
||||||
|
{
|
||||||
|
const int chk_order[] = {1, 0, 2};
|
||||||
|
int fd = chk_order[i];
|
||||||
|
fhandler_base *fh = ::cygheap->fdtab[fd];
|
||||||
|
if (fh && fh->get_major () == DEV_PTYS_MAJOR && ptys_primary == NULL)
|
||||||
|
ptys_primary = (fhandler_pty_slave *) fh;
|
||||||
|
else if (fh && fh->get_major () == DEV_CONS_MAJOR
|
||||||
|
&& !iscygwin && cons_native == NULL)
|
||||||
|
cons_native = (fhandler_console *) fh;
|
||||||
|
}
|
||||||
|
if (cons_native)
|
||||||
|
{
|
||||||
|
cons_native->setup_for_non_cygwin_app ();
|
||||||
|
/* Console handles will be already closed by close_all_files()
|
||||||
|
when cleaning up, therefore, duplicate them here. */
|
||||||
|
cons_native->get_duplicated_handle_set (&cons_handle_set);
|
||||||
|
cons_need_cleanup = true;
|
||||||
|
}
|
||||||
|
if (!iscygwin)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
cygheap_fdenum cfd (false);
|
||||||
|
while ((fd = cfd.next ()) >= 0)
|
||||||
|
if (cfd->get_major () == DEV_PTYS_MAJOR)
|
||||||
|
{
|
||||||
|
fhandler_pty_slave *ptys
|
||||||
|
= (fhandler_pty_slave *)(fhandler_base *) cfd;
|
||||||
|
ptys->create_invisible_console ();
|
||||||
|
ptys->setup_locale ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!iscygwin && ptys_primary && is_console_app (runpath))
|
||||||
|
{
|
||||||
|
if (h_stdin == ptys_primary->get_handle_nat ())
|
||||||
|
stdin_is_ptys = true;
|
||||||
|
if (reset_sendsig)
|
||||||
|
myself->sendsig = myself->exec_sendsig;
|
||||||
|
ptys_primary->setup_for_non_cygwin_app (nopcon, envblock, stdin_is_ptys);
|
||||||
|
if (reset_sendsig)
|
||||||
|
myself->sendsig = NULL;
|
||||||
|
ptys_primary->get_duplicated_handle_set (&ptys_handle_set);
|
||||||
|
ptys_ttyp = (tty *) ptys_primary->tc ();
|
||||||
|
ptys_need_cleanup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_termios::spawn_worker::cleanup ()
|
||||||
|
{
|
||||||
|
if (ptys_need_cleanup)
|
||||||
|
fhandler_pty_slave::cleanup_for_non_cygwin_app (&ptys_handle_set,
|
||||||
|
ptys_ttyp, stdin_is_ptys);
|
||||||
|
if (cons_need_cleanup)
|
||||||
|
fhandler_console::cleanup_for_non_cygwin_app (&cons_handle_set);
|
||||||
|
close_handle_set ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_termios::spawn_worker::close_handle_set ()
|
||||||
|
{
|
||||||
|
if (ptys_need_cleanup)
|
||||||
|
fhandler_pty_slave::close_handle_set (&ptys_handle_set);
|
||||||
|
if (cons_need_cleanup)
|
||||||
|
fhandler_console::close_handle_set (&cons_handle_set);
|
||||||
|
}
|
||||||
|
|
|
@ -247,7 +247,7 @@ atexit_func (void)
|
||||||
tty *ttyp = (tty *) ptys->tc ();
|
tty *ttyp = (tty *) ptys->tc ();
|
||||||
bool stdin_is_ptys =
|
bool stdin_is_ptys =
|
||||||
GetStdHandle (STD_INPUT_HANDLE) == ptys->get_handle ();
|
GetStdHandle (STD_INPUT_HANDLE) == ptys->get_handle ();
|
||||||
struct fhandler_pty_slave::handle_set_t handles =
|
fhandler_pty_slave::handle_set_t handles =
|
||||||
{
|
{
|
||||||
ptys->get_handle_nat (),
|
ptys->get_handle_nat (),
|
||||||
ptys->get_input_available_event (),
|
ptys->get_input_available_event (),
|
||||||
|
@ -4096,7 +4096,8 @@ fhandler_pty_slave::close_handle_set (handle_set_t *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_pty_slave::setup_for_non_cygwin_app (bool nopcon, PWCHAR envblock,
|
fhandler_pty_slave::setup_for_non_cygwin_app (bool nopcon,
|
||||||
|
const WCHAR *envblock,
|
||||||
bool stdin_is_ptys)
|
bool stdin_is_ptys)
|
||||||
{
|
{
|
||||||
if (disable_pcon || !term_has_pcon_cap (envblock))
|
if (disable_pcon || !term_has_pcon_cap (envblock))
|
||||||
|
|
|
@ -1989,6 +1989,40 @@ class fhandler_termios: public fhandler_base
|
||||||
virtual bool need_console_handler () { return false; }
|
virtual bool need_console_handler () { return false; }
|
||||||
virtual bool need_send_ctrl_c_event () { return true; }
|
virtual bool need_send_ctrl_c_event () { return true; }
|
||||||
virtual DWORD get_helper_pid () { return 0; }
|
virtual DWORD get_helper_pid () { return 0; }
|
||||||
|
|
||||||
|
struct ptys_handle_set_t
|
||||||
|
{
|
||||||
|
HANDLE from_master_nat;
|
||||||
|
HANDLE input_available_event;
|
||||||
|
HANDLE input_mutex;
|
||||||
|
HANDLE pipe_sw_mutex;
|
||||||
|
};
|
||||||
|
struct cons_handle_set_t
|
||||||
|
{
|
||||||
|
HANDLE input_handle;
|
||||||
|
HANDLE output_handle;
|
||||||
|
HANDLE input_mutex;
|
||||||
|
HANDLE output_mutex;
|
||||||
|
};
|
||||||
|
class spawn_worker
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ptys_handle_set_t ptys_handle_set;
|
||||||
|
cons_handle_set_t cons_handle_set;
|
||||||
|
bool ptys_need_cleanup;
|
||||||
|
bool cons_need_cleanup;
|
||||||
|
bool stdin_is_ptys;
|
||||||
|
tty *ptys_ttyp;
|
||||||
|
public:
|
||||||
|
spawn_worker () :
|
||||||
|
ptys_need_cleanup (false), cons_need_cleanup (false),
|
||||||
|
stdin_is_ptys (false), ptys_ttyp (NULL) {}
|
||||||
|
void setup (bool iscygwin, HANDLE h_stdin, const WCHAR *runpath,
|
||||||
|
bool nopcon, bool reset_sendsig, const WCHAR *envblock);
|
||||||
|
bool need_cleanup () { return ptys_need_cleanup || cons_need_cleanup; }
|
||||||
|
void cleanup ();
|
||||||
|
void close_handle_set ();
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ansi_intensity
|
enum ansi_intensity
|
||||||
|
@ -2133,13 +2167,7 @@ public:
|
||||||
input_signalled = 2,
|
input_signalled = 2,
|
||||||
input_winch = 3
|
input_winch = 3
|
||||||
};
|
};
|
||||||
struct handle_set_t
|
typedef cons_handle_set_t handle_set_t;
|
||||||
{
|
|
||||||
HANDLE input_handle;
|
|
||||||
HANDLE output_handle;
|
|
||||||
HANDLE input_mutex;
|
|
||||||
HANDLE output_mutex;
|
|
||||||
};
|
|
||||||
HANDLE thread_sync_event;
|
HANDLE thread_sync_event;
|
||||||
private:
|
private:
|
||||||
static const unsigned MAX_WRITE_CHARS;
|
static const unsigned MAX_WRITE_CHARS;
|
||||||
|
@ -2375,13 +2403,7 @@ class fhandler_pty_slave: public fhandler_pty_common
|
||||||
public:
|
public:
|
||||||
pid_t tc_getpgid () { return _tc ? _tc->pgid : 0; }
|
pid_t tc_getpgid () { return _tc ? _tc->pgid : 0; }
|
||||||
|
|
||||||
struct handle_set_t
|
typedef ptys_handle_set_t handle_set_t;
|
||||||
{
|
|
||||||
HANDLE from_master_nat;
|
|
||||||
HANDLE input_available_event;
|
|
||||||
HANDLE input_mutex;
|
|
||||||
HANDLE pipe_sw_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
fhandler_pty_slave (int);
|
fhandler_pty_slave (int);
|
||||||
|
@ -2450,7 +2472,7 @@ class fhandler_pty_slave: public fhandler_pty_common
|
||||||
void cleanup_before_exit ();
|
void cleanup_before_exit ();
|
||||||
void get_duplicated_handle_set (handle_set_t *p);
|
void get_duplicated_handle_set (handle_set_t *p);
|
||||||
static void close_handle_set (handle_set_t *p);
|
static void close_handle_set (handle_set_t *p);
|
||||||
void setup_for_non_cygwin_app (bool nopcon, PWCHAR envblock,
|
void setup_for_non_cygwin_app (bool nopcon, const WCHAR *envblock,
|
||||||
bool stdin_is_ptys);
|
bool stdin_is_ptys);
|
||||||
static void cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
|
static void cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
|
||||||
bool stdin_is_ptys,
|
bool stdin_is_ptys,
|
||||||
|
|
|
@ -211,29 +211,6 @@ handle (int fd, bool writing)
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
is_console_app (WCHAR *filename)
|
|
||||||
{
|
|
||||||
HANDLE h;
|
|
||||||
const int id_offset = 92;
|
|
||||||
h = CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ,
|
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
char buf[1024];
|
|
||||||
DWORD n;
|
|
||||||
ReadFile (h, buf, sizeof (buf), &n, 0);
|
|
||||||
CloseHandle (h);
|
|
||||||
char *p = (char *) memmem (buf, n, "PE\0\0", 4);
|
|
||||||
if (p && p + id_offset < buf + n)
|
|
||||||
return p[id_offset] == '\003'; /* 02: GUI, 03: console */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wchar_t *e = wcsrchr (filename, L'.');
|
|
||||||
if (e && (wcscasecmp (e, L".bat") == 0 || wcscasecmp (e, L".cmd") == 0))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
iscmd (const char *argv0, const char *what)
|
iscmd (const char *argv0, const char *what)
|
||||||
{
|
{
|
||||||
|
@ -345,10 +322,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
STARTUPINFOW si = {};
|
STARTUPINFOW si = {};
|
||||||
int looped = 0;
|
int looped = 0;
|
||||||
|
|
||||||
struct fhandler_pty_slave::handle_set_t ptys_handle_set = { 0, };
|
fhandler_termios::spawn_worker term_spawn_worker;
|
||||||
bool ptys_need_cleanup = false;
|
|
||||||
struct fhandler_console::handle_set_t cons_handle_set = { 0, };
|
|
||||||
bool cons_need_cleanup = false;
|
|
||||||
|
|
||||||
system_call_handle system_call (mode == _P_SYSTEM);
|
system_call_handle system_call (mode == _P_SYSTEM);
|
||||||
|
|
||||||
|
@ -598,29 +572,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
PROCESS_QUERY_LIMITED_INFORMATION))
|
PROCESS_QUERY_LIMITED_INFORMATION))
|
||||||
sa = &sec_none_nih;
|
sa = &sec_none_nih;
|
||||||
|
|
||||||
fhandler_pty_slave *ptys_primary = NULL;
|
|
||||||
fhandler_console *cons_native = NULL;
|
|
||||||
for (int i = 0; i < 3; i ++)
|
|
||||||
{
|
|
||||||
const int chk_order[] = {1, 0, 2};
|
|
||||||
int fd = chk_order[i];
|
|
||||||
fhandler_base *fh = ::cygheap->fdtab[fd];
|
|
||||||
if (fh && fh->get_major () == DEV_PTYS_MAJOR && ptys_primary == NULL)
|
|
||||||
ptys_primary = (fhandler_pty_slave *) fh;
|
|
||||||
else if (fh && fh->get_major () == DEV_CONS_MAJOR
|
|
||||||
&& !iscygwin () && cons_native == NULL)
|
|
||||||
cons_native = (fhandler_console *) fh;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cons_native)
|
|
||||||
{
|
|
||||||
cons_native->setup_for_non_cygwin_app ();
|
|
||||||
/* Console handles will be already closed by close_all_files()
|
|
||||||
when cleaning up, therefore, duplicate them here. */
|
|
||||||
cons_native->get_duplicated_handle_set (&cons_handle_set);
|
|
||||||
cons_need_cleanup = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fileno_stdin = in__stdin < 0 ? 0 : in__stdin;
|
int fileno_stdin = in__stdin < 0 ? 0 : in__stdin;
|
||||||
int fileno_stdout = in__stdout < 0 ? 1 : in__stdout;
|
int fileno_stdout = in__stdout < 0 ? 1 : in__stdout;
|
||||||
int fileno_stderr = 2;
|
int fileno_stderr = 2;
|
||||||
|
@ -631,14 +582,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
int fd;
|
int fd;
|
||||||
cygheap_fdenum cfd (false);
|
cygheap_fdenum cfd (false);
|
||||||
while ((fd = cfd.next ()) >= 0)
|
while ((fd = cfd.next ()) >= 0)
|
||||||
if (cfd->get_major () == DEV_PTYS_MAJOR)
|
if (cfd->get_dev () == FH_PIPEW
|
||||||
{
|
|
||||||
fhandler_pty_slave *ptys =
|
|
||||||
(fhandler_pty_slave *)(fhandler_base *) cfd;
|
|
||||||
ptys->create_invisible_console ();
|
|
||||||
ptys->setup_locale ();
|
|
||||||
}
|
|
||||||
else if (cfd->get_dev () == FH_PIPEW
|
|
||||||
&& (fd == fileno_stdout || fd == fileno_stderr))
|
&& (fd == fileno_stdout || fd == fileno_stderr))
|
||||||
{
|
{
|
||||||
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
|
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
|
||||||
|
@ -666,24 +610,9 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stdin_is_ptys = false;
|
bool no_pcon = mode != _P_OVERLAY && mode != _P_WAIT;
|
||||||
tty *ptys_ttyp = NULL;
|
term_spawn_worker.setup (iscygwin (), handle (fileno_stdin, false),
|
||||||
if (!iscygwin () && ptys_primary && is_console_app (runpath))
|
runpath, no_pcon, reset_sendsig, envblock);
|
||||||
{
|
|
||||||
bool nopcon = mode != _P_OVERLAY && mode != _P_WAIT;
|
|
||||||
HANDLE h_stdin = handle (fileno_stdin, false);
|
|
||||||
if (h_stdin == ptys_primary->get_handle_nat ())
|
|
||||||
stdin_is_ptys = true;
|
|
||||||
if (reset_sendsig)
|
|
||||||
myself->sendsig = myself->exec_sendsig;
|
|
||||||
ptys_primary->setup_for_non_cygwin_app (nopcon, envblock,
|
|
||||||
stdin_is_ptys);
|
|
||||||
if (reset_sendsig)
|
|
||||||
myself->sendsig = NULL;
|
|
||||||
ptys_primary->get_duplicated_handle_set (&ptys_handle_set);
|
|
||||||
ptys_ttyp = (tty *) ptys_primary->tc ();
|
|
||||||
ptys_need_cleanup = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up needed handles for stdio */
|
/* Set up needed handles for stdio */
|
||||||
si.dwFlags = STARTF_USESTDHANDLES;
|
si.dwFlags = STARTF_USESTDHANDLES;
|
||||||
|
@ -844,11 +773,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
/* Name the handle similarly to proc_subproc. */
|
/* Name the handle similarly to proc_subproc. */
|
||||||
ProtectHandle1 (pi.hProcess, childhProc);
|
ProtectHandle1 (pi.hProcess, childhProc);
|
||||||
|
|
||||||
/* Do not touch these terminal instances after here.
|
|
||||||
They may be destroyed by close_all_files(). */
|
|
||||||
ptys_primary = NULL;
|
|
||||||
cons_native = NULL;
|
|
||||||
|
|
||||||
if (mode == _P_OVERLAY)
|
if (mode == _P_OVERLAY)
|
||||||
{
|
{
|
||||||
myself->dwProcessId = pi.dwProcessId;
|
myself->dwProcessId = pi.dwProcessId;
|
||||||
|
@ -966,7 +890,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
}
|
}
|
||||||
if (sem)
|
if (sem)
|
||||||
__posix_spawn_sem_release (sem, 0);
|
__posix_spawn_sem_release (sem, 0);
|
||||||
if (ptys_need_cleanup || cons_need_cleanup)
|
if (term_spawn_worker.need_cleanup ())
|
||||||
{
|
{
|
||||||
LONG prev_sigExeced = sigExeced;
|
LONG prev_sigExeced = sigExeced;
|
||||||
while (WaitForSingleObject (pi.hProcess, 100) == WAIT_TIMEOUT)
|
while (WaitForSingleObject (pi.hProcess, 100) == WAIT_TIMEOUT)
|
||||||
|
@ -975,18 +899,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
the signal sigExeced. Therefore, clear sigExeced here. */
|
the signal sigExeced. Therefore, clear sigExeced here. */
|
||||||
prev_sigExeced =
|
prev_sigExeced =
|
||||||
InterlockedCompareExchange (&sigExeced, 0, prev_sigExeced);
|
InterlockedCompareExchange (&sigExeced, 0, prev_sigExeced);
|
||||||
}
|
term_spawn_worker.cleanup ();
|
||||||
if (ptys_need_cleanup)
|
term_spawn_worker.close_handle_set ();
|
||||||
{
|
|
||||||
fhandler_pty_slave::cleanup_for_non_cygwin_app (&ptys_handle_set,
|
|
||||||
ptys_ttyp,
|
|
||||||
stdin_is_ptys);
|
|
||||||
fhandler_pty_slave::close_handle_set (&ptys_handle_set);
|
|
||||||
}
|
|
||||||
if (cons_need_cleanup)
|
|
||||||
{
|
|
||||||
fhandler_console::cleanup_for_non_cygwin_app (&cons_handle_set);
|
|
||||||
fhandler_console::close_handle_set (&cons_handle_set);
|
|
||||||
}
|
}
|
||||||
/* Make sure that ctrl_c_handler() is not on going. Calling
|
/* Make sure that ctrl_c_handler() is not on going. Calling
|
||||||
init_console_handler(false) locks until returning from
|
init_console_handler(false) locks until returning from
|
||||||
|
@ -1000,12 +914,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
system_call.arm ();
|
system_call.arm ();
|
||||||
if (waitpid (cygpid, &res, 0) != cygpid)
|
if (waitpid (cygpid, &res, 0) != cygpid)
|
||||||
res = -1;
|
res = -1;
|
||||||
if (ptys_need_cleanup)
|
term_spawn_worker.cleanup ();
|
||||||
fhandler_pty_slave::cleanup_for_non_cygwin_app (&ptys_handle_set,
|
|
||||||
ptys_ttyp,
|
|
||||||
stdin_is_ptys);
|
|
||||||
if (cons_need_cleanup)
|
|
||||||
fhandler_console::cleanup_for_non_cygwin_app (&cons_handle_set);
|
|
||||||
break;
|
break;
|
||||||
case _P_DETACH:
|
case _P_DETACH:
|
||||||
res = 0; /* Lost all memory of this child. */
|
res = 0; /* Lost all memory of this child. */
|
||||||
|
@ -1028,10 +937,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
__endtry
|
__endtry
|
||||||
if (ptys_need_cleanup)
|
term_spawn_worker.close_handle_set ();
|
||||||
fhandler_pty_slave::close_handle_set (&ptys_handle_set);
|
|
||||||
if (cons_need_cleanup)
|
|
||||||
fhandler_console::close_handle_set (&cons_handle_set);
|
|
||||||
this->cleanup ();
|
this->cleanup ();
|
||||||
if (envblock)
|
if (envblock)
|
||||||
free (envblock);
|
free (envblock);
|
||||||
|
|
Loading…
Reference in New Issue