diff --git a/src/background.c b/src/background.c
index 2ec345b..6dff321 100644
a
|
b
|
register_task_running (FileOpContext *ctx, pid_t pid, int fd, int to_child, |
88 | 88 | add_select_channel (fd, background_attention, ctx); |
89 | 89 | } |
90 | 90 | |
91 | | void |
92 | | unregister_task_running (pid_t pid, int fd) |
| 91 | int |
| 92 | destroy_task_and_return_fd (pid_t pid) |
93 | 93 | { |
94 | 94 | TaskList *p = task_list; |
95 | 95 | TaskList *prev = 0; |
… |
… |
unregister_task_running (pid_t pid, int fd) |
102 | 102 | task_list = p->next; |
103 | 103 | g_free (p->info); |
104 | 104 | g_free (p); |
105 | | break; |
| 105 | return p->fd; |
106 | 106 | } |
107 | 107 | prev = p; |
108 | 108 | p = p->next; |
109 | 109 | } |
| 110 | |
| 111 | /* pid not found */ |
| 112 | return -1; |
| 113 | } |
| 114 | |
| 115 | void |
| 116 | unregister_task_running (pid_t pid, int fd) |
| 117 | { |
| 118 | destroy_task_and_return_fd(pid); |
110 | 119 | delete_select_channel (fd); |
111 | 120 | } |
112 | 121 | |
| 122 | void |
| 123 | unregister_task_with_pid (pid_t pid) |
| 124 | { |
| 125 | int fd = destroy_task_and_return_fd(pid); |
| 126 | if (fd != -1) |
| 127 | delete_select_channel (fd); |
| 128 | } |
| 129 | |
113 | 130 | /* |
114 | 131 | * Try to make the Midnight Commander a background job |
115 | 132 | * |
… |
… |
background_attention (int fd, void *closure) |
216 | 233 | int have_ctx; |
217 | 234 | union |
218 | 235 | { |
| 236 | int (*have_ctx0)(int); |
219 | 237 | int (*have_ctx1)(int, char *); |
220 | 238 | int (*have_ctx2)(int, char *, char *); |
221 | 239 | int (*have_ctx3)(int, char *, char *, char *); |
222 | 240 | int (*have_ctx4)(int, char *, char *, char *, char *); |
223 | 241 | |
| 242 | int (*non_have_ctx0)(FileOpContext *, int); |
224 | 243 | int (*non_have_ctx1)(FileOpContext *, int, char *); |
225 | 244 | int (*non_have_ctx2)(FileOpContext *, int, char *, char *); |
226 | 245 | int (*non_have_ctx3)(FileOpContext *, int, char *, char *, char *); |
227 | 246 | int (*non_have_ctx4)(FileOpContext *, int, char *, char *, char *, char *); |
228 | 247 | |
| 248 | char * (*ret_str0)(); |
229 | 249 | char * (*ret_str1)(char *); |
230 | 250 | char * (*ret_str2)(char *, char *); |
231 | 251 | char * (*ret_str3)(char *, char *, char *); |
… |
… |
background_attention (int fd, void *closure) |
238 | 258 | char *data [MAXCALLARGS]; |
239 | 259 | ssize_t bytes; |
240 | 260 | struct TaskList *p; |
241 | | int to_child_fd; |
| 261 | int to_child_fd = -1; |
242 | 262 | enum ReturnType type; |
243 | 263 | |
244 | 264 | ctx = closure; |
… |
… |
background_attention (int fd, void *closure) |
285 | 305 | data [i][size] = 0; /* NULL terminate the blocks (they could be strings) */ |
286 | 306 | } |
287 | 307 | |
| 308 | /* Find child task info by descriptor */ |
| 309 | /* Find before call, because process can destroy self after */ |
| 310 | for (p = task_list; p; p = p->next) { |
| 311 | if (p->fd == fd) |
| 312 | break; |
| 313 | } |
| 314 | |
| 315 | if (p) to_child_fd = p->to_child_fd; |
| 316 | |
| 317 | if (to_child_fd == -1) |
| 318 | message (D_ERROR, _(" Background process error "), _(" Unknown error in child ")); |
| 319 | |
288 | 320 | /* Handle the call */ |
289 | 321 | if (type == Return_Integer){ |
290 | 322 | if (!have_ctx) |
291 | 323 | switch (argc){ |
| 324 | case 0: |
| 325 | result = routine.have_ctx0 (Background); |
| 326 | break; |
292 | 327 | case 1: |
293 | 328 | result = routine.have_ctx1 (Background, data [0]); |
294 | 329 | break; |
… |
… |
background_attention (int fd, void *closure) |
304 | 339 | } |
305 | 340 | else |
306 | 341 | switch (argc){ |
| 342 | case 0: |
| 343 | result = routine.non_have_ctx0 (ctx, Background); |
| 344 | break; |
307 | 345 | case 1: |
308 | 346 | result = routine.non_have_ctx1 (ctx, Background, data [0]); |
309 | 347 | break; |
… |
… |
background_attention (int fd, void *closure) |
318 | 356 | break; |
319 | 357 | } |
320 | 358 | |
321 | | /* Find child task info by descriptor */ |
322 | | for (p = task_list; p; p = p->next) { |
323 | | if (p->fd == fd) |
324 | | break; |
325 | | } |
326 | | |
327 | | to_child_fd = p->to_child_fd; |
328 | | |
329 | 359 | /* Send the result code and the value for shared variables */ |
330 | 360 | write (to_child_fd, &result, sizeof (int)); |
331 | | if (have_ctx) |
| 361 | if (have_ctx && to_child_fd != -1) |
332 | 362 | write (to_child_fd, ctx, sizeof (FileOpContext)); |
333 | 363 | } else if (type == Return_String) { |
334 | 364 | int len; |
… |
… |
background_attention (int fd, void *closure) |
338 | 368 | * parameter. Currently, this is not used here |
339 | 369 | */ |
340 | 370 | switch (argc){ |
| 371 | case 0: |
| 372 | resstr = routine.ret_str0 (); |
| 373 | break; |
341 | 374 | case 1: |
342 | 375 | resstr = routine.ret_str1 (data [0]); |
343 | 376 | break; |
diff --git a/src/background.h b/src/background.h
index 8ad4d54..2dc4bf4 100644
a
|
b
|
int parent_call (void *routine, struct FileOpContext *ctx, int argc, ...); |
32 | 32 | char *parent_call_string (void *routine, int argc, ...); |
33 | 33 | |
34 | 34 | void unregister_task_running (pid_t pid, int fd); |
| 35 | void unregister_task_with_pid (pid_t pid); |
35 | 36 | extern int we_are_background; |
36 | 37 | |
37 | 38 | #endif /* !WITH_BACKGROUND */ |
diff --git a/src/boxes.c b/src/boxes.c
index 80944e6..e6db6bd 100644
a
|
b
|
task_cb (int action) |
883 | 883 | sig = SIGKILL; |
884 | 884 | } |
885 | 885 | |
886 | | if (sig == SIGINT) |
| 886 | if (sig == SIGKILL) |
887 | 887 | unregister_task_running (tl->pid, tl->fd); |
888 | 888 | |
889 | 889 | kill (tl->pid, sig); |
diff --git a/src/file.c b/src/file.c
index de3d600..fe4f4be 100644
a
|
b
|
panel_operate_generate_prompt (const WPanel *panel, const int operation, |
1768 | 1768 | return g_strdup (format_string); |
1769 | 1769 | } |
1770 | 1770 | |
| 1771 | #ifdef WITH_BACKGROUND |
| 1772 | int end_bg_process (FileOpContext *ctx, enum OperationMode mode) { |
| 1773 | int pid = ctx->pid; |
| 1774 | ctx->pid = 0; |
| 1775 | |
| 1776 | unregister_task_with_pid(pid); |
| 1777 | // file_op_context_destroy(ctx); |
| 1778 | return 1; |
| 1779 | } |
| 1780 | #endif |
| 1781 | |
1771 | 1782 | /** |
1772 | 1783 | * panel_operate: |
1773 | 1784 | * |
… |
… |
panel_operate (void *source_panel, FileOperation operation, |
1911 | 1922 | } |
1912 | 1923 | } |
1913 | 1924 | |
| 1925 | /* Background also need ctx->ui, but not full */ |
| 1926 | if (do_bg) |
| 1927 | file_op_context_create_ui_without_init (ctx, 1); |
| 1928 | else |
| 1929 | file_op_context_create_ui (ctx, 1); |
| 1930 | |
1914 | 1931 | #ifdef WITH_BACKGROUND |
1915 | 1932 | /* Did the user select to do a background operation? */ |
1916 | 1933 | if (do_bg) { |
… |
… |
panel_operate (void *source_panel, FileOperation operation, |
1949 | 1966 | |
1950 | 1967 | /* Now, let's do the job */ |
1951 | 1968 | |
1952 | | if (do_bg) |
1953 | | ctx->ui = NULL; |
1954 | | else |
1955 | | file_op_context_create_ui (ctx, 1); |
1956 | | |
1957 | 1969 | /* This code is only called by the tree and panel code */ |
1958 | 1970 | if (single_entry) { |
1959 | 1971 | /* We now have ETA in all cases */ |
… |
… |
panel_operate (void *source_panel, FileOperation operation, |
2181 | 2193 | #ifdef WITH_BACKGROUND |
2182 | 2194 | /* Let our parent know we are saying bye bye */ |
2183 | 2195 | if (we_are_background) { |
| 2196 | int cur_pid = getpid(); |
| 2197 | /* Send pid to parent with child context, it is fork and |
| 2198 | don't modify real parent ctx */ |
| 2199 | ctx->pid = cur_pid; |
| 2200 | parent_call ((void *) end_bg_process, ctx, 0); |
| 2201 | |
2184 | 2202 | vfs_shut (); |
2185 | 2203 | _exit (0); |
2186 | 2204 | } |
diff --git a/src/filegui.c b/src/filegui.c
index 340e12a..e9a31cf 100644
a
|
b
|
check_progress_buttons (FileOpContext *ctx) |
222 | 222 | /* {{{ File progress display routines */ |
223 | 223 | |
224 | 224 | void |
225 | | file_op_context_create_ui (FileOpContext *ctx, int with_eta) |
| 225 | file_op_context_create_ui_without_init (FileOpContext *ctx, int with_eta) |
226 | 226 | { |
227 | 227 | FileOpContextUI *ui; |
228 | 228 | int x_size; |
… |
… |
file_op_context_create_ui (FileOpContext *ctx, int with_eta) |
293 | 293 | label_new (3, FCOPY_GAUGE_X, sixty)); |
294 | 294 | add_widget (ui->op_dlg, ui->file_label[0] = |
295 | 295 | label_new (3, FCOPY_LABEL_X, fifteen)); |
| 296 | } |
| 297 | |
| 298 | void |
| 299 | file_op_context_create_ui (FileOpContext *ctx, int with_eta) |
| 300 | { |
| 301 | FileOpContextUI *ui; |
| 302 | |
| 303 | g_return_if_fail (ctx != NULL); |
| 304 | g_return_if_fail (ctx->ui == NULL); |
| 305 | |
| 306 | file_op_context_create_ui_without_init(ctx, with_eta); |
| 307 | ui = ctx->ui; |
296 | 308 | |
297 | 309 | /* We will manage the dialog without any help, that's why |
298 | 310 | we have to call init_dlg */ |
diff --git a/src/fileopctx.h b/src/fileopctx.h
index 4943e28..305fe63 100644
a
|
b
|
enum OperationMode { |
144 | 144 | /* The following functions are implemented separately by each port */ |
145 | 145 | |
146 | 146 | void file_op_context_create_ui (FileOpContext *ctx, int with_eta); |
| 147 | void file_op_context_create_ui_without_init (FileOpContext *ctx, int with_eta); |
147 | 148 | void file_op_context_destroy_ui (FileOpContext *ctx); |
148 | 149 | |
149 | 150 | FileProgressStatus file_progress_show (FileOpContext *ctx, off_t done, off_t total); |