[anjuta-extras/gnome-2-30: 4/6] profiler: Fix bgo 615360



commit 4f1aaddd6c1cbc372257668ab8c9a44962ec9c44
Author: James Liggett <jrliggett cox net>
Date:   Mon Apr 12 19:11:08 2010 -0700

    profiler: Fix bgo 615360
    
    Replace fgets and other C standard IO functions with GIOChannel.
    Not only does using this method negate the need for PATH_MAX, it also drops any
    reliance on fixed-sized buffers, so that lines can be any length, not limited by
    any arbitrary limit.

 plugins/profiler/gprof-call-graph.c   |   39 +++++++++++++++++++++++---------
 plugins/profiler/gprof-call-graph.h   |    2 +-
 plugins/profiler/gprof-flat-profile.c |   36 ++++++++++++++++++++++--------
 plugins/profiler/gprof-flat-profile.h |    2 +-
 plugins/profiler/gprof-profile-data.c |    7 +++--
 5 files changed, 60 insertions(+), 26 deletions(-)
---
diff --git a/plugins/profiler/gprof-call-graph.c b/plugins/profiler/gprof-call-graph.c
index 2814dbb..a436911 100644
--- a/plugins/profiler/gprof-call-graph.c
+++ b/plugins/profiler/gprof-call-graph.c
@@ -228,37 +228,52 @@ gprof_call_graph_get_type (void)
 }
 
 GProfCallGraph *
-gprof_call_graph_new (FILE *stream, GProfFlatProfile *flat_profile)
+gprof_call_graph_new (GIOChannel *stream, GProfFlatProfile *flat_profile)
 {
-	gchar buffer[PATH_MAX];
+	gchar *buffer;
+	gsize line_term_pos;
+	gboolean found_call_graph;
 	gchar **fields;
-	size_t length;
 	GProfCallGraphBlock *block;
 	GProfCallGraphBlockEntry *entry;
 	gchar *entry_name;
 	GProfCallGraph *call_graph;
-	gboolean found_primary = FALSE;  
+	gboolean found_primary;  
 	
 	call_graph = g_object_new (GPROF_CALL_GRAPH_TYPE, NULL);
+	found_call_graph = FALSE;
+	found_primary = FALSE;
 	
 	/* Find the beginning of the call graph. The call graph begins with
      * "index" */
 	do 
 	{
 		/* Don't loop infinitely if we don't have any data */
-		if (!fgets (buffer, PATH_MAX, stream))
+		if (g_io_channel_read_line (stream, &buffer, NULL, &line_term_pos, 
+		                            NULL) != G_IO_STATUS_NORMAL)
+		{
 			return call_graph;
+		}
+
+		found_call_graph = (strncmp ("index", buffer, 5) == 0);
+		g_free (buffer);
 			
-	} while (strncmp ("index", buffer, 5) != 0);
+	} while (!found_call_graph);
 	
 	block = NULL; 
 	
