From 2eac2b258dfadfb9ae1b32c461ea80252bfe1f16 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sun, 30 Jun 2024 20:15:15 +0200 Subject: [PATCH 1/3] Bump MSRV to 1.77 This is required for c"" CStr literals. --- .github/workflows/ci.yml | 2 +- Cargo.toml | 2 +- clippy.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56fdf1d1791d..54fddacd01ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,7 +83,7 @@ jobs: - name: Checkout sources uses: actions/checkout@v3 - name: Rust toolchain - uses: dtolnay/rust-toolchain@1.72.0 + uses: dtolnay/rust-toolchain@1.77.0 - name: Get date for registry cache id: date run: echo "::set-output name=date::$(date +'%Y-%m-%d')" diff --git a/Cargo.toml b/Cargo.toml index b584945ee9dd..0189698f1552 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ readme = "README.md" homepage = "https://smithay.github.io/" keywords = ["wayland", "compositor", "graphics", "server"] categories = ["gui"] -rust-version = "1.72.0" +rust-version = "1.77.0" [package.metadata.docs.rs] features = ["test_all_features"] diff --git a/clippy.toml b/clippy.toml index 7904b9c642d3..c3840152cd92 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1,4 +1,4 @@ -msrv = "1.72.0" +msrv = "1.77.0" type-complexity-threshold = 400 disallowed-macros = [ From e3b6eb111b1d3a5b37baa13fc2970014cb8f64fd Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sun, 30 Jun 2024 19:13:30 +0200 Subject: [PATCH 2/3] utils: Make SealedString take a &CStr instead of a CString MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It only uses it to pass it to a syscall, so it doesn’t need ownership of it. --- src/input/keyboard/keymap_file.rs | 6 ++---- src/utils/sealed_file.rs | 12 ++++++------ src/wayland/dmabuf/mod.rs | 4 +--- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/input/keyboard/keymap_file.rs b/src/input/keyboard/keymap_file.rs index fbb44932861b..a666bd0e5f3b 100644 --- a/src/input/keyboard/keymap_file.rs +++ b/src/input/keyboard/keymap_file.rs @@ -21,9 +21,8 @@ pub struct KeymapFile { impl KeymapFile { /// Turn the keymap into a string using KEYMAP_FORMAT_TEXT_V1, create a sealed file for it, and store the string pub fn new(keymap: &Keymap) -> Self { - let name = CString::new("smithay-keymap").unwrap(); let keymap = keymap.get_as_string(KEYMAP_FORMAT_TEXT_V1); - let sealed = SealedFile::with_content(name, CString::new(keymap.as_str()).unwrap()); + let sealed = SealedFile::with_content(c"smithay-keymap", CString::new(keymap.as_str()).unwrap()); if let Err(err) = sealed.as_ref() { error!("Error when creating sealed keymap file: {}", err); @@ -42,8 +41,7 @@ impl KeymapFile { pub(crate) fn change_keymap(&mut self, keymap: &Keymap) { let keymap = keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1); - let name = CString::new("smithay-keymap-file").unwrap(); - let sealed = SealedFile::with_content(name, CString::new(keymap.clone()).unwrap()); + let sealed = SealedFile::with_content(c"smithay-keymap-file", CString::new(keymap.clone()).unwrap()); if let Err(err) = sealed.as_ref() { error!("Error when creating sealed keymap file: {}", err); diff --git a/src/utils/sealed_file.rs b/src/utils/sealed_file.rs index 178e91ca8eb0..64470d7b76c6 100644 --- a/src/utils/sealed_file.rs +++ b/src/utils/sealed_file.rs @@ -4,7 +4,7 @@ //! information such as keymaps without them being able to write to the handle. use std::{ - ffi::CString, + ffi::{CStr, CString}, fs::File, io::Write, os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}, @@ -17,16 +17,16 @@ pub(crate) struct SealedFile { } impl SealedFile { - pub fn with_content(name: CString, contents: CString) -> Result { + pub fn with_content(name: &CStr, contents: CString) -> Result { Self::with_data(name, contents.as_bytes_with_nul()) } #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "android"))] - pub fn with_data(name: CString, data: &[u8]) -> Result { + pub fn with_data(name: &CStr, data: &[u8]) -> Result { use rustix::fs::{MemfdFlags, SealFlags}; use std::io::Seek; - let fd = rustix::fs::memfd_create(&name, MemfdFlags::CLOEXEC | MemfdFlags::ALLOW_SEALING)?; + let fd = rustix::fs::memfd_create(name, MemfdFlags::CLOEXEC | MemfdFlags::ALLOW_SEALING)?; let mut file: File = fd.into(); file.write_all(data)?; @@ -46,7 +46,7 @@ impl SealedFile { } #[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "android")))] - pub fn with_data(name: CString, data: &[u8]) -> Result { + pub fn with_data(name: &CStr, data: &[u8]) -> Result { use rand::{distributions::Alphanumeric, Rng}; use rustix::{ io::Errno, @@ -59,7 +59,7 @@ impl SealedFile { // loop a couple times if it exists. let mut n = 0; let (shm_name, mut file) = loop { - let mut shm_name = name.as_bytes().to_owned(); + let mut shm_name = name.to_bytes().to_owned(); shm_name.push(b'-'); shm_name.extend((0..7).map(|_| rng.sample(Alphanumeric))); let fd = rustix::shm::shm_open( diff --git a/src/wayland/dmabuf/mod.rs b/src/wayland/dmabuf/mod.rs index b2c23b29e974..58c9df6f29e9 100644 --- a/src/wayland/dmabuf/mod.rs +++ b/src/wayland/dmabuf/mod.rs @@ -189,7 +189,6 @@ mod dispatch; use std::{ collections::HashMap, - ffi::CString, ops::Sub, os::unix::io::AsFd, sync::{ @@ -397,8 +396,7 @@ impl DmabufFeedbackBuilder { .flat_map(DmabufFeedbackFormat::to_ne_bytes) .collect::>(); - let name = CString::new("smithay-dmabuffeedback-format-table").unwrap(); - let format_table_file = SealedFile::with_data(name, &formats)?; + let format_table_file = SealedFile::with_data(c"smithay-dmabuffeedback-format-table", &formats)?; // remove all formats from the main tranche that are already covered // by a preference tranche From fc1219532d70d019681484d0c04f78e1138ef9cf Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sun, 30 Jun 2024 19:17:25 +0200 Subject: [PATCH 3/3] backends: Use CStr literals everywhere possible This addition to the 2021 edition makes it possible to generate a &CStr at compile-time, with no need for unwrap()/expect() or unsafe, making it much more ergonomic to pass to C APIs. --- examples/buffer_test.rs | 8 +--- src/backend/renderer/gles/mod.rs | 39 +++++++---------- src/backend/renderer/gles/shaders/mod.rs | 54 ++++++++++-------------- src/backend/vulkan/mod.rs | 6 +-- 4 files changed, 43 insertions(+), 64 deletions(-) diff --git a/examples/buffer_test.rs b/examples/buffer_test.rs index 47044c3e5de0..106f2733450f 100644 --- a/examples/buffer_test.rs +++ b/examples/buffer_test.rs @@ -1,4 +1,4 @@ -use std::{ffi::CStr, fmt, fs::File, os::unix::io::OwnedFd, path::PathBuf}; +use std::{fmt, fs::File, os::unix::io::OwnedFd, path::PathBuf}; use clap::{Args, Parser, Subcommand, ValueEnum}; use smithay::{ @@ -189,11 +189,7 @@ fn buffer_test(args: TestArgs) { Instance::new(Version::VERSION_1_2, None).expect("Unable to create vulkan instance"); let physical_device = PhysicalDevice::enumerate(&instance) .expect("Failed to enumerate physical devices") - .filter(|phd| { - phd.has_device_extension(unsafe { - CStr::from_bytes_with_nul_unchecked(b"VK_EXT_physical_device_drm\0") - }) - }) + .filter(|phd| phd.has_device_extension(ash::vk::EXT_PHYSICAL_DEVICE_DRM_NAME)) .find(|phd| { phd.primary_node().unwrap() == Some(node) || phd.render_node().unwrap() == Some(node) }) diff --git a/src/backend/renderer/gles/mod.rs b/src/backend/renderer/gles/mod.rs index c9f42dd1f04e..2076793e687f 100644 --- a/src/backend/renderer/gles/mod.rs +++ b/src/backend/renderer/gles/mod.rs @@ -1848,36 +1848,28 @@ impl GlesRenderer { let debug_shader = format!("#version 100\n#define {}\n{}", shaders::DEBUG_FLAGS, src.as_ref()); let debug_program = unsafe { link_program(&self.gl, shaders::VERTEX_SHADER, &debug_shader)? }; - let vert = CStr::from_bytes_with_nul(b"vert\0").expect("NULL terminated"); - let vert_position = CStr::from_bytes_with_nul(b"vert_position\0").expect("NULL terminated"); - let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated"); - let tex_matrix = CStr::from_bytes_with_nul(b"tex_matrix\0").expect("NULL terminated"); - let size = CStr::from_bytes_with_nul(b"size\0").expect("NULL terminated"); - let alpha = CStr::from_bytes_with_nul(b"alpha\0").expect("NULL terminated"); - let tint = CStr::from_bytes_with_nul(b"tint\0").expect("NULL terminated"); - unsafe { Ok(GlesPixelProgram(Rc::new(GlesPixelProgramInner { normal: GlesPixelProgramInternal { program, uniform_matrix: self .gl - .GetUniformLocation(program, matrix.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(program, c"matrix".as_ptr() as *const ffi::types::GLchar), uniform_tex_matrix: self .gl - .GetUniformLocation(program, tex_matrix.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(program, c"tex_matrix".as_ptr() as *const ffi::types::GLchar), uniform_alpha: self .gl - .GetUniformLocation(program, alpha.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(program, c"alpha".as_ptr() as *const ffi::types::GLchar), uniform_size: self .gl - .GetUniformLocation(program, size.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(program, c"size".as_ptr() as *const ffi::types::GLchar), attrib_vert: self .gl - .GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar), + .GetAttribLocation(program, c"vert".as_ptr() as *const ffi::types::GLchar), attrib_position: self .gl - .GetAttribLocation(program, vert_position.as_ptr() as *const ffi::types::GLchar), + .GetAttribLocation(program, c"vert_position".as_ptr() as *const ffi::types::GLchar), additional_uniforms: additional_uniforms .iter() .map(|uniform| { @@ -1899,22 +1891,23 @@ impl GlesRenderer { program: debug_program, uniform_matrix: self .gl - .GetUniformLocation(debug_program, matrix.as_ptr() as *const ffi::types::GLchar), - uniform_tex_matrix: self - .gl - .GetUniformLocation(debug_program, tex_matrix.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"matrix".as_ptr() as *const ffi::types::GLchar), + uniform_tex_matrix: self.gl.GetUniformLocation( + debug_program, + c"tex_matrix".as_ptr() as *const ffi::types::GLchar, + ), uniform_alpha: self .gl - .GetUniformLocation(debug_program, alpha.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"alpha".as_ptr() as *const ffi::types::GLchar), uniform_size: self .gl - .GetUniformLocation(debug_program, size.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"size".as_ptr() as *const ffi::types::GLchar), attrib_vert: self .gl - .GetAttribLocation(debug_program, vert.as_ptr() as *const ffi::types::GLchar), + .GetAttribLocation(debug_program, c"vert".as_ptr() as *const ffi::types::GLchar), attrib_position: self.gl.GetAttribLocation( debug_program, - vert_position.as_ptr() as *const ffi::types::GLchar, + c"vert_position".as_ptr() as *const ffi::types::GLchar, ), additional_uniforms: additional_uniforms .iter() @@ -1937,7 +1930,7 @@ impl GlesRenderer { destruction_callback_sender: self.destruction_callback_sender.clone(), uniform_tint: self .gl - .GetUniformLocation(debug_program, tint.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"tint".as_ptr() as *const ffi::types::GLchar), }))) } } diff --git a/src/backend/renderer/gles/shaders/mod.rs b/src/backend/renderer/gles/shaders/mod.rs index 148b6e16eacb..3df60f0d31fc 100644 --- a/src/backend/renderer/gles/shaders/mod.rs +++ b/src/backend/renderer/gles/shaders/mod.rs @@ -142,25 +142,18 @@ pub(super) unsafe fn texture_program( let program = unsafe { link_program(gl, shaders::VERTEX_SHADER, &shader)? }; let debug_program = unsafe { link_program(gl, shaders::VERTEX_SHADER, debug_shader.as_ref())? }; - let vert = CStr::from_bytes_with_nul(b"vert\0").expect("NULL terminated"); - let vert_position = CStr::from_bytes_with_nul(b"vert_position\0").expect("NULL terminated"); - let tex = CStr::from_bytes_with_nul(b"tex\0").expect("NULL terminated"); - let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated"); - let tex_matrix = CStr::from_bytes_with_nul(b"tex_matrix\0").expect("NULL terminated"); - let alpha = CStr::from_bytes_with_nul(b"alpha\0").expect("NULL terminated"); - let tint = CStr::from_bytes_with_nul(b"tint\0").expect("NULL terminated"); - Ok(GlesTexProgramVariant { normal: GlesTexProgramInternal { program, - uniform_tex: gl.GetUniformLocation(program, tex.as_ptr() as *const ffi::types::GLchar), - uniform_matrix: gl.GetUniformLocation(program, matrix.as_ptr() as *const ffi::types::GLchar), + uniform_tex: gl.GetUniformLocation(program, c"tex".as_ptr() as *const ffi::types::GLchar), + uniform_matrix: gl + .GetUniformLocation(program, c"matrix".as_ptr() as *const ffi::types::GLchar), uniform_tex_matrix: gl - .GetUniformLocation(program, tex_matrix.as_ptr() as *const ffi::types::GLchar), - uniform_alpha: gl.GetUniformLocation(program, alpha.as_ptr() as *const ffi::types::GLchar), - attrib_vert: gl.GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(program, c"tex_matrix".as_ptr() as *const ffi::types::GLchar), + uniform_alpha: gl.GetUniformLocation(program, c"alpha".as_ptr() as *const ffi::types::GLchar), + attrib_vert: gl.GetAttribLocation(program, c"vert".as_ptr() as *const ffi::types::GLchar), attrib_vert_position: gl - .GetAttribLocation(program, vert_position.as_ptr() as *const ffi::types::GLchar), + .GetAttribLocation(program, c"vert_position".as_ptr() as *const ffi::types::GLchar), additional_uniforms: additional_uniforms .iter() .map(|uniform| { @@ -179,16 +172,20 @@ pub(super) unsafe fn texture_program( }, debug: GlesTexProgramInternal { program: debug_program, - uniform_tex: gl.GetUniformLocation(debug_program, tex.as_ptr() as *const ffi::types::GLchar), + uniform_tex: gl + .GetUniformLocation(debug_program, c"tex".as_ptr() as *const ffi::types::GLchar), uniform_matrix: gl - .GetUniformLocation(debug_program, matrix.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"matrix".as_ptr() as *const ffi::types::GLchar), uniform_tex_matrix: gl - .GetUniformLocation(debug_program, tex_matrix.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"tex_matrix".as_ptr() as *const ffi::types::GLchar), uniform_alpha: gl - .GetUniformLocation(debug_program, alpha.as_ptr() as *const ffi::types::GLchar), - attrib_vert: gl.GetAttribLocation(debug_program, vert.as_ptr() as *const ffi::types::GLchar), - attrib_vert_position: gl - .GetAttribLocation(debug_program, vert_position.as_ptr() as *const ffi::types::GLchar), + .GetUniformLocation(debug_program, c"alpha".as_ptr() as *const ffi::types::GLchar), + attrib_vert: gl + .GetAttribLocation(debug_program, c"vert".as_ptr() as *const ffi::types::GLchar), + attrib_vert_position: gl.GetAttribLocation( + debug_program, + c"vert_position".as_ptr() as *const ffi::types::GLchar, + ), additional_uniforms: additional_uniforms .iter() .map(|uniform| { @@ -206,7 +203,7 @@ pub(super) unsafe fn texture_program( .collect(), }, // debug flags - uniform_tint: gl.GetUniformLocation(debug_program, tint.as_ptr() as *const ffi::types::GLchar), + uniform_tint: gl.GetUniformLocation(debug_program, c"tint".as_ptr() as *const ffi::types::GLchar), }) }; @@ -223,16 +220,11 @@ pub(super) unsafe fn texture_program( pub(super) unsafe fn solid_program(gl: &ffi::Gles2) -> Result { let program = link_program(gl, shaders::VERTEX_SHADER_SOLID, shaders::FRAGMENT_SHADER_SOLID)?; - let matrix = CStr::from_bytes_with_nul(b"matrix\0").expect("NULL terminated"); - let color = CStr::from_bytes_with_nul(b"color\0").expect("NULL terminated"); - let vert = CStr::from_bytes_with_nul(b"vert\0").expect("NULL terminated"); - let position = CStr::from_bytes_with_nul(b"position\0").expect("NULL terminated"); - Ok(GlesSolidProgram { program, - uniform_matrix: gl.GetUniformLocation(program, matrix.as_ptr() as *const ffi::types::GLchar), - uniform_color: gl.GetUniformLocation(program, color.as_ptr() as *const ffi::types::GLchar), - attrib_vert: gl.GetAttribLocation(program, vert.as_ptr() as *const ffi::types::GLchar), - attrib_position: gl.GetAttribLocation(program, position.as_ptr() as *const ffi::types::GLchar), + uniform_matrix: gl.GetUniformLocation(program, c"matrix".as_ptr() as *const ffi::types::GLchar), + uniform_color: gl.GetUniformLocation(program, c"color".as_ptr() as *const ffi::types::GLchar), + attrib_vert: gl.GetAttribLocation(program, c"vert".as_ptr() as *const ffi::types::GLchar), + attrib_position: gl.GetAttribLocation(program, c"position".as_ptr() as *const ffi::types::GLchar), }) } diff --git a/src/backend/vulkan/mod.rs b/src/backend/vulkan/mod.rs index 889f4a5e6000..daa1839a606e 100644 --- a/src/backend/vulkan/mod.rs +++ b/src/backend/vulkan/mod.rs @@ -219,8 +219,7 @@ impl Instance { // Enable debug layers if present and debug assertions are enabled. if cfg!(debug_assertions) { - const VALIDATION: &CStr = - unsafe { CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0") }; + const VALIDATION: &CStr = c"VK_LAYER_KHRONOS_validation"; if available_layers .iter() @@ -256,8 +255,7 @@ impl Instance { app_info.map(|info| CString::new(info.name).expect("app name contains null terminator")); let mut app_info = vk::ApplicationInfo::default() .api_version(api_version.to_raw()) - // SAFETY: null terminated with no interior null bytes. - .engine_name(unsafe { CStr::from_bytes_with_nul_unchecked(b"Smithay\0") }) + .engine_name(c"Smithay") .engine_version(Version::SMITHAY.to_raw()); if let Some(app_version) = app_version {