x11: dup fd before passing to shm_attach_fd

This function takes `Into<RawFdContainer>`. So it accepts an owned fd,
and closes it. So as long as the API is like this, we need to dup a new
fd it can close when calling it.

`Into<RawFdContainer>` is implemented for anything implementing `IntoRawFd`,
so passing `OwnedFd` works.

Fixes https://github.com/rust-windowing/softbuffer/issues/168. Should be
backported to 0.3.x.
This commit is contained in:
Ian Douglas Scott 2023-10-31 07:09:50 -07:00 committed by GitHub
parent 2eef592745
commit 3b98da7e28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -11,7 +11,10 @@ use raw_window_handle::{
HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle, XcbDisplayHandle,
XcbWindowHandle,
};
use rustix::{fd, mm, shm as posix_shm};
use rustix::{
fd::{AsFd, BorrowedFd, OwnedFd},
mm, shm as posix_shm,
};
use std::{
fmt,
@ -618,7 +621,7 @@ impl ShmBuffer {
) -> Result<(), PushBufferError> {
// Register the guard.
let new_id = conn.generate_id()?;
conn.shm_attach_fd(new_id, fd::AsRawFd::as_raw_fd(&seg), true)?
conn.shm_attach_fd(new_id, seg.as_fd().try_clone_to_owned().unwrap(), true)?
.ignore_error();
// Take out the old one and detach it.
@ -738,9 +741,9 @@ impl ShmSegment {
}
}
impl fd::AsRawFd for ShmSegment {
fn as_raw_fd(&self) -> fd::RawFd {
self.id.as_raw_fd()
impl AsFd for ShmSegment {
fn as_fd(&self) -> BorrowedFd<'_> {
self.id.as_fd()
}
}
@ -785,7 +788,7 @@ impl<D: ?Sized, W: ?Sized> Drop for X11Impl<D, W> {
}
/// Create a shared memory identifier.
fn create_shm_id() -> io::Result<fd::OwnedFd> {
fn create_shm_id() -> io::Result<OwnedFd> {
use posix_shm::{Mode, ShmOFlags};
let mut rng = fastrand::Rng::new();
@ -838,7 +841,7 @@ fn is_shm_available(c: &impl Connection) -> bool {
};
let (attach, detach) = {
let attach = c.shm_attach_fd(seg_id, fd::AsRawFd::as_raw_fd(&seg), false);
let attach = c.shm_attach_fd(seg_id, seg.as_fd().try_clone_to_owned().unwrap(), false);
let detach = c.shm_detach(seg_id);
match (attach, detach) {