mirror of https://github.com/MidnightCommander/mc
Fixed problems:
* When try to replace existing file in background operation assertion raised (created operations for initialization ctx->ui for background): ** (mc:25716): CRITICAL **: file_progress_real_query_replace: assertion `ctx->ui != NULL' failed * Process has been already done, but still draw in list (C-x j) * Process is stopped or worked, remove operation don't hide process from list, but kill it Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
81f5b5e0b8
commit
936727622d
|
@ -88,8 +88,8 @@ register_task_running (FileOpContext *ctx, pid_t pid, int fd, int to_child,
|
|||
add_select_channel (fd, background_attention, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
unregister_task_running (pid_t pid, int fd)
|
||||
int
|
||||
destroy_task_and_return_fd (pid_t pid)
|
||||
{
|
||||
TaskList *p = task_list;
|
||||
TaskList *prev = 0;
|
||||
|
@ -102,14 +102,31 @@ unregister_task_running (pid_t pid, int fd)
|
|||
task_list = p->next;
|
||||
g_free (p->info);
|
||||
g_free (p);
|
||||
break;
|
||||
return p->fd;
|
||||
}
|
||||
prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
/* pid not found */
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
unregister_task_running (pid_t pid, int fd)
|
||||
{
|
||||
destroy_task_and_return_fd(pid);
|
||||
delete_select_channel (fd);
|
||||
}
|
||||
|
||||
void
|
||||
unregister_task_with_pid (pid_t pid)
|
||||
{
|
||||
int fd = destroy_task_and_return_fd(pid);
|
||||
if (fd != -1)
|
||||
delete_select_channel (fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to make the Midnight Commander a background job
|
||||
*
|
||||
|
@ -216,16 +233,19 @@ background_attention (int fd, void *closure)
|
|||
int have_ctx;
|
||||
union
|
||||
{
|
||||
int (*have_ctx0)(int);
|
||||
int (*have_ctx1)(int, char *);
|
||||
int (*have_ctx2)(int, char *, char *);
|
||||
int (*have_ctx3)(int, char *, char *, char *);
|
||||
int (*have_ctx4)(int, char *, char *, char *, char *);
|
||||
|
||||
int (*non_have_ctx0)(FileOpContext *, int);
|
||||
int (*non_have_ctx1)(FileOpContext *, int, char *);
|
||||
int (*non_have_ctx2)(FileOpContext *, int, char *, char *);
|
||||
int (*non_have_ctx3)(FileOpContext *, int, char *, char *, char *);
|
||||
int (*non_have_ctx4)(FileOpContext *, int, char *, char *, char *, char *);
|
||||
|
||||
char * (*ret_str0)();
|
||||
char * (*ret_str1)(char *);
|
||||
char * (*ret_str2)(char *, char *);
|
||||
char * (*ret_str3)(char *, char *, char *);
|
||||
|
@ -238,7 +258,7 @@ background_attention (int fd, void *closure)
|
|||
char *data [MAXCALLARGS];
|
||||
ssize_t bytes;
|
||||
struct TaskList *p;
|
||||
int to_child_fd;
|
||||
int to_child_fd = -1;
|
||||
enum ReturnType type;
|
||||
|
||||
ctx = closure;
|
||||
|
@ -285,10 +305,25 @@ background_attention (int fd, void *closure)
|
|||
data [i][size] = 0; /* NULL terminate the blocks (they could be strings) */
|
||||
}
|
||||
|
||||
/* Find child task info by descriptor */
|
||||
/* Find before call, because process can destroy self after */
|
||||
for (p = task_list; p; p = p->next) {
|
||||
if (p->fd == fd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p) to_child_fd = p->to_child_fd;
|
||||
|
||||
if (to_child_fd == -1)
|
||||
message (D_ERROR, _(" Background process error "), _(" Unknown error in child "));
|
||||
|
||||
/* Handle the call */
|
||||
if (type == Return_Integer){
|
||||
if (!have_ctx)
|
||||
switch (argc){
|
||||
case 0:
|
||||
result = routine.have_ctx0 (Background);
|
||||
break;
|
||||
case 1:
|
||||
result = routine.have_ctx1 (Background, data [0]);
|
||||
break;
|
||||
|
@ -304,6 +339,9 @@ background_attention (int fd, void *closure)
|
|||
}
|
||||
else
|
||||
switch (argc){
|
||||
case 0:
|
||||
result = routine.non_have_ctx0 (ctx, Background);
|
||||
break;
|
||||
case 1:
|
||||
result = routine.non_have_ctx1 (ctx, Background, data [0]);
|
||||
break;
|
||||
|
@ -318,17 +356,9 @@ background_attention (int fd, void *closure)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Find child task info by descriptor */
|
||||
for (p = task_list; p; p = p->next) {
|
||||
if (p->fd == fd)
|
||||
break;
|
||||
}
|
||||
|
||||
to_child_fd = p->to_child_fd;
|
||||
|
||||
/* Send the result code and the value for shared variables */
|
||||
write (to_child_fd, &result, sizeof (int));
|
||||
if (have_ctx)
|
||||
if (have_ctx && to_child_fd != -1)
|
||||
write (to_child_fd, ctx, sizeof (FileOpContext));
|
||||
} else if (type == Return_String) {
|
||||
int len;
|
||||
|
@ -338,6 +368,9 @@ background_attention (int fd, void *closure)
|
|||
* parameter. Currently, this is not used here
|
||||
*/
|
||||
switch (argc){
|
||||
case 0:
|
||||
resstr = routine.ret_str0 ();
|
||||
break;
|
||||
case 1:
|
||||
resstr = routine.ret_str1 (data [0]);
|
||||
break;
|
||||
|
|
|
@ -32,6 +32,7 @@ int parent_call (void *routine, struct FileOpContext *ctx, int argc, ...);
|
|||
char *parent_call_string (void *routine, int argc, ...);
|
||||
|
||||
void unregister_task_running (pid_t pid, int fd);
|
||||
void unregister_task_with_pid (pid_t pid);
|
||||
extern int we_are_background;
|
||||
|
||||
#endif /* !WITH_BACKGROUND */
|
||||
|
|
|
@ -883,7 +883,7 @@ task_cb (int action)
|
|||
sig = SIGKILL;
|
||||
}
|
||||
|
||||
if (sig == SIGINT)
|
||||
if (sig == SIGKILL)
|
||||
unregister_task_running (tl->pid, tl->fd);
|
||||
|
||||
kill (tl->pid, sig);
|
||||
|
|
28
src/file.c
28
src/file.c
|
@ -1787,6 +1787,17 @@ panel_operate_generate_prompt (const WPanel *panel, const int operation,
|
|||
return g_strdup (format_string);
|
||||
}
|
||||
|
||||
#ifdef WITH_BACKGROUND
|
||||
int end_bg_process (FileOpContext *ctx, enum OperationMode mode) {
|
||||
int pid = ctx->pid;
|
||||
ctx->pid = 0;
|
||||
|
||||
unregister_task_with_pid(pid);
|
||||
// file_op_context_destroy(ctx);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* panel_operate:
|
||||
*
|
||||
|
@ -1931,6 +1942,12 @@ panel_operate (void *source_panel, FileOperation operation,
|
|||
}
|
||||
}
|
||||
|
||||
/* Background also need ctx->ui, but not full */
|
||||
if (do_bg)
|
||||
file_op_context_create_ui_without_init (ctx, 1);
|
||||
else
|
||||
file_op_context_create_ui (ctx, 1);
|
||||
|
||||
#ifdef WITH_BACKGROUND
|
||||
/* Did the user select to do a background operation? */
|
||||
if (do_bg) {
|
||||
|
@ -1969,11 +1986,6 @@ panel_operate (void *source_panel, FileOperation operation,
|
|||
|
||||
/* Now, let's do the job */
|
||||
|
||||
if (do_bg)
|
||||
ctx->ui = NULL;
|
||||
else
|
||||
file_op_context_create_ui (ctx, 1);
|
||||
|
||||
/* This code is only called by the tree and panel code */
|
||||
if (single_entry) {
|
||||
/* We now have ETA in all cases */
|
||||
|
@ -2201,6 +2213,12 @@ panel_operate (void *source_panel, FileOperation operation,
|
|||
#ifdef WITH_BACKGROUND
|
||||
/* Let our parent know we are saying bye bye */
|
||||
if (we_are_background) {
|
||||
int cur_pid = getpid();
|
||||
/* Send pid to parent with child context, it is fork and
|
||||
don't modify real parent ctx */
|
||||
ctx->pid = cur_pid;
|
||||
parent_call ((void *) end_bg_process, ctx, 0);
|
||||
|
||||
vfs_shut ();
|
||||
_exit (0);
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ check_progress_buttons (FileOpContext *ctx)
|
|||
/* {{{ File progress display routines */
|
||||
|
||||
void
|
||||
file_op_context_create_ui (FileOpContext *ctx, int with_eta)
|
||||
file_op_context_create_ui_without_init (FileOpContext *ctx, int with_eta)
|
||||
{
|
||||
FileOpContextUI *ui;
|
||||
int x_size;
|
||||
|
@ -321,6 +321,18 @@ file_op_context_create_ui (FileOpContext *ctx, int with_eta)
|
|||
label_new (3, FCOPY_GAUGE_X, sixty));
|
||||
add_widget (ui->op_dlg, ui->file_label[0] =
|
||||
label_new (3, FCOPY_LABEL_X, fifteen));
|
||||
}
|
||||
|
||||
void
|
||||
file_op_context_create_ui (FileOpContext *ctx, int with_eta)
|
||||
{
|
||||
FileOpContextUI *ui;
|
||||
|
||||
g_return_if_fail (ctx != NULL);
|
||||
g_return_if_fail (ctx->ui == NULL);
|
||||
|
||||
file_op_context_create_ui_without_init(ctx, with_eta);
|
||||
ui = ctx->ui;
|
||||
|
||||
/* We will manage the dialog without any help, that's why
|
||||
we have to call init_dlg */
|
||||
|
|
|
@ -144,6 +144,7 @@ enum OperationMode {
|
|||
/* The following functions are implemented separately by each port */
|
||||
|
||||
void file_op_context_create_ui (FileOpContext *ctx, int with_eta);
|
||||
void file_op_context_create_ui_without_init (FileOpContext *ctx, int with_eta);
|
||||
void file_op_context_destroy_ui (FileOpContext *ctx);
|
||||
|
||||
FileProgressStatus file_progress_show (FileOpContext *ctx, off_t done, off_t total);
|
||||
|
|
Loading…
Reference in New Issue