Re: [PATCH] Fix for tottaly broken background operations support - part 1



Hello,

On Wed, 13 Jul 2005, Pavel Tsekov wrote:

> The suggested patch addresses the problem by creating two pipes one used
> to send data from the parent to the child and the other in the
> opposite direction. All calls a adjusted accordingly.

The attached patch was incomplete it lacks the changes to background.h.
Here is the correct patch. Sorry for the inconvenience.
Index: src/background.c
===================================================================
RCS file: /cvsroot/mc/mc/src/background.c,v
retrieving revision 1.41
diff -u -p -r1.41 background.c
--- src/background.c	27 May 2005 03:35:15 -0000	1.41
+++ src/background.c	14 Jul 2005 07:09:47 -0000
@@ -51,8 +51,8 @@ enum ReturnType {
 /* If true, this is a background process */
 int we_are_background = 0;
 
-/* File descriptor for talking to our parent */
-static int parent_fd;
+/* Used by the child to talk to the parent. */
+static int parent_comm_pipe[2];
 
 #define MAXCALLARGS 4		/* Number of arguments supported */
 
@@ -61,19 +61,23 @@ struct TaskList *task_list = NULL;
 static int background_attention (int fd, void *closure);
     
 static void
-register_task_running (FileOpContext *ctx, pid_t pid, int fd, char *info)
+register_task_running (FileOpContext *ctx, pid_t pid, int fd[2], char *info)
 {
-    TaskList *new;
+    TaskList *new_task;
 
-    new = g_new (TaskList, 1);
-    new->pid   = pid;
-    new->info  = info;
-    new->state = Task_Running;
-    new->next  = task_list;
-    new->fd    = fd;
-    task_list  = new;
+    ctx->pid   = pid;
 
-    add_select_channel (fd, background_attention, ctx);
+    new_task = g_new (TaskList, 1);
+    new_task->pid   = pid;
+    new_task->info  = info;
+    new_task->state = Task_Running;
+    new_task->next  = task_list;
+    new_task->fd[0]    = fd[0];
+    new_task->fd[1]    = fd[1];
+    new_task->file_op_context = ctx; 
+    task_list  = new_task;
+
+    add_select_channel (fd[0], background_attention, new_task);
 }
 
 void
@@ -109,16 +113,25 @@ unregister_task_running (pid_t pid, int 
 int
 do_background (struct FileOpContext *ctx, char *info)
 {
-    int comm[2];		/* control connection stream */
     pid_t pid;
+    int parent_to_child_pipe[2];
+    int child_to_parent_pipe[2];
+
+    if (pipe (parent_to_child_pipe) == -1)
+	return -1;
 
-    if (pipe (comm) == -1)
+    if (pipe (child_to_parent_pipe) == -1) {
+	close (parent_to_child_pipe[0]);
+	close (parent_to_child_pipe[1]);
 	return -1;
+    }
 
     if ((pid = fork ()) == -1) {
     	int saved_errno = errno;
-    	(void) close (comm[0]);
-    	(void) close (comm[1]);
+	close (child_to_parent_pipe[0]);
+	close (child_to_parent_pipe[1]);
+	close (parent_to_child_pipe[0]);
+	close (parent_to_child_pipe[1]);
     	errno = saved_errno;
 	return -1;
     }
@@ -126,27 +139,34 @@ do_background (struct FileOpContext *ctx
     if (pid == 0) {
 	int nullfd;
 
-	close (comm[0]);
-	parent_fd = comm[1];
 	we_are_background = 1;
 	current_dlg = NULL;
 
-	/* Make stdin/stdout/stderr point somewhere */
-	close (0);
-	close (1);
-	close (2);
-
 	if ((nullfd = open ("/dev/null", O_RDWR)) != -1) {
-	    while (dup2 (nullfd, 0) == -1 && errno == EINTR);
-	    while (dup2 (nullfd, 1) == -1 && errno == EINTR);
-	    while (dup2 (nullfd, 2) == -1 && errno == EINTR);
+	    while (dup2 (nullfd, STDIN_FILENO) == -1 && errno == EINTR);
+	    while (dup2 (nullfd, STDOUT_FILENO) == -1 && errno == EINTR);
+	    while (dup2 (nullfd, STDERR_FILENO) == -1 && errno == EINTR);
 	}
+	/* TODO: else ... */
+
+	close (child_to_parent_pipe[0]);
+	close (parent_to_child_pipe[1]);
+
+	parent_comm_pipe[0] = parent_to_child_pipe[0];
+	parent_comm_pipe[1] = child_to_parent_pipe[1];
 
 	return 0;
     } else {
-	close (comm[1]);
-	ctx->pid = pid;
-	register_task_running (ctx, pid, comm[0], info);
+	int comm[2];
+
+	close (child_to_parent_pipe[1]);
+	close (parent_to_child_pipe[0]);
+
+	comm[0] = child_to_parent_pipe[0];
+	comm[1] = parent_to_child_pipe[1];
+
+	register_task_running (ctx, pid, comm, info);
+
 	return 1;
     }
 }
@@ -194,6 +214,7 @@ do_background (struct FileOpContext *ctx
 static int
 background_attention (int fd, void *closure)
 {
+    TaskList *task_info;
     FileOpContext *ctx;
     int have_ctx;
     void *routine;
@@ -202,7 +223,8 @@ background_attention (int fd, void *clos
     ssize_t bytes;
     enum ReturnType type;
 
-    ctx = closure;
+    task_info = closure;
+    ctx = task_info->file_op_context;
 
     bytes = read (fd, &routine, sizeof (routine));
     if (bytes == -1 || (size_t) bytes < (sizeof (routine))) {
@@ -246,6 +268,8 @@ background_attention (int fd, void *clos
 	data [i][size] = 0;	/* NULL terminate the blocks (they could be strings) */
     }
 
+    channels_down ();
+
     /* Handle the call */
     if (type == Return_Integer){
 	if (!have_ctx)
@@ -287,9 +311,9 @@ background_attention (int fd, void *clos
 	    }
 
 	/* Send the result code and the value for shared variables */
-	write (fd, &result, sizeof (int));
+	write (task_info->fd[1], &result, sizeof (int));
 	if (have_ctx)
-	    write (fd, ctx, sizeof (FileOpContext));
+	    write (task_info->fd[1], ctx, sizeof (FileOpContext));
     } else if (type == Return_String) {
 	int len;
 	char *resstr = NULL;
@@ -317,14 +341,14 @@ background_attention (int fd, void *clos
 	}
 	if (resstr){
 	    len = strlen (resstr);
-	    write (fd, &len, sizeof (len));
+	    write (task_info->fd[1], &len, sizeof (len));
 	    if (len){
-		write (fd, resstr, len);
+		write (task_info->fd[1], resstr, len);
 		g_free (resstr);
 	    }
 	} else {
 	    len = 0;
-	    write (fd, &len, sizeof (len));
+	    write (task_info->fd[1], &len, sizeof (len));
 	}
     }
     for (i = 0; i < argc; i++)
@@ -333,6 +357,9 @@ background_attention (int fd, void *clos
     do_refresh ();
     mc_refresh ();
     doupdate ();
+
+    channels_up ();
+
     return 0;
 }
 
@@ -352,13 +379,13 @@ parent_call_header (void *routine, int a
 
     have_ctx = (ctx != NULL);
 
-    write (parent_fd, &routine, sizeof (routine));
-    write (parent_fd, &argc, sizeof (int));
-    write (parent_fd, &type, sizeof (type));
-    write (parent_fd, &have_ctx, sizeof (have_ctx));
+    write (parent_comm_pipe[1], &routine, sizeof (routine));
+    write (parent_comm_pipe[1], &argc, sizeof (int));
+    write (parent_comm_pipe[1], &type, sizeof (type));
+    write (parent_comm_pipe[1], &have_ctx, sizeof (have_ctx));
 
     if (have_ctx)
-	write (parent_fd, ctx, sizeof (FileOpContext));
+	write (parent_comm_pipe[1], ctx, sizeof (FileOpContext));
 }
 
 int
@@ -375,12 +402,12 @@ parent_call (void *routine, struct FileO
 
 	len   = va_arg (ap, int);
 	value = va_arg (ap, void *);
-	write (parent_fd, &len, sizeof (int));
-	write (parent_fd, value, len);
+	write (parent_comm_pipe[1], &len, sizeof (int));
+	write (parent_comm_pipe[1], value, len);
     }
-    read (parent_fd, &i, sizeof (int));
+    read (parent_comm_pipe[0], &i, sizeof (int));
     if (ctx)
-	read (parent_fd, ctx, sizeof (FileOpContext));
+	read (parent_comm_pipe[0], ctx, sizeof (FileOpContext));
 
     return i;
 }
@@ -400,14 +427,14 @@ parent_call_string (void *routine, int a
 
 	len   = va_arg (ap, int);
 	value = va_arg (ap, void *);
-	write (parent_fd, &len, sizeof (int));
-	write (parent_fd, value, len);
+	write (parent_comm_pipe[1], &len, sizeof (int));
+	write (parent_comm_pipe[1], value, len);
     }
-    read (parent_fd, &i, sizeof (int));
+    read (parent_comm_pipe[0], &i, sizeof (int));
     if (!i)
 	return NULL;
     str = g_malloc (i + 1);
-    read (parent_fd, str, i);
+    read (parent_comm_pipe[0], str, i);
     str [i] = 0;
     return str;
 }
Index: src/background.h
===================================================================
RCS file: /cvsroot/mc/mc/src/background.h,v
retrieving revision 1.14
diff -u -p -r1.14 background.h
--- src/background.h	3 Dec 2004 19:17:47 -0000	1.14
+++ src/background.h	14 Jul 2005 07:09:47 -0000
@@ -8,8 +8,11 @@ enum TaskState {
     Task_Stopped
 };
 
+struct FileOpContext;
+
 typedef struct TaskList {
-    int fd;
+    struct FileOpContext *file_op_context;
+    int fd[2];
     pid_t pid;
     int state;
     char *info;
@@ -18,7 +21,6 @@ typedef struct TaskList {
 
 extern struct TaskList *task_list;
 
-struct FileOpContext;
 int do_background (struct FileOpContext *ctx, char *info);
 int parent_call (void *routine, struct FileOpContext *ctx, int argc, ...);
 char *parent_call_string (void *routine, int argc, ...);
Index: src/boxes.c
===================================================================
RCS file: /cvsroot/mc/mc/src/boxes.c,v
retrieving revision 1.91
diff -u -p -r1.91 boxes.c
--- src/boxes.c	14 Jun 2005 13:02:31 -0000	1.91
+++ src/boxes.c	14 Jul 2005 07:09:48 -0000
@@ -926,7 +926,7 @@ task_cb (int action)
     }
     
     if (sig == SIGINT)
-	unregister_task_running (tl->pid, tl->fd);
+	unregister_task_running (tl->pid, tl->fd[0]);
 
     kill (tl->pid, sig);
     listbox_remove_list (bg_list);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]