Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/ashmem/src/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 5 kB image not shown  

Quelle  lib.rs

  Sprache: Rust
 

#![cfg(target_os = "android")]
//! Provides a wrapper around Android's ASharedMemory API.
//!
//! ashmem has existed in Android as a non-public API for some time.
//! Originally accessed via ioctl, it was later available via libcutils as ashmem_create_region etc.
//! ASharedMemory is the new public API, but it isn't available until API 26 (Android 8).
//! Builds targeting Android 10 (API 29) are no longer permitted to access ashmem via the ioctl interface.
//! This makes life for a portable program difficult - you can't reliably use the old or new interface during this transition period.
//! We try to dynamically load the new API first, then fall back to the ioctl interface.
//!
//! References:
//!   - [ASharedMemory documentation](https://developer.android.com/ndk/reference/group/memory)
//!   - [Linux ashmem.h definitions](https://elixir.bootlin.com/linux/v5.11.8/source/drivers/staging/android/uapi/ashmem.h)

#[macro_use]
extern crate ioctl_sys;

const __ASHMEMIOC: u32 = 0x77;

static mut LIBANDROID_ASHAREDMEMORY_CREATE: Option<
    extern "C" fn(*const libc::c_char, libc::size_t) -> libc::c_int,
> = None;
static mut LIBANDROID_ASHAREDMEMORY_GETSIZE: Option<extern "C" fn(libc::c_int) -> libc::size_t> =
    None;
static mut LIBANDROID_ASHAREDMEMORY_SETPROT: Option<
    extern "C" fn(libc::c_int, libc::c_int) -> libc::c_int,
> = None;

unsafe fn maybe_init() {
    const LIBANDROID_NAME: *const libc::c_char = "libandroid.so\0".as_ptr() as *const libc::c_char;
    const LIBANDROID_ASHAREDMEMORY_CREATE_NAME: *const libc::c_char =
        "ASharedMemory_create\0".as_ptr() as _;
    const LIBANDROID_ASHAREDMEMORY_GETSIZE_NAME: *const libc::c_char =
        "ASharedMemory_getSize\0".as_ptr() as _;
    const LIBANDROID_ASHAREDMEMORY_SETPROT_NAME: *const libc::c_char =
        "ASharedMemory_setProt\0".as_ptr() as _;
    static ONCE: std::sync::Once = std::sync::Once::new();
    ONCE.call_once(|| {
        // Leak the handle, there's no safe time to close it.
        let handle = libc::dlopen(LIBANDROID_NAME, libc::RTLD_LAZY | libc::RTLD_LOCAL);
        if handle.is_null() {
            return;
        }
        // Transmute guarantee for `fn -> Option<fn>`: https://doc.rust-lang.org/std/option/#representation
        LIBANDROID_ASHAREDMEMORY_CREATE =
            std::mem::transmute(libc::dlsym(handle, LIBANDROID_ASHAREDMEMORY_CREATE_NAME));
        LIBANDROID_ASHAREDMEMORY_GETSIZE =
            std::mem::transmute(libc::dlsym(handle, LIBANDROID_ASHAREDMEMORY_GETSIZE_NAME));
        LIBANDROID_ASHAREDMEMORY_SETPROT =
            std::mem::transmute(libc::dlsym(handle, LIBANDROID_ASHAREDMEMORY_SETPROT_NAME));
    });
}

/// See [ASharedMemory_create NDK documentation](https://developer.android.com/ndk/reference/group/memory#asharedmemory_create)
///
/// # Safety
///
/// Directly calls C or kernel APIs.
#[allow(non_snake_case)]
pub unsafe fn ASharedMemory_create(name: *const libc::c_char, size: libc::size_t) -> libc::c_int {
    const ASHMEM_NAME_DEF: *const libc::c_char = "/dev/ashmem\0".as_ptr() as _;
    const ASHMEM_NAME_LEN: usize = 256;
    const ASHMEM_SET_NAME: libc::c_int = iow!(
        __ASHMEMIOC,
        1,
        std::mem::size_of::<[libc::c_char; ASHMEM_NAME_LEN]>()
    ) as _;
    const ASHMEM_SET_SIZE: libc::c_int =
        iow!(__ASHMEMIOC, 3, std::mem::size_of::<libc::size_t>()) as _;

    maybe_init();
    if let Some(fun) = LIBANDROID_ASHAREDMEMORY_CREATE {
        return fun(name, size);
    }

    let fd = libc::open(ASHMEM_NAME_DEF, libc::O_RDWR, 0o600);
    if fd < 0 {
        return fd;
    }

    if !name.is_null() {
        // NOTE: libcutils uses a local stack copy of `name`.
        let r = libc::ioctl(fd, ASHMEM_SET_NAME, name);
        if r != 0 {
            libc::close(fd);
            return -1;
        }
    }

    let r = libc::ioctl(fd, ASHMEM_SET_SIZE, size);
    if r != 0 {
        libc::close(fd);
        return -1;
    }

    fd
}

/// See [ASharedMemory_getSize NDK documentation](https://developer.android.com/ndk/reference/group/memory#asharedmemory_getsize)
///
/// # Safety
///
/// Directly calls C or kernel APIs.
#[allow(non_snake_case)]
pub unsafe fn ASharedMemory_getSize(fd: libc::c_int) -> libc::size_t {
    const ASHMEM_GET_SIZE: libc::c_int = io!(__ASHMEMIOC, 4as _;

    maybe_init();
    if let Some(fun) = LIBANDROID_ASHAREDMEMORY_GETSIZE {
        return fun(fd);
    }

    libc::ioctl(fd, ASHMEM_GET_SIZE) as libc::size_t
}

/// See [ASharedMemory_setProt NDK documentation](https://developer.android.com/ndk/reference/group/memory#asharedmemory_setprot)
///
/// # Safety
///
/// Directly calls C or kernel APIs.
#[allow(non_snake_case)]
pub unsafe fn ASharedMemory_setProt(fd: libc::c_int, prot: libc::c_int) -> libc::c_int {
    const ASHMEM_SET_PROT_MASK: libc::c_int =
        iow!(__ASHMEMIOC, 5, std::mem::size_of::<libc::c_ulong>()) as _;

    maybe_init();
    if let Some(fun) = LIBANDROID_ASHAREDMEMORY_SETPROT {
        return fun(fd, prot);
    }

    let r = libc::ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
    if r != 0 {
        return -1;
    }
    r
}

#[cfg(test)]
mod tests {
    #[test]
    fn basic() {
        unsafe {
            let name = std::ffi::CString::new("/test-ashmem").unwrap();
            let fd = super::ASharedMemory_create(name.as_ptr(), 128);
            assert!(fd >= 0);
            assert_eq!(super::ASharedMemory_getSize(fd), 128);
            assert_eq!(super::ASharedMemory_setProt(fd, 0), 0);
            libc::close(fd);
        }
    }

    #[test]
    fn anonymous() {
        unsafe {
            let fd = super::ASharedMemory_create(std::ptr::null(), 128);
            assert!(fd >= 0);
            libc::close(fd);
        }
    }
}

Messung V0.5 in Prozent
C=85 H=98 G=91

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-06-18) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.