[PATCH 1/2] wayland-cursor: Introduce size_t, improve error handling
Martin Minarik
minarik11 at student.fiit.stuba.sk
Fri Feb 1 08:44:33 PST 2013
The size_t is introduced, accomodating for the possibility of
a large addres space.
The error handling is improved, in particular the memory leaks
are fixed.
---
cursor/wayland-cursor.c | 88 +++++++++++++++++++++++++++++++++--------------
1 file changed, 63 insertions(+), 25 deletions(-)
diff --git a/cursor/wayland-cursor.c b/cursor/wayland-cursor.c
index 25e51c2..821ef31 100644
--- a/cursor/wayland-cursor.c
+++ b/cursor/wayland-cursor.c
@@ -36,13 +36,13 @@
struct shm_pool {
struct wl_shm_pool *pool;
int fd;
- unsigned int size;
- unsigned int used;
+ size_t size;
+ size_t used;
char *data;
};
static struct shm_pool *
-shm_pool_create(struct wl_shm *shm, int size)
+shm_pool_create(struct wl_shm *shm, size_t size)
{
struct shm_pool *pool;
@@ -74,35 +74,53 @@ err_free:
}
static int
-shm_pool_resize(struct shm_pool *pool, int size)
+shm_pool_resize(struct shm_pool *pool, size_t size)
{
if (ftruncate(pool->fd, size) < 0)
- return 0;
+ goto err_unmap;
wl_shm_pool_resize(pool->pool, size);
- munmap(pool->data, pool->size);
+ if (-1 == munmap(pool->data, pool->size)) {
+ goto err;
+ }
pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
pool->fd, 0);
+
+ if (pool->data == MAP_FAILED) {
+ goto err;
+ }
pool->size = size;
return 1;
+err_unmap:
+ munmap(pool->data, pool->size);
+err:
+ wl_shm_pool_destroy(pool->pool);
+ pool->pool = NULL;
+ close(pool->fd);
+ free(pool);
+ return 0;
}
static int
-shm_pool_allocate(struct shm_pool *pool, int size)
+shm_pool_allocate(struct shm_pool *pool, size_t size, size_t *offset)
{
- int offset;
+ const size_t need = pool->used + size;
+
+ if (need > pool->size) {
+ const size_t double_s = 2 * pool->size;
+ const size_t new_size = double_s > need ? double_s : need;
- if (pool->used + size > pool->size)
- if (!shm_pool_resize(pool, 2 * pool->size + size))
+ if (!shm_pool_resize(pool, new_size))
return -1;
+ }
- offset = pool->used;
+ *offset = pool->used;
pool->used += size;
- return offset;
+ return 0;
}
static void
@@ -128,7 +146,7 @@ struct cursor_image {
struct wl_cursor_image image;
struct wl_cursor_theme *theme;
struct wl_buffer *buffer;
- int offset; /* data offset of this image in the shm pool */
+ size_t offset; /* data offset of this image in the shm pool */
};
struct cursor {
@@ -200,8 +218,7 @@ wl_cursor_create_from_data(struct cursor_metadata *metadata,
cursor->cursor.image_count = 1;
cursor->cursor.images = malloc(sizeof *cursor->cursor.images);
if (!cursor->cursor.images) {
- free(cursor);
- return NULL;
+ goto err_cursor;
}
cursor->cursor.name = strdup(metadata->name);
@@ -209,10 +226,7 @@ wl_cursor_create_from_data(struct cursor_metadata *metadata,
image = malloc(sizeof *image);
if (!image) {
- free(cursor->cursor.name);
- free(cursor->cursor.images);
- free(cursor);
- return NULL;
+ goto err;
}
cursor->cursor.images[0] = (struct wl_cursor_image *) image;
@@ -225,11 +239,20 @@ wl_cursor_create_from_data(struct cursor_metadata *metadata,
image->image.delay = 0;
size = metadata->width * metadata->height * sizeof(uint32_t);
- image->offset = shm_pool_allocate(theme->pool, size);
+ if (shm_pool_allocate(theme->pool, size, &image->offset)) {
+ goto err;
+ }
memcpy(theme->pool->data + image->offset,
cursor_data + metadata->offset, size);
return &cursor->cursor;
+
+err:
+ free(cursor->cursor.name);
+ free(cursor->cursor.images);
+err_cursor:
+ free(cursor);
+ return NULL;
}
static void
@@ -264,8 +287,7 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
cursor->cursor.images =
malloc(images->nimage * sizeof cursor->cursor.images[0]);
if (!cursor->cursor.images) {
- free(cursor);
- return NULL;
+ goto err;
}
cursor->cursor.name = strdup(images->name);
@@ -287,12 +309,28 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
/* copy pixels to shm pool */
size = image->image.width * image->image.height * 4;
- image->offset = shm_pool_allocate(theme->pool, size);
- memcpy(theme->pool->data + image->offset,
- images->images[i]->pixels, size);
+ int fail = shm_pool_allocate(theme->pool, size, &image->offset);
+
+ if (fail == 0) {
+ memcpy(theme->pool->data + image->offset,
+ images->images[i]->pixels, size);
+
+ }
+ if (fail == -1) {
+ /* on error, rollback the allocations. */
+ int j;
+ for (j = 0; j <= i; j++){
+ free(cursor->cursor.images[j]);
+ }
+
+ goto err;
+ }
}
return &cursor->cursor;
+err:
+ free(cursor);
+ return NULL;
}
static void
--
1.7.10.4
More information about the wayland-devel
mailing list