diff --git a/src/background.c b/src/background.c
index 9eadd29..812b114 100644
a
|
b
|
int we_are_background = 0; |
62 | 62 | /* File descriptor for talking to our parent */ |
63 | 63 | static int parent_fd; |
64 | 64 | |
| 65 | /* File descriptor for messages from our parent */ |
| 66 | static int from_parent_fd; |
| 67 | |
65 | 68 | #define MAXCALLARGS 4 /* Number of arguments supported */ |
66 | 69 | |
67 | 70 | struct TaskList *task_list = NULL; |
… |
… |
struct TaskList *task_list = NULL; |
69 | 72 | static int background_attention (int fd, void *closure); |
70 | 73 | |
71 | 74 | static void |
72 | | register_task_running (FileOpContext *ctx, pid_t pid, int fd, char *info) |
| 75 | register_task_running (FileOpContext *ctx, pid_t pid, int fd, int to_child, |
| 76 | char *info) |
73 | 77 | { |
74 | 78 | TaskList *new; |
75 | 79 | |
… |
… |
register_task_running (FileOpContext *ctx, pid_t pid, int fd, char *info) |
79 | 83 | new->state = Task_Running; |
80 | 84 | new->next = task_list; |
81 | 85 | new->fd = fd; |
| 86 | new->to_child_fd = to_child; |
82 | 87 | task_list = new; |
83 | 88 | |
84 | 89 | add_select_channel (fd, background_attention, ctx); |
… |
… |
int |
118 | 123 | do_background (struct FileOpContext *ctx, char *info) |
119 | 124 | { |
120 | 125 | int comm[2]; /* control connection stream */ |
| 126 | int back_comm[2]; /* back connection */ |
121 | 127 | pid_t pid; |
122 | 128 | |
123 | 129 | if (pipe (comm) == -1) |
124 | 130 | return -1; |
125 | 131 | |
| 132 | if (pipe (back_comm) == -1) |
| 133 | return -1; |
| 134 | |
126 | 135 | if ((pid = fork ()) == -1) { |
127 | 136 | int saved_errno = errno; |
128 | 137 | (void) close (comm[0]); |
129 | 138 | (void) close (comm[1]); |
| 139 | (void) close (back_comm[0]); |
| 140 | (void) close (back_comm[1]); |
130 | 141 | errno = saved_errno; |
131 | 142 | return -1; |
132 | 143 | } |
… |
… |
do_background (struct FileOpContext *ctx, char *info) |
134 | 145 | if (pid == 0) { |
135 | 146 | int nullfd; |
136 | 147 | |
137 | | close (comm[0]); |
138 | 148 | parent_fd = comm[1]; |
| 149 | from_parent_fd = back_comm[0]; |
| 150 | |
139 | 151 | we_are_background = 1; |
140 | 152 | current_dlg = NULL; |
141 | 153 | |
… |
… |
do_background (struct FileOpContext *ctx, char *info) |
152 | 164 | |
153 | 165 | return 0; |
154 | 166 | } else { |
155 | | close (comm[1]); |
156 | 167 | ctx->pid = pid; |
157 | | register_task_running (ctx, pid, comm[0], info); |
| 168 | register_task_running (ctx, pid, comm[0], back_comm[1], info); |
158 | 169 | return 1; |
159 | 170 | } |
160 | 171 | } |
… |
… |
background_attention (int fd, void *closure) |
227 | 238 | int argc, i, result, status; |
228 | 239 | char *data [MAXCALLARGS]; |
229 | 240 | ssize_t bytes; |
| 241 | struct TaskList *p; |
| 242 | int to_child_fd; |
230 | 243 | enum ReturnType type; |
231 | 244 | |
232 | 245 | ctx = closure; |
… |
… |
background_attention (int fd, void *closure) |
306 | 319 | break; |
307 | 320 | } |
308 | 321 | |
| 322 | /* Find child task info by descriptor */ |
| 323 | for (p = task_list; p; p = p->next) { |
| 324 | if (p->fd == fd) |
| 325 | break; |
| 326 | } |
| 327 | |
| 328 | to_child_fd = p->to_child_fd; |
| 329 | |
309 | 330 | /* Send the result code and the value for shared variables */ |
310 | | write (fd, &result, sizeof (int)); |
| 331 | write (to_child_fd, &result, sizeof (int)); |
311 | 332 | if (have_ctx) |
312 | | write (fd, ctx, sizeof (FileOpContext)); |
| 333 | write (to_child_fd, ctx, sizeof (FileOpContext)); |
313 | 334 | } else if (type == Return_String) { |
314 | 335 | int len; |
315 | 336 | char *resstr = NULL; |
… |
… |
background_attention (int fd, void *closure) |
334 | 355 | } |
335 | 356 | if (resstr){ |
336 | 357 | len = strlen (resstr); |
337 | | write (fd, &len, sizeof (len)); |
| 358 | write (to_child_fd, &len, sizeof (len)); |
338 | 359 | if (len){ |
339 | | write (fd, resstr, len); |
| 360 | write (to_child_fd, resstr, len); |
340 | 361 | g_free (resstr); |
341 | 362 | } |
342 | 363 | } else { |
343 | 364 | len = 0; |
344 | | write (fd, &len, sizeof (len)); |
| 365 | write (to_child_fd, &len, sizeof (len)); |
345 | 366 | } |
346 | 367 | } |
347 | 368 | for (i = 0; i < argc; i++) |
… |
… |
parent_call (void *routine, struct FileOpContext *ctx, int argc, ...) |
395 | 416 | write (parent_fd, &len, sizeof (int)); |
396 | 417 | write (parent_fd, value, len); |
397 | 418 | } |
398 | | read (parent_fd, &i, sizeof (int)); |
| 419 | |
| 420 | read (from_parent_fd, &i, sizeof (int)); |
399 | 421 | if (ctx) |
400 | | read (parent_fd, ctx, sizeof (FileOpContext)); |
| 422 | read (from_parent_fd, ctx, sizeof (FileOpContext)); |
401 | 423 | |
402 | 424 | return i; |
403 | 425 | } |
… |
… |
parent_call_string (void *routine, int argc, ...) |
420 | 442 | write (parent_fd, &len, sizeof (int)); |
421 | 443 | write (parent_fd, value, len); |
422 | 444 | } |
423 | | read (parent_fd, &i, sizeof (int)); |
| 445 | read (from_parent_fd, &i, sizeof (int)); |
424 | 446 | if (!i) |
425 | 447 | return NULL; |
426 | 448 | str = g_malloc (i + 1); |
427 | | read (parent_fd, str, i); |
| 449 | read (from_parent_fd, str, i); |
428 | 450 | str [i] = 0; |
429 | 451 | return str; |
430 | 452 | } |
diff --git a/src/background.h b/src/background.h
index 266240d..8ad4d54 100644
a
|
b
|
enum TaskState { |
17 | 17 | |
18 | 18 | typedef struct TaskList { |
19 | 19 | int fd; |
| 20 | int to_child_fd; |
20 | 21 | pid_t pid; |
21 | 22 | int state; |
22 | 23 | char *info; |
diff --git a/src/file.c b/src/file.c
index 15d5f70..73e4305 100644
a
|
b
|
enum { |
381 | 381 | }; |
382 | 382 | |
383 | 383 | static FileProgressStatus |
384 | | warn_same_file (const char *fmt, const char *a, const char *b) |
| 384 | real_warn_same_file (enum OperationMode mode, const char *fmt, |
| 385 | const char *a, const char *b) |
385 | 386 | { |
386 | 387 | char *msg; |
387 | 388 | int result = 0; |
| 389 | const char *head_msg; |
| 390 | |
| 391 | head_msg = mode == Foreground ? MSG_ERROR : |
| 392 | _(" Background process error "); |
| 393 | |
388 | 394 | msg = g_strdup_printf (fmt, a, b); |
389 | | result = query_dialog (MSG_ERROR, msg, D_ERROR, 2, _("&Skip"), _("&Abort")); |
| 395 | result = query_dialog (head_msg, msg, D_ERROR, 2, _("&Skip"), _("&Abort")); |
390 | 396 | g_free(msg); |
391 | 397 | do_refresh (); |
392 | 398 | if ( result ) { /* 1 == Abort */ |
… |
… |
warn_same_file (const char *fmt, const char *a, const char *b) |
396 | 402 | } |
397 | 403 | } |
398 | 404 | |
| 405 | #ifdef WITH_BACKGROUND |
| 406 | static FileProgressStatus |
| 407 | warn_same_file (const char *fmt, const char *a, const char *b) |
| 408 | { |
| 409 | union { |
| 410 | void *p; |
| 411 | FileProgressStatus (*f) (enum OperationMode, const char *fmt, |
| 412 | const char *a, const char *b); |
| 413 | } pntr; |
| 414 | pntr.f = real_warn_same_file; |
| 415 | |
| 416 | if (we_are_background) |
| 417 | return parent_call (pntr.p, NULL, 3, strlen (fmt), |
| 418 | fmt, strlen(a), a, strlen(b), b); |
| 419 | else |
| 420 | return real_warn_same_file (Foreground, fmt, a, b); |
| 421 | } |
| 422 | #else |
| 423 | static FileProgressStatus |
| 424 | warn_same_file (const char *fmt, const char *a, const char *b) |
| 425 | { |
| 426 | return real_warn_same_file (Foreground, fmt, a, b); |
| 427 | } |
| 428 | #endif |
| 429 | |
399 | 430 | FileProgressStatus |
400 | 431 | copy_file_file (FileOpContext *ctx, const char *src_path, const char *dst_path, |
401 | 432 | int ask_overwrite, off_t *progress_count, |