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 #include #include +#include #include #include @@ -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 (),