Get rid of some function forward declarations.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Этот коммит содержится в:
родитель
321f5b2555
Коммит
d92a2a4fd6
@ -76,10 +76,6 @@ typedef enum
|
|||||||
/*** file scope variables ************************************************************************/
|
/*** file scope variables ************************************************************************/
|
||||||
|
|
||||||
/*** file scope functions ************************************************************************/
|
/*** file scope functions ************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static void dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t msg, gboolean reverse, int flags);
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* broadcast a message to all the widgets in a dialog that have
|
* broadcast a message to all the widgets in a dialog that have
|
||||||
|
@ -186,17 +186,6 @@ static FileProgressStatus transform_error = FILE_CONT;
|
|||||||
/*** file scope functions ************************************************************************/
|
/*** file scope functions ************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static FileProgressStatus query_replace (FileOpContext * ctx, const char *destname,
|
|
||||||
struct stat *_s_stat, struct stat *_d_stat);
|
|
||||||
static FileProgressStatus query_recursive (FileOpContext * ctx, const char *s);
|
|
||||||
static FileProgressStatus do_file_error (const char *str);
|
|
||||||
static FileProgressStatus erase_dir_iff_empty (FileOpContext * ctx, const char *s);
|
|
||||||
static FileProgressStatus erase_file (FileOpTotalContext * tctx, FileOpContext * ctx,
|
|
||||||
const char *s, gboolean is_toplevel_file);
|
|
||||||
static FileProgressStatus files_error (const char *format, const char *file1, const char *file2);
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
transform_source (FileOpContext * ctx, const char *source)
|
transform_source (FileOpContext * ctx, const char *source)
|
||||||
{
|
{
|
||||||
@ -483,6 +472,186 @@ warn_same_file (const char *fmt, const char *a, const char *b)
|
|||||||
return real_warn_same_file (Foreground, fmt, a, b);
|
return real_warn_same_file (Foreground, fmt, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
/* {{{ Query/status report routines */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
real_do_file_error (enum OperationMode mode, const char *error)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
const char *msg;
|
||||||
|
|
||||||
|
msg = mode == Foreground ? MSG_ERROR : _("Background process error");
|
||||||
|
result =
|
||||||
|
query_dialog (msg, error, D_ERROR, 4, _("&Skip"), _("Ski&p all"), _("&Retry"), _("&Abort"));
|
||||||
|
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
do_refresh ();
|
||||||
|
return FILE_SKIP;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
do_refresh ();
|
||||||
|
return FILE_SKIPALL;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
do_refresh ();
|
||||||
|
return FILE_RETRY;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
default:
|
||||||
|
return FILE_ABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
real_query_recursive (FileOpContext * ctx, enum OperationMode mode, const char *s)
|
||||||
|
{
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
if (ctx->recursive_result < RECURSIVE_ALWAYS)
|
||||||
|
{
|
||||||
|
const char *msg = mode == Foreground
|
||||||
|
? _("\nDirectory not empty.\nDelete it recursively?")
|
||||||
|
: _("\nBackground process: Directory not empty.\nDelete it recursively?");
|
||||||
|
text = g_strconcat (_("Delete:"), " ", path_trunc (s, 30), (char *) NULL);
|
||||||
|
|
||||||
|
if (safe_delete)
|
||||||
|
query_set_sel (1);
|
||||||
|
|
||||||
|
ctx->recursive_result =
|
||||||
|
(FileCopyMode) query_dialog (text, msg, D_ERROR, 5,
|
||||||
|
_("&Yes"), _("&No"), _("A&ll"), _("Non&e"), _("&Abort"));
|
||||||
|
|
||||||
|
if (ctx->recursive_result != RECURSIVE_ABORT)
|
||||||
|
do_refresh ();
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ctx->recursive_result)
|
||||||
|
{
|
||||||
|
case RECURSIVE_YES:
|
||||||
|
case RECURSIVE_ALWAYS:
|
||||||
|
return FILE_CONT;
|
||||||
|
|
||||||
|
case RECURSIVE_NO:
|
||||||
|
case RECURSIVE_NEVER:
|
||||||
|
return FILE_SKIP;
|
||||||
|
|
||||||
|
case RECURSIVE_ABORT:
|
||||||
|
default:
|
||||||
|
return FILE_ABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef WITH_BACKGROUND
|
||||||
|
static FileProgressStatus
|
||||||
|
do_file_error (const char *str)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
FileProgressStatus (*f) (enum OperationMode, const char *);
|
||||||
|
} pntr;
|
||||||
|
pntr.f = real_do_file_error;
|
||||||
|
|
||||||
|
if (mc_global.we_are_background)
|
||||||
|
return parent_call (pntr.p, NULL, 1, strlen (str), str);
|
||||||
|
else
|
||||||
|
return real_do_file_error (Foreground, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
query_recursive (FileOpContext * ctx, const char *s)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *);
|
||||||
|
} pntr;
|
||||||
|
pntr.f = real_query_recursive;
|
||||||
|
|
||||||
|
if (mc_global.we_are_background)
|
||||||
|
return parent_call (pntr.p, ctx, 1, strlen (s), s);
|
||||||
|
else
|
||||||
|
return real_query_recursive (ctx, Foreground, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat,
|
||||||
|
struct stat *_d_stat)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *,
|
||||||
|
struct stat *, struct stat *);
|
||||||
|
} pntr;
|
||||||
|
pntr.f = file_progress_real_query_replace;
|
||||||
|
|
||||||
|
if (mc_global.we_are_background)
|
||||||
|
return parent_call (pntr.p, ctx, 3, strlen (destname), destname,
|
||||||
|
sizeof (struct stat), _s_stat, sizeof (struct stat), _d_stat);
|
||||||
|
else
|
||||||
|
return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
do_file_error (const char *str)
|
||||||
|
{
|
||||||
|
return real_do_file_error (Foreground, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
query_recursive (FileOpContext * ctx, const char *s)
|
||||||
|
{
|
||||||
|
return real_query_recursive (ctx, Foreground, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat,
|
||||||
|
struct stat *_d_stat)
|
||||||
|
{
|
||||||
|
return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !WITH_BACKGROUND */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
/** Report error with two files */
|
||||||
|
|
||||||
|
static FileProgressStatus
|
||||||
|
files_error (const char *format, const char *file1, const char *file2)
|
||||||
|
{
|
||||||
|
char buf[BUF_MEDIUM];
|
||||||
|
char *nfile1 = g_strdup (path_trunc (file1, 15));
|
||||||
|
char *nfile2 = g_strdup (path_trunc (file2, 15));
|
||||||
|
|
||||||
|
g_snprintf (buf, sizeof (buf), format, nfile1, nfile2, unix_error_string (errno));
|
||||||
|
|
||||||
|
g_free (nfile1);
|
||||||
|
g_free (nfile2);
|
||||||
|
|
||||||
|
return do_file_error (buf);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -539,7 +708,6 @@ copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx,
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
/* {{{ Move routines */
|
/* {{{ Move routines */
|
||||||
static FileProgressStatus
|
static FileProgressStatus
|
||||||
move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, const char *d)
|
move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, const char *d)
|
||||||
@ -918,6 +1086,7 @@ panel_compute_totals (const WPanel * panel, const void *ui,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/** Initialize variables for progress bars */
|
/** Initialize variables for progress bars */
|
||||||
static FileProgressStatus
|
static FileProgressStatus
|
||||||
panel_operate_init_totals (FileOperation operation,
|
panel_operate_init_totals (FileOperation operation,
|
||||||
@ -1076,186 +1245,6 @@ end_bg_process (FileOpContext * ctx, enum OperationMode mode)
|
|||||||
#endif
|
#endif
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
/* {{{ Query/status report routines */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
real_do_file_error (enum OperationMode mode, const char *error)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
const char *msg;
|
|
||||||
|
|
||||||
msg = mode == Foreground ? MSG_ERROR : _("Background process error");
|
|
||||||
result =
|
|
||||||
query_dialog (msg, error, D_ERROR, 4, _("&Skip"), _("Ski&p all"), _("&Retry"), _("&Abort"));
|
|
||||||
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
do_refresh ();
|
|
||||||
return FILE_SKIP;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
do_refresh ();
|
|
||||||
return FILE_SKIPALL;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
do_refresh ();
|
|
||||||
return FILE_RETRY;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
default:
|
|
||||||
return FILE_ABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
/** Report error with two files */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
files_error (const char *format, const char *file1, const char *file2)
|
|
||||||
{
|
|
||||||
char buf[BUF_MEDIUM];
|
|
||||||
char *nfile1 = g_strdup (path_trunc (file1, 15));
|
|
||||||
char *nfile2 = g_strdup (path_trunc (file2, 15));
|
|
||||||
|
|
||||||
g_snprintf (buf, sizeof (buf), format, nfile1, nfile2, unix_error_string (errno));
|
|
||||||
|
|
||||||
g_free (nfile1);
|
|
||||||
g_free (nfile2);
|
|
||||||
|
|
||||||
return do_file_error (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
real_query_recursive (FileOpContext * ctx, enum OperationMode mode, const char *s)
|
|
||||||
{
|
|
||||||
gchar *text;
|
|
||||||
|
|
||||||
if (ctx->recursive_result < RECURSIVE_ALWAYS)
|
|
||||||
{
|
|
||||||
const char *msg = mode == Foreground
|
|
||||||
? _("\nDirectory not empty.\nDelete it recursively?")
|
|
||||||
: _("\nBackground process: Directory not empty.\nDelete it recursively?");
|
|
||||||
text = g_strconcat (_("Delete:"), " ", path_trunc (s, 30), (char *) NULL);
|
|
||||||
|
|
||||||
if (safe_delete)
|
|
||||||
query_set_sel (1);
|
|
||||||
|
|
||||||
ctx->recursive_result =
|
|
||||||
(FileCopyMode) query_dialog (text, msg, D_ERROR, 5,
|
|
||||||
_("&Yes"), _("&No"), _("A&ll"), _("Non&e"), _("&Abort"));
|
|
||||||
|
|
||||||
if (ctx->recursive_result != RECURSIVE_ABORT)
|
|
||||||
do_refresh ();
|
|
||||||
g_free (text);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ctx->recursive_result)
|
|
||||||
{
|
|
||||||
case RECURSIVE_YES:
|
|
||||||
case RECURSIVE_ALWAYS:
|
|
||||||
return FILE_CONT;
|
|
||||||
|
|
||||||
case RECURSIVE_NO:
|
|
||||||
case RECURSIVE_NEVER:
|
|
||||||
return FILE_SKIP;
|
|
||||||
|
|
||||||
case RECURSIVE_ABORT:
|
|
||||||
default:
|
|
||||||
return FILE_ABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#ifdef WITH_BACKGROUND
|
|
||||||
static FileProgressStatus
|
|
||||||
do_file_error (const char *str)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
FileProgressStatus (*f) (enum OperationMode, const char *);
|
|
||||||
} pntr;
|
|
||||||
pntr.f = real_do_file_error;
|
|
||||||
|
|
||||||
if (mc_global.we_are_background)
|
|
||||||
return parent_call (pntr.p, NULL, 1, strlen (str), str);
|
|
||||||
else
|
|
||||||
return real_do_file_error (Foreground, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
query_recursive (FileOpContext * ctx, const char *s)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *);
|
|
||||||
} pntr;
|
|
||||||
pntr.f = real_query_recursive;
|
|
||||||
|
|
||||||
if (mc_global.we_are_background)
|
|
||||||
return parent_call (pntr.p, ctx, 1, strlen (s), s);
|
|
||||||
else
|
|
||||||
return real_query_recursive (ctx, Foreground, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat,
|
|
||||||
struct stat *_d_stat)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *,
|
|
||||||
struct stat *, struct stat *);
|
|
||||||
} pntr;
|
|
||||||
pntr.f = file_progress_real_query_replace;
|
|
||||||
|
|
||||||
if (mc_global.we_are_background)
|
|
||||||
return parent_call (pntr.p, ctx, 3, strlen (destname), destname,
|
|
||||||
sizeof (struct stat), _s_stat, sizeof (struct stat), _d_stat);
|
|
||||||
else
|
|
||||||
return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
do_file_error (const char *str)
|
|
||||||
{
|
|
||||||
return real_do_file_error (Foreground, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
query_recursive (FileOpContext * ctx, const char *s)
|
|
||||||
{
|
|
||||||
return real_query_recursive (ctx, Foreground, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static FileProgressStatus
|
|
||||||
query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat,
|
|
||||||
struct stat *_d_stat)
|
|
||||||
{
|
|
||||||
return file_progress_real_query_replace (ctx, Foreground, destname, _s_stat, _d_stat);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !WITH_BACKGROUND */
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/*** public functions ****************************************************************************/
|
/*** public functions ****************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
@ -337,12 +337,6 @@ typedef struct format_e
|
|||||||
|
|
||||||
/*** file scope variables ************************************************************************/
|
/*** file scope variables ************************************************************************/
|
||||||
|
|
||||||
static cb_ret_t panel_callback (Widget *, widget_msg_t msg, int parm);
|
|
||||||
static int panel_event (Gpm_Event * event, void *);
|
|
||||||
static void paint_frame (WPanel * panel);
|
|
||||||
static const char *panel_format (WPanel * panel);
|
|
||||||
static const char *mini_status_format (WPanel * panel);
|
|
||||||
|
|
||||||
static char *panel_sort_up_sign = NULL;
|
static char *panel_sort_up_sign = NULL;
|
||||||
static char *panel_sort_down_sign = NULL;
|
static char *panel_sort_down_sign = NULL;
|
||||||
|
|
||||||
@ -1630,7 +1624,6 @@ panel_format (WPanel * panel)
|
|||||||
{
|
{
|
||||||
switch (panel->list_type)
|
switch (panel->list_type)
|
||||||
{
|
{
|
||||||
|
|
||||||
case list_long:
|
case list_long:
|
||||||
return "full perm space nlink space owner space group space size space mtime space name";
|
return "full perm space nlink space owner space group space size space mtime space name";
|
||||||
|
|
||||||
|
@ -173,14 +173,6 @@ static int prompt_pos;
|
|||||||
|
|
||||||
|
|
||||||
/*** file scope functions ************************************************************************/
|
/*** file scope functions ************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static void init_raw_mode (void);
|
|
||||||
static gboolean feed_subshell (int how, int fail_on_error);
|
|
||||||
static void synchronize (void);
|
|
||||||
static int pty_open_master (char *pty_name);
|
|
||||||
static int pty_open_slave (const char *pty_name);
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Write all data, even if the write() call is interrupted.
|
* Write all data, even if the write() call is interrupted.
|
||||||
@ -429,6 +421,44 @@ init_raw_mode ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
/**
|
||||||
|
* Wait until the subshell dies or stops. If it stops, make it resume.
|
||||||
|
* Possibly modifies the globals `subshell_alive' and `subshell_stopped'
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
synchronize (void)
|
||||||
|
{
|
||||||
|
sigset_t sigchld_mask, old_mask;
|
||||||
|
|
||||||
|
sigemptyset (&sigchld_mask);
|
||||||
|
sigaddset (&sigchld_mask, SIGCHLD);
|
||||||
|
sigprocmask (SIG_BLOCK, &sigchld_mask, &old_mask);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SIGCHLD should not be blocked, but we unblock it just in case.
|
||||||
|
* This is known to be useful for cygwin 1.3.12 and older.
|
||||||
|
*/
|
||||||
|
sigdelset (&old_mask, SIGCHLD);
|
||||||
|
|
||||||
|
/* Wait until the subshell has stopped */
|
||||||
|
while (subshell_alive && !subshell_stopped)
|
||||||
|
sigsuspend (&old_mask);
|
||||||
|
|
||||||
|
if (subshell_state != ACTIVE)
|
||||||
|
{
|
||||||
|
/* Discard all remaining data from stdin to the subshell */
|
||||||
|
tcflush (subshell_pty_slave, TCIFLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
subshell_stopped = FALSE;
|
||||||
|
kill (subshell_pid, SIGCONT);
|
||||||
|
|
||||||
|
sigprocmask (SIG_SETMASK, &old_mask, NULL);
|
||||||
|
/* We can't do any better without modifying the shell(s) */
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/** Feed the subshell our keyboard input until it says it's finished */
|
/** Feed the subshell our keyboard input until it says it's finished */
|
||||||
|
|
||||||
@ -558,43 +588,6 @@ feed_subshell (int how, int fail_on_error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
|
||||||
* Wait until the subshell dies or stops. If it stops, make it resume.
|
|
||||||
* Possibly modifies the globals `subshell_alive' and `subshell_stopped'
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
synchronize (void)
|
|
||||||
{
|
|
||||||
sigset_t sigchld_mask, old_mask;
|
|
||||||
|
|
||||||
sigemptyset (&sigchld_mask);
|
|
||||||
sigaddset (&sigchld_mask, SIGCHLD);
|
|
||||||
sigprocmask (SIG_BLOCK, &sigchld_mask, &old_mask);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SIGCHLD should not be blocked, but we unblock it just in case.
|
|
||||||
* This is known to be useful for cygwin 1.3.12 and older.
|
|
||||||
*/
|
|
||||||
sigdelset (&old_mask, SIGCHLD);
|
|
||||||
|
|
||||||
/* Wait until the subshell has stopped */
|
|
||||||
while (subshell_alive && !subshell_stopped)
|
|
||||||
sigsuspend (&old_mask);
|
|
||||||
|
|
||||||
if (subshell_state != ACTIVE)
|
|
||||||
{
|
|
||||||
/* Discard all remaining data from stdin to the subshell */
|
|
||||||
tcflush (subshell_pty_slave, TCIFLUSH);
|
|
||||||
}
|
|
||||||
|
|
||||||
subshell_stopped = FALSE;
|
|
||||||
kill (subshell_pid, SIGCONT);
|
|
||||||
|
|
||||||
sigprocmask (SIG_SETMASK, &old_mask, NULL);
|
|
||||||
/* We can't do any better without modifying the shell(s) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pty opening functions */
|
/* pty opening functions */
|
||||||
|
|
||||||
#ifdef HAVE_GRANTPT
|
#ifdef HAVE_GRANTPT
|
||||||
@ -747,6 +740,7 @@ pty_open_slave (const char *pty_name)
|
|||||||
return pty_slave;
|
return pty_slave;
|
||||||
}
|
}
|
||||||
#endif /* !HAVE_GRANTPT */
|
#endif /* !HAVE_GRANTPT */
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/*** public functions ****************************************************************************/
|
/*** public functions ****************************************************************************/
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1073,7 +1067,6 @@ exit_subshell (void)
|
|||||||
return subshell_quit;
|
return subshell_quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
/**
|
/**
|
||||||
* Carefully quote directory name to allow entering any directory safely,
|
* Carefully quote directory name to allow entering any directory safely,
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user