vte r2041 - in trunk: . src



Author: cpwilson
Date: Fri May  9 19:50:37 2008
New Revision: 2041
URL: http://svn.gnome.org/viewvc/vte?rev=2041&view=rev

Log:
2008-05-09  Chris Wilson  <chris chris-wilson co uk>

    Fix "GLib-CRITICAL **: g_io_add_watch_full: assertion
                           `channel != NULL' failed"

    * src/debug.c (_vte_debug_parse_string):
    * src/debug.h:
    * src/vte-private.h:
    * src/vte.c (vte_terminal_emit_adjustment_changed),
    (_vte_terminal_adjust_adjustments_full),
    (vte_terminal_scroll_lines), (vte_terminal_maybe_scroll_to_bottom),
    (_vte_terminal_insert_char), (vte_terminal_catch_child_exited),
    (mark_input_source_invalid), (_vte_terminal_connect_pty_read),
    (mark_output_source_invalid), (_vte_terminal_connect_pty_write),
    (_vte_terminal_disconnect_pty_read),
    (_vte_terminal_disconnect_pty_write), (_vte_terminal_fork_basic),
    (vte_terminal_eof), (_vte_terminal_enable_input_source),
    (vte_terminal_io_read), (vte_terminal_handle_scroll),
    (vte_terminal_finalize), (vte_terminal_class_init),
    (vte_terminal_set_pty), (process_timeout), (update_repeat_timeout),
    (update_timeout):
    It was possible for _vte_terminal_enable_input_source() to be called
    after the input closed with G_IO_HUP. The minimal change would just
    have been to add a guard to check the pty_master was still valid
    before reattaching the source. Instead I removed the redundant
    duplication of the input and output channels and added lots of
    debugging.



Modified:
   trunk/ChangeLog
   trunk/src/debug.c
   trunk/src/debug.h
   trunk/src/vte-private.h
   trunk/src/vte.c

Modified: trunk/src/debug.c
==============================================================================
--- trunk/src/debug.c	(original)
+++ trunk/src/debug.c	Fri May  9 19:50:37 2008
@@ -40,6 +40,9 @@
 			if (g_ascii_strcasecmp(flags[i], "IO") == 0) {
 				_vte_debug_flags |= VTE_DEBUG_IO;
 			} else
+			if (g_ascii_strcasecmp(flags[i], "ADJ") == 0) {
+				_vte_debug_flags |= VTE_DEBUG_ADJ;
+			} else
 			if (g_ascii_strcasecmp(flags[i], "UPDATES") == 0) {
 				_vte_debug_flags |= VTE_DEBUG_UPDATES;
 			} else

Modified: trunk/src/debug.h
==============================================================================
--- trunk/src/debug.h	(original)
+++ trunk/src/debug.h	Fri May  9 19:50:37 2008
@@ -45,7 +45,8 @@
 	VTE_DEBUG_CELLS		= 1 << 15,
 	VTE_DEBUG_TIMEOUT	= 1 << 16,
 	VTE_DEBUG_DRAW		= 1 << 17,
-	VTE_DEBUG_ALLY		= 1 << 18
+	VTE_DEBUG_ALLY		= 1 << 18,
+	VTE_DEBUG_ADJ		= 1 << 19
 } VteDebugFlags;
 
 void _vte_debug_parse_string(const char *string);

Modified: trunk/src/vte-private.h
==============================================================================
--- trunk/src/vte-private.h	(original)
+++ trunk/src/vte-private.h	Fri May  9 19:50:37 2008
@@ -177,11 +177,10 @@
 	/* PTY handling data. */
 	const char *shell;		/* shell we started */
 	int pty_master;			/* pty master descriptor */
-	GIOChannel *pty_input;		/* master input watch */
+	GIOChannel *pty_channel;	/* master channel */
 	guint pty_input_source;
-	gboolean pty_input_active;
-	GIOChannel *pty_output;		/* master output watch */
 	guint pty_output_source;
+	gboolean pty_input_active;
 	GPid pty_pid;			/* pid of child using pty slave */
 	VteReaper *pty_reaper;
 

Modified: trunk/src/vte.c
==============================================================================
--- trunk/src/vte.c	(original)
+++ trunk/src/vte.c	Fri May  9 19:50:37 2008
@@ -1621,7 +1621,7 @@
 
 		v = _vte_ring_delta (screen->row_data);
 		if (terminal->adjustment->lower != v) {
-			_vte_debug_print(VTE_DEBUG_IO,
+			_vte_debug_print(VTE_DEBUG_ADJ,
 					"Changing lower bound from %.0f to %ld\n",
 					terminal->adjustment->lower,
 					v);
@@ -1634,7 +1634,7 @@
 		v = MAX(_vte_ring_next(screen->row_data),
 				screen->cursor_current.row + 1);
 		if (terminal->adjustment->upper != v) {
-			_vte_debug_print(VTE_DEBUG_IO,
+			_vte_debug_print(VTE_DEBUG_ADJ,
 					"Changing upper bound from %.0f to %ld\n",
 					terminal->adjustment->upper,
 					v);
@@ -1727,7 +1727,7 @@
 
 	/* The step increment should always be one. */
 	if (terminal->adjustment->step_increment != 1) {
-		_vte_debug_print(VTE_DEBUG_IO,
+		_vte_debug_print(VTE_DEBUG_ADJ,
 				"Changing step increment from %.0lf to %ld\n",
 				terminal->adjustment->step_increment,
 				terminal->row_count);
@@ -1738,7 +1738,7 @@
 	/* Set the number of rows the user sees to the number of rows the
 	 * user sees. */
 	if (terminal->adjustment->page_size != terminal->row_count) {
-		_vte_debug_print(VTE_DEBUG_IO,
+		_vte_debug_print(VTE_DEBUG_ADJ,
 				"Changing page size from %.0f to %ld\n",
 				terminal->adjustment->page_size,
 				terminal->row_count);
@@ -1749,7 +1749,7 @@
 	/* Clicking in the empty area should scroll one screen, so set the
 	 * page size to the number of visible rows. */
 	if (terminal->adjustment->page_increment != terminal->row_count) {
-		_vte_debug_print(VTE_DEBUG_IO,
+		_vte_debug_print(VTE_DEBUG_ADJ,
 				"Changing page increment from "
 				"%.0f to %ld\n",
 				terminal->adjustment->page_increment,
@@ -1770,7 +1770,7 @@
 vte_terminal_scroll_lines(VteTerminal *terminal, gint lines)
 {
 	glong destination;
-	_vte_debug_print(VTE_DEBUG_IO, "Scrolling %d lines.\n", lines);
+	_vte_debug_print(VTE_DEBUG_ADJ, "Scrolling %d lines.\n", lines);
 	/* Calculate the ideal position where we want to be before clamping. */
 	destination = terminal->pvt->screen->scroll_delta;
 	destination += lines;
@@ -1804,7 +1804,7 @@
 	glong delta;
 	delta = terminal->pvt->screen->insert_delta;
 	vte_terminal_queue_adjustment_value_changed (terminal, delta);
-	_vte_debug_print(VTE_DEBUG_IO,
+	_vte_debug_print(VTE_DEBUG_ADJ,
 			"Snapping to bottom of screen\n");
 }
 
@@ -2551,7 +2551,7 @@
 	col = screen->cursor_current.col;
 	if (G_UNLIKELY (col + columns > terminal->column_count)) {
 		if (terminal->pvt->flags.am) {
-			_vte_debug_print(VTE_DEBUG_IO,
+			_vte_debug_print(VTE_DEBUG_ADJ,
 					"Autowrapping before character\n");
 			/* Wrap. */
 			col = screen->cursor_current.col = 0;
@@ -2567,7 +2567,7 @@
 		line_wrapped = TRUE;
 	}
 
-	_vte_debug_print(VTE_DEBUG_IO|VTE_DEBUG_PARSE,
+	_vte_debug_print(VTE_DEBUG_PARSE,
 			"Inserting %ld '%c' (%d/%d) (%ld+%d, %ld), delta = %ld; ",
 			(long)c, c < 256 ? c : ' ',
 			screen->defaults.attr.fore,
@@ -2646,7 +2646,7 @@
 	/* We added text, so make a note of it. */
 	terminal->pvt->text_inserted_flag = TRUE;
 
-	_vte_debug_print(VTE_DEBUG_IO|VTE_DEBUG_PARSE,
+	_vte_debug_print(VTE_DEBUG_ADJ|VTE_DEBUG_PARSE,
 			"insertion delta => %ld.\n",
 			(long)screen->insert_delta);
 	return line_wrapped;
@@ -2760,6 +2760,10 @@
 		/* Close out the PTY. */
 		_vte_terminal_disconnect_pty_read(terminal);
 		_vte_terminal_disconnect_pty_write(terminal);
+		if (terminal->pvt->pty_channel != NULL) {
+			g_io_channel_unref (terminal->pvt->pty_channel);
+			terminal->pvt->pty_channel = NULL;
+		}
 		if (terminal->pvt->pty_master != -1) {
 			_vte_pty_close(terminal->pvt->pty_master);
 			close(terminal->pvt->pty_master);
@@ -2788,21 +2792,20 @@
 
 static void mark_input_source_invalid(VteTerminal *terminal)
 {
+	_vte_debug_print (VTE_DEBUG_IO, "removed poll of vte_terminal_io_read\n");
 	terminal->pvt->pty_input_source = VTE_INVALID_SOURCE;
 }
 static void
 _vte_terminal_connect_pty_read(VteTerminal *terminal)
 {
-	if (terminal->pvt->pty_master == -1) {
+	if (terminal->pvt->pty_channel == NULL) {
 		return;
 	}
-	if (terminal->pvt->pty_input == NULL) {
-		terminal->pvt->pty_input =
-			g_io_channel_unix_new(terminal->pvt->pty_master);
-	}
+
 	if (terminal->pvt->pty_input_source == VTE_INVALID_SOURCE) {
+		_vte_debug_print (VTE_DEBUG_IO, "polling vte_terminal_io_read\n");
 		terminal->pvt->pty_input_source =
-			g_io_add_watch_full(terminal->pvt->pty_input,
+			g_io_add_watch_full(terminal->pvt->pty_channel,
 					    VTE_CHILD_INPUT_PRIORITY,
 					    G_IO_IN | G_IO_HUP,
 					    (GIOFunc) vte_terminal_io_read,
@@ -2813,40 +2816,38 @@
 
 static void mark_output_source_invalid(VteTerminal *terminal)
 {
+	_vte_debug_print (VTE_DEBUG_IO, "removed poll of vte_terminal_io_write\n");
 	terminal->pvt->pty_output_source = VTE_INVALID_SOURCE;
 }
 static void
 _vte_terminal_connect_pty_write(VteTerminal *terminal)
 {
-	if (terminal->pvt->pty_master == -1) {
+	if (terminal->pvt->pty_channel == NULL) {
 		return;
 	}
-	if (terminal->pvt->pty_output == NULL) {
-		terminal->pvt->pty_output =
-			g_io_channel_unix_new(terminal->pvt->pty_master);
-	}
+
 	if (terminal->pvt->pty_output_source == VTE_INVALID_SOURCE) {
-		terminal->pvt->pty_output_source =
-			g_io_add_watch_full(terminal->pvt->pty_output,
-					    VTE_CHILD_OUTPUT_PRIORITY,
-					    G_IO_OUT,
-					    (GIOFunc) vte_terminal_io_write,
-					    terminal,
-					    (GDestroyNotify) mark_output_source_invalid);
+		if (vte_terminal_io_write (terminal->pvt->pty_channel,
+					     G_IO_OUT,
+					     terminal))
+		{
+			_vte_debug_print (VTE_DEBUG_IO, "polling vte_terminal_io_write\n");
+			terminal->pvt->pty_output_source =
+				g_io_add_watch_full(terminal->pvt->pty_channel,
+						    VTE_CHILD_OUTPUT_PRIORITY,
+						    G_IO_OUT,
+						    (GIOFunc) vte_terminal_io_write,
+						    terminal,
+						    (GDestroyNotify) mark_output_source_invalid);
+		}
 	}
 }
 
 static void
 _vte_terminal_disconnect_pty_read(VteTerminal *terminal)
 {
-	if (terminal->pvt->pty_master == -1) {
-		return;
-	}
-	if (terminal->pvt->pty_input != NULL) {
-		g_io_channel_unref(terminal->pvt->pty_input);
-		terminal->pvt->pty_input = NULL;
-	}
 	if (terminal->pvt->pty_input_source != VTE_INVALID_SOURCE) {
+		_vte_debug_print (VTE_DEBUG_IO, "disconnecting poll of vte_terminal_io_read\n");
 		g_source_remove(terminal->pvt->pty_input_source);
 		terminal->pvt->pty_input_source = VTE_INVALID_SOURCE;
 	}
@@ -2855,14 +2856,9 @@
 static void
 _vte_terminal_disconnect_pty_write(VteTerminal *terminal)
 {
-	if (terminal->pvt->pty_master == -1) {
-		return;
-	}
-	if (terminal->pvt->pty_output != NULL) {
-		g_io_channel_unref(terminal->pvt->pty_output);
-		terminal->pvt->pty_output = NULL;
-	}
 	if (terminal->pvt->pty_output_source != VTE_INVALID_SOURCE) {
+		_vte_debug_print (VTE_DEBUG_IO, "disconnecting poll of vte_terminal_io_write\n");
+
 		g_source_remove(terminal->pvt->pty_output_source);
 		terminal->pvt->pty_output_source = VTE_INVALID_SOURCE;
 	}
@@ -2876,7 +2872,7 @@
 			 gboolean lastlog, gboolean utmp, gboolean wtmp)
 {
 	char **env_add;
-	int i;
+	int i, fd;
 	pid_t pid;
 	VteReaper *reaper;
 
@@ -2892,6 +2888,9 @@
 	env_add[i + 1] = NULL;
 
 	/* Close any existing ptys. */
+	if (terminal->pvt->pty_channel != NULL) {
+		g_io_channel_unref (terminal->pvt->pty_channel);
+	}
 	if (terminal->pvt->pty_master != -1) {
 		_vte_pty_close(terminal->pvt->pty_master);
 		close(terminal->pvt->pty_master);
@@ -2899,26 +2898,22 @@
 
 	/* Open the new pty. */
 	pid = -1;
-	i = _vte_pty_open(&pid, env_add, command, argv, directory,
+	fd = _vte_pty_open(&pid, env_add, command, argv, directory,
 			  terminal->column_count, terminal->row_count,
 			  lastlog, utmp, wtmp);
-	switch (i) {
-	case -1:
+	if (pid == -1 || fd == -1) {
+		g_strfreev(env_add);
 		return -1;
-		break;
-	default:
-		if (pid != 0) {
-			terminal->pvt->pty_master = i;
-		       _vte_terminal_setup_utf8(terminal);
-		}
 	}
 
 	/* If we successfully started the process, set up to listen for its
 	 * output. */
-	if ((pid != -1) && (pid != 0)) {
+	if (pid != 0) {
 		/* Set this as the child's pid. */
 		terminal->pvt->pty_pid = pid;
 
+		vte_terminal_set_pty (terminal, fd);
+
 		/* Catch a child-exited signal from the child pid. */
 		reaper = vte_reaper_get();
 		vte_reaper_add_child(pid);
@@ -2935,23 +2930,6 @@
 			terminal->pvt->pty_reaper = reaper;
 		} else
 			g_object_unref(reaper);
-
-		/* Set the pty to be non-blocking. */
-		i = fcntl(terminal->pvt->pty_master, F_GETFL);
-		if ((i & O_NONBLOCK) == 0) {
-			fcntl(terminal->pvt->pty_master, F_SETFL, i | O_NONBLOCK);
-		}
-
-		/* Set the PTY size. */
-		vte_terminal_set_size(terminal,
-				      terminal->column_count,
-				      terminal->row_count);
-		if (GTK_WIDGET_REALIZED(terminal)) {
-			gtk_widget_queue_resize_no_redraw(&terminal->widget);
-		}
-
-		/* Open a channel to listen for input on. */
-		_vte_terminal_connect_pty_read(terminal);
 	}
 
 	/* Clean up. */
@@ -3062,12 +3040,13 @@
 {
 	/* Close the connections to the child -- note that the source channel
 	 * has already been dereferenced. */
-	if (channel == terminal->pvt->pty_input) {
-		_vte_terminal_disconnect_pty_read(terminal);
-	}
 
-	/* Close out the PTY. */
+	_vte_terminal_disconnect_pty_read(terminal);
 	_vte_terminal_disconnect_pty_write(terminal);
+	if (terminal->pvt->pty_channel != NULL) {
+		g_io_channel_unref (terminal->pvt->pty_channel);
+		terminal->pvt->pty_channel = NULL;
+	}
 	if (terminal->pvt->pty_master != -1) {
 		_vte_pty_close(terminal->pvt->pty_master);
 		close(terminal->pvt->pty_master);
@@ -3578,9 +3557,14 @@
 static inline void
 _vte_terminal_enable_input_source (VteTerminal *terminal)
 {
+	if (terminal->pvt->pty_channel == NULL) {
+		return;
+	}
+
 	if (terminal->pvt->pty_input_source == VTE_INVALID_SOURCE) {
+		_vte_debug_print (VTE_DEBUG_IO, "polling vte_terminal_io_read\n");
 		terminal->pvt->pty_input_source =
-			g_io_add_watch_full(terminal->pvt->pty_input,
+			g_io_add_watch_full(terminal->pvt->pty_channel,
 					    VTE_CHILD_INPUT_PRIORITY,
 					    G_IO_IN | G_IO_HUP,
 					    (GIOFunc) vte_terminal_io_read,
@@ -3687,6 +3671,11 @@
 		terminal->pvt->pty_input_active = len != 0;
 		terminal->pvt->input_bytes = bytes;
 		again = bytes < max_bytes;
+
+		_vte_debug_print (VTE_DEBUG_IO, "read %d/%d bytes, again? %s, active? %s\n",
+				bytes, max_bytes,
+				again ? "yes" : "no",
+				terminal->pvt->pty_input_active ? "yes" : "no");
 	}
 
 	/* Error? */
@@ -7087,14 +7076,14 @@
 	}
 
 	if (dy != 0) {
-		_vte_debug_print(VTE_DEBUG_IO,
+		_vte_debug_print(VTE_DEBUG_ADJ,
 			    "Scrolling by %ld\n", dy);
 		_vte_terminal_scroll_region(terminal, screen->scroll_delta,
 					   terminal->row_count, -dy);
 		vte_terminal_emit_text_scrolled(terminal, dy);
 		_vte_terminal_queue_contents_changed(terminal);
 	} else {
-		_vte_debug_print(VTE_DEBUG_IO, "Not scrolling\n");
+		_vte_debug_print(VTE_DEBUG_ADJ, "Not scrolling\n");
 	}
 }
 
@@ -7915,6 +7904,9 @@
 	}
 	_vte_terminal_disconnect_pty_read(terminal);
 	_vte_terminal_disconnect_pty_write(terminal);
+	if (terminal->pvt->pty_channel != NULL) {
+		g_io_channel_unref (terminal->pvt->pty_channel);
+	}
 	if (terminal->pvt->pty_master != -1) {
 		_vte_pty_close(terminal->pvt->pty_master);
 		close(terminal->pvt->pty_master);
@@ -10439,7 +10431,7 @@
 					"  -  gdk_window_process_updates\n"
 					"  +  vte_terminal_expose\n"
 					"  =  vte_terminal_paint\n"
-					"  ]} start update_timeout\n"
+					"  ]} end update_timeout\n"
 					"  >  end process_timeout\n");
 	}
 #endif
@@ -12010,11 +12002,16 @@
 	       return;
        }
 
+       if (terminal->pvt->pty_channel != NULL) {
+	       g_io_channel_unref (terminal->pvt->pty_channel);
+       }
        if (terminal->pvt->pty_master != -1) {
                _vte_pty_close(terminal->pvt->pty_master);
                close(terminal->pvt->pty_master);
        }
        terminal->pvt->pty_master = pty_master;
+       terminal->pvt->pty_channel = g_io_channel_unix_new (pty_master);
+       g_io_channel_set_close_on_unref (terminal->pvt->pty_channel, FALSE);
 
 
        /* Set the pty to be non-blocking. */
@@ -12031,9 +12028,6 @@
 
        /* Open channels to listen for input on. */
        _vte_terminal_connect_pty_read(terminal);
-
-       /* Open channels to write output to. */
-       _vte_terminal_connect_pty_write(terminal);
 }
 
 /* We need this bit of glue to ensure that accessible objects will always
@@ -12330,11 +12324,11 @@
 		if (l != active_terminals) {
 			_vte_debug_print (VTE_DEBUG_WORK, "T");
 		}
-		if (terminal->pvt->pty_input != NULL) {
+		if (terminal->pvt->pty_channel != NULL) {
 			if (terminal->pvt->pty_input_active ||
 					terminal->pvt->pty_input_source == VTE_INVALID_SOURCE) {
 				terminal->pvt->pty_input_active = FALSE;
-				vte_terminal_io_read (terminal->pvt->pty_input,
+				vte_terminal_io_read (terminal->pvt->pty_channel,
 						G_IO_IN, terminal);
 			}
 			_vte_terminal_enable_input_source (terminal);
@@ -12454,11 +12448,11 @@
 		if (l != active_terminals) {
 			_vte_debug_print (VTE_DEBUG_WORK, "T");
 		}
-		if (terminal->pvt->pty_input != NULL) {
+		if (terminal->pvt->pty_channel != NULL) {
 			if (terminal->pvt->pty_input_active ||
 					terminal->pvt->pty_input_source == VTE_INVALID_SOURCE) {
 				terminal->pvt->pty_input_active = FALSE;
-				vte_terminal_io_read (terminal->pvt->pty_input,
+				vte_terminal_io_read (terminal->pvt->pty_channel,
 						G_IO_IN, terminal);
 			}
 			_vte_terminal_enable_input_source (terminal);
@@ -12558,11 +12552,11 @@
 		if (l != active_terminals) {
 			_vte_debug_print (VTE_DEBUG_WORK, "T");
 		}
-		if (terminal->pvt->pty_input != NULL) {
+		if (terminal->pvt->pty_channel != NULL) {
 			if (terminal->pvt->pty_input_active ||
 					terminal->pvt->pty_input_source == VTE_INVALID_SOURCE) {
 				terminal->pvt->pty_input_active = FALSE;
-				vte_terminal_io_read (terminal->pvt->pty_input,
+				vte_terminal_io_read (terminal->pvt->pty_channel,
 						G_IO_IN, terminal);
 			}
 			_vte_terminal_enable_input_source (terminal);



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