@ -8,6 +8,8 @@
# include <wlr/config.h>
# include <wlr/config.h>
# include "util/shm.h"
# include "util/shm.h"
# define RANDNAME_PATTERN " / wlroots-XXXXXX"
static void randname ( char * buf ) {
static void randname ( char * buf ) {
struct timespec ts ;
struct timespec ts ;
clock_gettime ( CLOCK_REALTIME , & ts ) ;
clock_gettime ( CLOCK_REALTIME , & ts ) ;
@ -18,17 +20,15 @@ static void randname(char *buf) {
}
}
}
}
int create_shm_file ( void ) {
static int excl_shm_open ( char * name ) {
int retries = 100 ;
int retries = 100 ;
do {
do {
char name [ ] = " /wlroots-XXXXXX " ;
randname ( name + strlen ( RANDNAME_PATTERN ) - 6 ) ;
randname ( name + strlen ( name ) - 6 ) ;
- - retries ;
- - retries ;
// CLOEXEC is guaranteed to be set by shm_open
// CLOEXEC is guaranteed to be set by shm_open
int fd = shm_open ( name , O_RDWR | O_CREAT | O_EXCL , 0600 ) ;
int fd = shm_open ( name , O_RDWR | O_CREAT | O_EXCL , 0600 ) ;
if ( fd > = 0 ) {
if ( fd > = 0 ) {
shm_unlink ( name ) ;
return fd ;
return fd ;
}
}
} while ( retries > 0 & & errno = = EEXIST ) ;
} while ( retries > 0 & & errno = = EEXIST ) ;
@ -37,10 +37,12 @@ int create_shm_file(void) {
}
}
int allocate_shm_file ( size_t size ) {
int allocate_shm_file ( size_t size ) {
int fd = create_shm_file ( ) ;
char name [ ] = RANDNAME_PATTERN ;
int fd = excl_shm_open ( name ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
return - 1 ;
return - 1 ;
}
}
shm_unlink ( name ) ;
int ret ;
int ret ;
do {
do {
@ -53,3 +55,35 @@ int allocate_shm_file(size_t size) {
return fd ;
return fd ;
}
}
bool allocate_shm_file_pair ( size_t size , int * rw_fd_ptr , int * ro_fd_ptr ) {
char name [ ] = RANDNAME_PATTERN ;
int rw_fd = excl_shm_open ( name ) ;
if ( rw_fd < 0 ) {
return false ;
}
// CLOEXEC is guaranteed to be set by shm_open
int ro_fd = shm_open ( name , O_RDONLY , 0 ) ;
if ( ro_fd < 0 ) {
shm_unlink ( name ) ;
close ( rw_fd ) ;
return false ;
}
shm_unlink ( name ) ;
int ret ;
do {
ret = ftruncate ( rw_fd , size ) ;
} while ( ret < 0 & & errno = = EINTR ) ;
if ( ret < 0 ) {
close ( rw_fd ) ;
close ( ro_fd ) ;
return false ;
}
* rw_fd_ptr = rw_fd ;
* ro_fd_ptr = ro_fd ;
return true ;
}