commit
						659d39baaa
					
				| @ -1,9 +0,0 @@ | ||||
| #ifndef UTIL_OS_COMPATIBILITY_H | ||||
| #define UTIL_OS_COMPATIBILITY_H | ||||
| 
 | ||||
| int os_fd_set_cloexec(int fd); | ||||
| int set_cloexec_or_close(int fd); | ||||
| int create_tmpfile_cloexec(char *tmpname); | ||||
| int os_create_anonymous_file(off_t size); | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,7 @@ | ||||
| #ifndef UTIL_SHM_H | ||||
| #define UTIL_SHM_H | ||||
| 
 | ||||
| int create_shm_file(void); | ||||
| int allocate_shm_file(size_t size); | ||||
| 
 | ||||
| #endif | ||||
| @ -1,149 +0,0 @@ | ||||
| /*
 | ||||
|  * Copyright © 2012 Collabora, Ltd. | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining | ||||
|  * a copy of this software and associated documentation files (the | ||||
|  * "Software"), to deal in the Software without restriction, including | ||||
|  * without limitation the rights to use, copy, modify, merge, publish, | ||||
|  * distribute, sublicense, and/or sell copies of the Software, and to | ||||
|  * permit persons to whom the Software is furnished to do so, subject to | ||||
|  * the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice (including the | ||||
|  * next paragraph) shall be included in all copies or substantial | ||||
|  * portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||
|  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||
|  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
|  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||
|  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||
|  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||
|  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| #define _POSIX_C_SOURCE 200809L | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/types.h> | ||||
| #include <unistd.h> | ||||
| #include <wlr/config.h> | ||||
| #include "util/os-compatibility.h" | ||||
| 
 | ||||
| int os_fd_set_cloexec(int fd) { | ||||
| 	if (fd == -1) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	long flags = fcntl(fd, F_GETFD); | ||||
| 	if (flags == -1) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int set_cloexec_or_close(int fd) { | ||||
| 	if (os_fd_set_cloexec(fd) != 0) { | ||||
| 		close(fd); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return fd; | ||||
| } | ||||
| 
 | ||||
| int create_tmpfile_cloexec(char *tmpname) { | ||||
| 	int fd; | ||||
| 	mode_t prev_umask = umask(0066); | ||||
| #ifdef HAVE_MKOSTEMP | ||||
| 	fd = mkostemp(tmpname, O_CLOEXEC); | ||||
| 	if (fd >= 0) { | ||||
| 		unlink(tmpname); | ||||
| 	} | ||||
| #else | ||||
| 	fd = mkstemp(tmpname); | ||||
| 	if (fd >= 0) { | ||||
| 		fd = set_cloexec_or_close(fd); | ||||
| 		unlink(tmpname); | ||||
| 	} | ||||
| #endif | ||||
| 	umask(prev_umask); | ||||
| 
 | ||||
| 	return fd; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Create a new, unique, anonymous file of the given size, and | ||||
|  * return the file descriptor for it. The file descriptor is set | ||||
|  * CLOEXEC. The file is immediately suitable for mmap()'ing | ||||
|  * the given size at offset zero. | ||||
|  * | ||||
|  * The file should not have a permanent backing store like a disk, | ||||
|  * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. | ||||
|  * | ||||
|  * The file name is deleted from the file system. | ||||
|  * | ||||
|  * The file is suitable for buffer sharing between processes by | ||||
|  * transmitting the file descriptor over Unix sockets using the | ||||
|  * SCM_RIGHTS methods. | ||||
|  * | ||||
|  * If the C library implements posix_fallocate(), it is used to | ||||
|  * guarantee that disk space is available for the file at the | ||||
|  * given size. If disk space is insufficient, errno is set to ENOSPC. | ||||
|  * If posix_fallocate() is not supported, program may receive | ||||
|  * SIGBUS on accessing mmap()'ed file contents instead. | ||||
|  */ | ||||
| int os_create_anonymous_file(off_t size) { | ||||
| 	static const char template[] = "/wlroots-shared-XXXXXX"; | ||||
| 
 | ||||
| 	const char *path = getenv("XDG_RUNTIME_DIR"); | ||||
| 	if (!path) { | ||||
| 		errno = ENOENT; | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	char *name = malloc(strlen(path) + sizeof(template)); | ||||
| 	if (!name) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	strcpy(name, path); | ||||
| 	strcat(name, template); | ||||
| 
 | ||||
| 	int fd = create_tmpfile_cloexec(name); | ||||
| 	free(name); | ||||
| 	if (fd < 0) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef WLR_HAS_POSIX_FALLOCATE | ||||
| 	int ret; | ||||
| 	do { | ||||
| 		ret = posix_fallocate(fd, 0, size); | ||||
| 	} while (ret == EINTR); | ||||
| 	if (ret != 0) { | ||||
| 		close(fd); | ||||
| 		errno = ret; | ||||
| 		return -1; | ||||
| 	} | ||||
| #else | ||||
| 	int ret; | ||||
| 	do { | ||||
| 		ret = ftruncate(fd, size); | ||||
| 	} while (ret < 0 && errno == EINTR); | ||||
| 	if (ret < 0) { | ||||
| 		close(fd); | ||||
| 		return -1; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	return fd; | ||||
| } | ||||
| @ -0,0 +1,67 @@ | ||||
| #define _POSIX_C_SOURCE 200112L | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <string.h> | ||||
| #include <sys/mman.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| #include <wlr/config.h> | ||||
| #include "util/shm.h" | ||||
| 
 | ||||
| static void randname(char *buf) { | ||||
| 	struct timespec ts; | ||||
| 	clock_gettime(CLOCK_REALTIME, &ts); | ||||
| 	long r = ts.tv_nsec; | ||||
| 	for (int i = 0; i < 6; ++i) { | ||||
| 		buf[i] = 'A'+(r&15)+(r&16)*2; | ||||
| 		r >>= 5; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int create_shm_file(void) { | ||||
| 	int retries = 100; | ||||
| 	do { | ||||
| 		char name[] = "/wlroots-XXXXXX"; | ||||
| 		randname(name + strlen(name) - 6); | ||||
| 
 | ||||
| 		--retries; | ||||
| 		// CLOEXEC is guaranteed to be set by shm_open
 | ||||
| 		int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); | ||||
| 		if (fd >= 0) { | ||||
| 			shm_unlink(name); | ||||
| 			return fd; | ||||
| 		} | ||||
| 	} while (retries > 0 && errno == EEXIST); | ||||
| 
 | ||||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| int allocate_shm_file(size_t size) { | ||||
| 	int fd = create_shm_file(); | ||||
| 	if (fd < 0) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef WLR_HAS_POSIX_FALLOCATE | ||||
| 	int ret; | ||||
| 	do { | ||||
| 		ret = posix_fallocate(fd, 0, size); | ||||
| 	} while (ret == EINTR); | ||||
| 	if (ret != 0) { | ||||
| 		close(fd); | ||||
| 		errno = ret; | ||||
| 		return -1; | ||||
| 	} | ||||
| #else | ||||
| 	int ret; | ||||
| 	do { | ||||
| 		ret = ftruncate(fd, size); | ||||
| 	} while (ret < 0 && errno == EINTR); | ||||
| 	if (ret < 0) { | ||||
| 		close(fd); | ||||
| 		return -1; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	return fd; | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue