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