13 #include <linux/videodev2.h>
18 os_fd_set_cloexec(int fd)
25 flags = fcntl(fd, F_GETFD);
29 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
36 set_cloexec_or_close(int fd)
38 if (os_fd_set_cloexec(fd) != 0) {
46 create_tmpfile_cloexec(char *tmpname)
51 fd = mkostemp(tmpname, O_CLOEXEC);
55 fd = mkstemp(tmpname);
57 fd = set_cloexec_or_close(fd);
66 * Create a new, unique, anonymous file of the given size, and
67 * return the file descriptor for it. The file descriptor is set
68 * CLOEXEC. The file is immediately suitable for mmap()'ing
69 * the given size at offset zero.
71 * The file should not have a permanent backing store like a disk,
72 * but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
74 * The file name is deleted from the file system.
76 * The file is suitable for buffer sharing between processes by
77 * transmitting the file descriptor over Unix sockets using the
80 * If the C library implements posix_fallocate(), it is used to
81 * guarantee that disk space is available for the file at the
82 * given size. If disk space is insufficient, errno is set to ENOSPC.
83 * If posix_fallocate() is not supported, program may receive
84 * SIGBUS on accessing mmap()'ed file contents instead.
86 * If the C library implements memfd_create(), it is used to create the
87 * file purely in memory, without any backing file name on the file
88 * system, and then sealing off the possibility of shrinking it. This
89 * can then be checked before accessing mmap()'ed file contents, to
90 * make sure SIGBUS can't happen. It also avoids requiring
94 os_create_anonymous_file(off_t size)
96 static const char weston_template[] = "/weston-shared-XXXXXX";
102 #ifdef HAVE_MEMFD_CREATE
103 fd = memfd_create("weston-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING);
105 /* We can add this seal before calling posix_fallocate(), as
106 * the file is currently zero-sized anyway.
108 * There is also no need to check for the return value, we
109 * couldn't do anything with it anyway.
111 fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK);
115 path = getenv("XDG_RUNTIME_DIR");
121 name = static_cast<char *>(malloc(strlen(path) + sizeof(weston_template)));
126 strcat(name, weston_template);
128 fd = create_tmpfile_cloexec(name);
136 #ifdef HAVE_POSIX_FALLOCATE
138 ret = posix_fallocate(fd, 0, size);
139 } while (ret == EINTR);
147 ret = ftruncate(fd, size);
148 } while (ret < 0 && errno == EINTR);
159 get_first_camera_device(void)
161 DIR *dir = opendir("/dev");
163 perror("Couldn't open the '/dev' directory");
167 static char device[PATH_MAX];
168 struct dirent *dirent;
170 while ((dirent = readdir(dir)) != NULL) {
171 struct v4l2_capability vid_cap;
174 if (strcmp(dirent->d_name, "video"))
176 if (!isdigit(dirent->d_name[5]))
179 snprintf(device, sizeof(device), "/dev/%s", dirent->d_name);
181 fd = open(device, O_RDWR);
184 if (ioctl(fd, VIDIOC_QUERYCAP, &vid_cap) < 0) {
190 if ((vid_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||
191 (vid_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) {
198 return found ? device : NULL;