Replaces all calls to g_file_read_link with POSIX readlink
and uses static buffers where possible.
Reduces memory fragmentation.

diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c
index b7b2b86..7517d03 100644
--- a/hald/linux/blockdev.c
+++ b/hald/linux/blockdev.c
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 #include <syslog.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib.h>
@@ -565,17 +572,15 @@ resolve_symlink (const char *file)
 {
 	GError *error;
 	char *dir;
-	char *link;
+	gchar link[HAL_PATH_MAX] ;
 	char *f;
 	char *f1;
 
 	f = g_strdup (file);
-
+	memset(link, 0, HAL_PATH_MAX);
 	while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) {
-		link = g_file_read_link (f, &error);
-		if (link == NULL) {
-			g_warning ("Cannot resolve symlink %s: %s", f, error->message);
-			g_error_free (error);
+		if(readlink(f, link, HAL_PATH_MAX-1)<0) {
+			g_warning ("Cannot resolve symlink %s: %s", f, strerror(errno));
 			g_free (f);
 			f = NULL;
 			goto out;
@@ -584,7 +589,6 @@ resolve_symlink (const char *file)
 		dir = g_path_get_dirname (f);
 		f1 = g_strdup_printf ("%s/%s", dir, link);
 		g_free (dir);
-		g_free (link);
 		g_free (f);
 		f = f1;
 	}
diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c
index 177f05a..fd81e6a 100644
--- a/hald/linux/coldplug.c
+++ b/hald/linux/coldplug.c
@@ -310,13 +310,12 @@ static int device_list_insert(const char
 	if (S_ISLNK(statbuf.st_mode)) {
 		gchar *target;
 
-		if ((target = g_file_read_link (path, NULL)) != NULL) {
+		if ((target = hal_util_readlink (path)) != NULL) {
 			gchar *normalized_target;
 
 			g_strlcpy(filename, path, sizeof(filename));
 			hal_util_path_ascend (filename);
 			normalized_target = hal_util_get_normalized_path (filename, target);
-			g_free (target);
 			sysfs_dev->path = normalized_target;
 			goto found;
 		}
diff --git a/hald/linux/hotplug.c b/hald/linux/hotplug.c
index 1b9282a..aaa5597 100644
--- a/hald/linux/hotplug.c
+++ b/hald/linux/hotplug.c
@@ -123,7 +120,10 @@ hotplug_event_begin_sysfs (HotplugEvent
 	 */
 	if (hotplug_event->type == HOTPLUG_EVENT_SYSFS) {
 		g_snprintf (subsystem, HAL_PATH_MAX, "%s/subsystem", hotplug_event->sysfs.sysfs_path);
-		subsystem_target = g_file_read_link (subsystem, NULL);
+		/* g_file_read_link leaks memory. We alloc lots of trash here but return NULL, damn
+		   Re-implemented this using POSIX readlink() */
+		/* subsystem_target = g_file_read_link (subsystem, NULL); */
+		subsystem_target = hal_util_readlink(subsystem);
 		if (subsystem_target != NULL) {
 			if (strstr(subsystem_target, "/block") != NULL) {
 				HAL_INFO (("%s is a block device (subsystem)", hotplug_event->sysfs.sysfs_path));
diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index 991dadf..ed76509 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -694,6 +696,18 @@ static gboolean get_parent_device(char *
 		return FALSE;
 	return TRUE;
 }
+static gchar path_buffer [HAL_PATH_MAX];
+
+gchar *
+hal_util_readlink(gchar * link)
+{
+ memset(path_buffer, 0, HAL_PATH_MAX);
+ if(readlink(link, path_buffer, HAL_PATH_MAX-1)<0)
+    return NULL;
+    
+ return path_buffer;
+}
+
 /* return the first already known parent device */
 gboolean
 hal_util_find_known_parent (const gchar *sysfs_path, HalDevice **parent, gchar **parent_path)
@@ -720,9 +734,8 @@ hal_util_find_known_parent (const gchar
 
 	/* try if the parent chain is constructed by the device-link */
 	g_snprintf (parentdevpath, HAL_PATH_MAX, "%s/device", sysfs_path);
-	if (((target = g_file_read_link (parentdevpath, NULL)) != NULL)) {
+	if ((target = hal_util_readlink (parentdevpath)) != NULL) {
 		parent_devpath = hal_util_get_normalized_path (sysfs_path, target);
-		g_free (target);
 
 		while (TRUE) {
 			parent_dev = hal_device_store_match_key_value_string (hald_get_gdl (),