-	while (fgets (buffer, PATH_MAX, stream))
+	while (g_io_channel_read_line (stream, &buffer, NULL, &line_term_pos, 
+		                            NULL) == G_IO_STATUS_NORMAL)
 	{
+		g_print ("Line data: %s\n", buffer);
+
 		/* If the first character of the line is 12, that's the end of the call
 		 * graph. */
 		if (buffer[0] == 12)
+		{
+			g_free (buffer);
 			break;
+		}
 		
 		if (!block)
 		{
@@ -266,9 +281,8 @@ gprof_call_graph_new (FILE *stream, GProfFlatProfile *flat_profile)
 			found_primary = FALSE;
 		}
 		
-		/* Remove the newline from the buffer */
-		length = strlen (buffer);
-		buffer[length - 1] = 0;
+		/* Remove the line terminator from the buffer */
+		buffer[line_term_pos] = 0;
 		
 		/* If we encounter the block separator, add the block to the graph */
 		if (strcmp (BLOCK_SEPARATOR, buffer) == 0)
@@ -298,14 +312,17 @@ gprof_call_graph_new (FILE *stream, GProfFlatProfile *flat_profile)
 				/* If we don't get any fields, that means this is a 
 				 * placeholder line.*/
 				if (!fields)
+				{
+					g_free (buffer);
 					continue;
+				}
 				
 				entry = gprof_call_graph_block_secondary_entry_new (fields);
 				entry_name = gprof_call_graph_block_entry_get_name (entry);
 				
 				g_strfreev (fields);
 				
-				if (gprof_flat_profile_find_entry(flat_profile, entry_name))
+				if (gprof_flat_profile_find_entry (flat_profile, entry_name))
 				{
 					if (found_primary)
 						gprof_call_graph_block_add_child_entry (block, entry);
diff --git a/plugins/profiler/gprof-call-graph.h b/plugins/profiler/gprof-call-graph.h
index d6635ba..4ab2f99 100644
--- a/plugins/profiler/gprof-call-graph.h
+++ b/plugins/profiler/gprof-call-graph.h
@@ -56,7 +56,7 @@ struct _GProfCallGraphClass
 
 GType gprof_call_graph_get_type (void);
 
-GProfCallGraph *gprof_call_graph_new (FILE *stream, 
+GProfCallGraph *gprof_call_graph_new (GIOChannel *stream, 
 									  GProfFlatProfile *flat_profile);
 void gprof_call_graph_free (GProfCallGraph *self);
 
diff --git a/plugins/profiler/gprof-flat-profile.c b/plugins/profiler/gprof-flat-profile.c
index fb931b9..937df14 100644
--- a/plugins/profiler/gprof-flat-profile.c
+++ b/plugins/profiler/gprof-flat-profile.c
@@ -146,38 +146,54 @@ gprof_flat_profile_get_type (void)
 }
 
 GProfFlatProfile *
-gprof_flat_profile_new (FILE *stream)
+gprof_flat_profile_new (GIOChannel *stream)
 {
-	gchar buffer[PATH_MAX];
-	size_t length;
+	gchar *buffer;
+	gsize line_term_pos;
+	gboolean found_flat_profile;
 	gchar **fields;
 	GProfFlatProfile *flat_profile;
 	
 	flat_profile = g_object_new (GPROF_FLAT_PROFILE_TYPE, NULL);
+	found_flat_profile = FALSE;
 	
 	/* Read to beginning of flat profile data */
 	do
 	{
 		/* Don't loop infinitely if we don't have any data */
-		if (!fgets (buffer, PATH_MAX, stream))
+		if (g_io_channel_read_line (stream, &buffer, NULL, &line_term_pos, 
+		                            NULL) != G_IO_STATUS_NORMAL)
+		{
 			return flat_profile;
+		}
+
+		found_flat_profile = (gboolean) strchr (buffer, '%');
+		g_free (buffer);
 			
-	} while (!strchr (buffer, '%'));
+	} while (!found_flat_profile);
 	
 	/* Skip the second line of the column header */
-	fgets (buffer, PATH_MAX, stream);
+	g_io_channel_read_line (stream, &buffer, NULL, NULL, NULL);
+	g_free (buffer);
 	
-	while (fgets (buffer, PATH_MAX, stream))
+	while (g_io_channel_read_line (stream, &buffer, NULL, &line_term_pos,
+	                               NULL) == G_IO_STATUS_NORMAL)
 	{
+		g_print ("Line data: %s", buffer);
+
 		/* If the first character is 12, that's the end of the flat profile. */
 		if (buffer[0] == 12)
+		{
+			g_free (buffer);
 			break;
+		}
 		
-		/* Remove the newline from the buffer */
-		length = strlen (buffer);
-		buffer[length - 1] = 0;
+		/* Remove the line terminator from the buffer */
+		buffer[line_term_pos] = 0;
 		
 		fields = get_flat_profile_fields (buffer);
+
+		g_free (buffer);
 		
 		if (fields)
 		{
diff --git a/plugins/profiler/gprof-flat-profile.h b/plugins/profiler/gprof-flat-profile.h
index 1e0107d..09f24db 100644
--- a/plugins/profiler/gprof-flat-profile.h
+++ b/plugins/profiler/gprof-flat-profile.h
@@ -55,7 +55,7 @@ struct _GProfFlatProfileClass
 };
 
 GType gprof_flat_profile_get_type (void);
-GProfFlatProfile *gprof_flat_profile_new (FILE *stream);
+GProfFlatProfile *gprof_flat_profile_new (GIOChannel *stream);
 void gprof_flat_profile_free (GProfFlatProfile *self);
 
 GProfFlatProfileEntry *gprof_flat_profile_get_first_entry (GProfFlatProfile *self,
diff --git a/plugins/profiler/gprof-profile-data.c b/plugins/profiler/gprof-profile-data.c
index 6803f3e..2d510ff 100644
--- a/plugins/profiler/gprof-profile-data.c
+++ b/plugins/profiler/gprof-profile-data.c
@@ -107,7 +107,7 @@ gprof_profile_data_init_profile (GProfProfileData *self, gchar *path,
 {
 	gint stdout_pipe;
 	gint i;
-	FILE *stdout_stream;
+	GIOChannel *stdout_stream;
 	gchar *program_dir;
 	gchar *profile_data_path;
 	GPtrArray *gprof_args;
@@ -212,7 +212,7 @@ gprof_profile_data_init_profile (GProfProfileData *self, gchar *path,
 	g_free (profile_data_path);
 	g_free (program_dir);
 
-	stdout_stream = fdopen (stdout_pipe, "r");
+	stdout_stream = g_io_channel_unix_new (stdout_pipe);
 
 	if (self->priv->flat_profile)
 		gprof_flat_profile_free (self->priv->flat_profile);
@@ -225,7 +225,8 @@ gprof_profile_data_init_profile (GProfProfileData *self, gchar *path,
 	self->priv->call_graph = gprof_call_graph_new (stdout_stream, 
 												   self->priv->flat_profile);	
 	
-	fclose (stdout_stream);
+	g_io_channel_shutdown (stdout_stream, TRUE, NULL);
+	g_io_channel_unref (stdout_stream);
 	close (stdout_pipe);
 	
 	waitpid (gprof_pid, &gprof_status, 0);



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