[Xfce4-commits] <xfce4-taskmanager:master> Fix for scanf failing at parsing process names with spaces

Mike Massonnet noreply at xfce.org
Sat May 8 00:14:01 CEST 2010


Updating branch refs/heads/master
         to a7465b61f4a5eedc08d1a1223c2f32b86ad5fd0b (commit)
       from 553be8eee1d3a0e496d2f24dfb7b54c4e057ce7e (commit)

commit a7465b61f4a5eedc08d1a1223c2f32b86ad5fd0b
Author: Mike Massonnet <mmassonnet at xfce.org>
Date:   Sat May 8 00:10:22 2010 +0200

    Fix for scanf failing at parsing process names with spaces
    
    The code still uses scanf to parse the stat file, but the process name
    is being cleansed so that it never fails. The name is read from the
    “comm” file. It is still a truncated version of the name, and will
    likely remain for very long like this. There is one solution, but since
    the name isn't currently used inside the interface there is no point
    wasting time.

 src/task-manager-linux.c |   42 ++++++++++++++++++++++--------------------
 1 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/task-manager-linux.c b/src/task-manager-linux.c
index 56583cb..f1aa1e9 100644
--- a/src/task-manager-linux.c
+++ b/src/task-manager-linux.c
@@ -116,19 +116,9 @@ get_task_cmdline (Task *task)
 	gchar c;
 
 	snprintf (filename, 96, "/proc/%i/cmdline", task->pid);
-	if ((file = fopen (filename, "r")) == NULL)
-		return;
-
-	/* Drop parentheses around task->name */
-	// FIXME comm concats the name to 15 chars
-	{
-		gchar *p;
-		g_strlcpy (task->name, &task->name[1], sizeof (task->name));
-		p = g_strrstr (task->name, ")");
-		*p = '\0';
-	}
 
 	/* Read byte per byte until EOF */
+	file = fopen (filename, "r");
 	for (i = 0; (c = fgetc (file)) != EOF && i < sizeof (task->cmdline) - 1; i++)
 		task->cmdline[i] = (c == '\0') ? ' ' : c;
 	if (task->cmdline[i-1] == ' ')
@@ -181,6 +171,7 @@ get_task_details (guint pid, Task *task)
 	FILE *file;
 	gchar filename[96];
 	gchar buffer[1024];
+	gchar *p1, *p2;
 
 	snprintf (filename, 96, "/proc/%d/stat", pid);
 	if ((file = fopen (filename, "r")) == NULL)
@@ -189,19 +180,34 @@ get_task_details (guint pid, Task *task)
 	fgets (buffer, 1024, file);
 	fclose (file);
 
+	/* Scanning the short process name is unreliable with scanf when it contains spaces */
+	p1 = g_strrstr (buffer, "(");
+	p2 = g_strrstr (buffer, ")");
+	while (p1 <= p2)
+	{
+		*p1 = 'x';
+		p1++;
+	}
+
+	/* Retrieve the short name from the comm file */
+	snprintf (filename, 96, "/proc/%d/comm", pid);
+	file = fopen (filename, "r");
+	fscanf (file, "%255s", task->name);
+	fclose (file);
+
+	/* Parse the stat file */
 	{
-		gchar dummy[255];
+		gchar dummy[256];
 		gint idummy;
 		gulong jiffies_user, jiffies_system;
 		struct passwd *pw;
 		struct stat sstat;
-		guint ppid = 0;
 
 		sscanf(buffer, "%i %255s %1s %i %i %i %i %i %255s %255s %255s %255s %255s %i %i %i %i %i %i %i %i %i %i %i %255s %255s %255s %i %255s %255s %255s %255s %255s %255s %255s %255s %255s %255s %i %255s %255s",
 			&task->pid,	// processid
-			task->name,	// processname
+			 dummy,		// processname
 			task->state,	// processstate
-			&ppid,		// parentid
+			&task->ppid,	// parentid
 			 &idummy,	// processs groupid
 
 			 &idummy,	// session id
@@ -249,11 +255,6 @@ get_task_details (guint pid, Task *task)
 			 dummy
 		);
 
-		// FIXME sscanf sucks, big news, process names with spaces don't pass
-		if (ppid == 0)
-			return FALSE;
-
-		task->ppid = ppid;
 		task->rss *= get_pagesize ();
 		get_cpu_percent (task->pid, jiffies_user, &task->cpu_user, jiffies_system, &task->cpu_system);
 
@@ -263,6 +264,7 @@ get_task_details (guint pid, Task *task)
 		g_strlcpy (task->uid_name, (pw != NULL) ? pw->pw_name : "nobody", sizeof (task->uid_name));
 	}
 
+	/* Read the full command line */
 	get_task_cmdline (task);
 
 	return TRUE;



More information about the Xfce4-commits mailing list