int fd;
void *ptr;
+ char *filename = NULL;
fd = shm_open(name, O_RDONLY, 0600);
if (fd == -1)
{
- perror ("Failed to shm_open");
- return NULL;
+ filename = g_build_filename (g_get_tmp_dir (), name, NULL);
+ fd = open (filename, O_RDONLY);
+ if (fd == -1)
+ {
+ perror ("Failed to map shm");
+ return NULL;
+ }
}
ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
(void) close(fd);
- shm_unlink (name);
+ if (filename)
+ {
+ unlink (filename);
+ g_free (filename);
+ }
+ else
+ shm_unlink (name);
return ptr;
}
static void *
-map_named_shm (char *name, gsize size)
+map_named_shm (char *name, gsize size, gboolean *is_shm)
{
#ifdef G_OS_UNIX
+ char *filename = NULL;
int fd;
void *ptr;
int res;
fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
if (fd == -1)
{
- if (errno != EEXIST)
- g_error ("Unable to allocate shared mem for window");
- return NULL;
+ if (errno == EEXIST)
+ return NULL;
+
+ filename = g_build_filename (g_get_tmp_dir (), name, NULL);
+
+ fd = open (filename, O_RDWR | O_CREAT | O_EXCL, 0600);
+ g_free (filename);
+ if (fd == -1)
+ {
+ if (errno != EEXIST)
+ g_error ("Unable to allocate shared mem for window");
+ return NULL;
+ }
+ else
+ *is_shm = FALSE;
}
+ else
+ *is_shm = TRUE;
res = ftruncate (fd, size);
g_assert (res != -1);
res = posix_fallocate (fd, 0, size);
if (res != 0 && errno == ENOSPC)
{
- shm_unlink (name);
+ if (filename)
+ unlink (filename);
+ else
+ shm_unlink (name);
g_error ("Not enough shared memory for window surface");
}
#endif
return NULL;
}
+ *is_shm = TRUE;
res = ftruncate (fd, size);
g_assert (res != -1);
/* name must have at least space for 34 bytes */
static gpointer
-create_random_shm (char *name, gsize size)
+create_random_shm (char *name, gsize size, gboolean *is_shm)
{
guint32 r;
int i, o;
}
name[o++] = 0;
- ptr = map_named_shm (name, size);
+ ptr = map_named_shm (name, size, is_shm);
if (ptr)
return ptr;
}
char name[36];
void *data;
gsize data_size;
+ gboolean is_shm;
} BroadwayShmSurfaceData;
static void
#ifdef G_OS_UNIX
munmap (data->data, data->data_size);
- shm_unlink (data->name);
+ if (data->is_shm)
+ shm_unlink (data->name);
+ else
+ {
+ char *filename = g_build_filename (g_get_tmp_dir (), data->name, NULL);
+ unlink (filename);
+ g_free (filename);
+ }
#elif defined(G_OS_WIN32)
data = g_new (BroadwayShmSurfaceData, 1);
data->data_size = width * height * sizeof (guint32);
- data->data = create_random_shm (data->name, data->data_size);
+ data->data = create_random_shm (data->name, data->data_size, &data->is_shm);
surface = cairo_image_surface_create_for_data ((guchar *)data->data,
CAIRO_FORMAT_ARGB32, width, height, width * sizeof (guint32));