Shared memory - A Rust wrapper around native shared memory for Linux and Windows

Overview

shared_memory

Build Status crates.io mio Lines of Code

A crate that allows you to share memory between processes.

This crate provides lightweight wrappers around shared memory APIs in an OS agnostic way. It is intended to be used with it's sister crate raw_sync which provide simple primitves to synchronize access to the shared memory (Mutex, RwLock, Events, etc...).

raw_sync
crates.io docs.rs

Usage

For usage examples, see code located in examples/ :

Examples Description
event Shows the use of shared events through shared memory
mutex Shows the use of a shared mutex through shared memory

License

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Is it safe to implement SharedMemCast for bool?

    Is it safe to implement SharedMemCast for bool?

    One of the requirements for bool is that it only has the values 0x00 and 0x01, so there is a possible safety issue around having bool implement SharedMemCast.

    opened by asajeffrey 21
  • Race Condition on Mac OS with file system locking

    Race Condition on Mac OS with file system locking

    Unfortunately, the dependency i chose for file system locks seems to be broken on MacOS.

    The race happens when process 1 creates a file that is supposed to contain the shared memory mapping unique ID but process 2 ends up reading the file before the ID is written by process 1...

    I will have to either find a new file locking crate or be OK with not fully supporting MacOS for now.

    bug 
    opened by elast0ny 5
  • Procedural Macro for implementing SharedMemCast

    Procedural Macro for implementing SharedMemCast

    Fixes #17.

    Hello! Thanks for the great crate. I want to use this for a project and I noticed that you needed a custom derive for the SharedMemCast trait. This is really useful for using this crate without having to write the unsafe impl, so I thought I would help out and contribute the macro. :)

    The size of this PR is probably quite daunting, so I'll give you an overview of what I had to do so you understand each step:

    1. All procedural macros need to go in a separate crate that is compiled before shared_memory is compiled. I called this crate shared_memory_derive and added it to the root directory of the project.
    2. In order to re-export the SharedMemCast proc macro from src/lib.rs and make using the macro convenient, I needed to upgrade the crate to the 2018 edition. I didn't want my changes to be too obtrusive, so I only added the edition = 2018 line in the Cargo.toml file and made the most minimal changes to fix any errors that cropped up. You can always use cargo fix to finish the upgrade later if you feel the need to do that.
    3. I copied all the metadata from the root Cargo.toml file into the shared_memory_derive/Cargo.toml file. I made sure that the versions of both crates are in sync. This can be useful to avoid confusion. Please make sure you publish shared_memory_derive before publishing shared_memory to avoid any problems.
    4. I then went and created a comprehensive set of tests to make sure we never accidentally let through anything that should not be casted from shared memory. I'm using the trybuild crate for that. The tests in tests/ui are all meant to produce compiler errors and the tests in tests/run-pass are all meant to compile with no errors. See the CONTRIBUTING.md file I added for more details.
      • [ ] You should go through my tests and make sure all the cases I've allowed to pass are valid
      • [ ] Can you confirm whether or not zero-sized types are allowed to be cast from shared memory? (e.g. PhantomData<T>, (), [T; 0], unit structs, etc.) I've disabled them (by producing a compiler error) because it made the most sense to me that they should not ever be casted from shared memory. The same goes for empty enums which should never be initialized.
    5. In order for these tests to pass, we need the SharedMemCast trait to be implemented for various sizes of fixed-size array. Rust has no type-level integer support just yet, so the solution that every crate uses is to have a bunch of impls for different sizes. I think we can cover a large number of use-cases by having impls for all sizes between 1 and 32, then the powers of 2 up to about 2 GB. See cast.rs for what I mean by that. I think these impls should be more than enough for most peoples' needs and we can always add more later.
    6. Finally, after all these tests and impls were added, I implemented the actual custom derive code. This code actually isn't terribly complicated. I have attempted to comment it quite well so you understand the approach and the implementation. Please let me know if you have any questions.
    7. After implementing that and getting the tests to pass, I updated the example in the examples/ directory to use #[derive] instead of unsafe impl. I also updated the docs to let people know that this feature exists. See below for a screenshot of that.
    8. I modified the Travis CI script so that it uses the --all flag. This should ensure that the custom derive tests also run on CI.

    These steps can be roughly seen in my commits as well if you prefer to go through things that way. Please don't hesitate to ask me any questions about all of this and do let me know if I've missed describing any part of what I did.

    Thanks again for the great library! Looking forward to using it once these changes land and everything is published. :smile:

    Documentation Screenshot

    Only the docs for SharedMemCast were updated:

    updated docs

    opened by sunjay 5
  • + file lock

    + file lock

    Сhanges

    This fork has a feature rs2 that allows you to safely create shared memory through file locks. Example of common to all processes code:

    SharedMem::open_linked(file_name)
        .or_else(|_|SharedMem::create_linked(file_name, LockType::RwLock, 4096))
        .or_else(|_|SharedMem::open_linked(file_name))
        .ok()
    
    opened by bopohaa 5
  • segmentation fault

    segmentation fault

    I was able to run the example where shared data is of primitive type e.g. u8 or usize. but when i tried to run the logic with struct or vec, the read side always returned segmentation fault:

    write side:

    { let data_ptr = mutex.lock().unwrap(); let data = unsafe { &mut *(*data_ptr as *mut Vec) };

        //let sd : Entry = Entry { hashcode: 1, buff: vec![1, 2, 3, 4, 5]};
        let sd : Entry = Entry { hashcode: 1};
        serialize_into(data, &sd).unwrap();
    }
    

    read side:

    { let data_ptr = mutex.rlock().unwrap(); let data = unsafe { & *(*data_ptr as *const Vec) };

        eprintln!("{}", data[1]);
    
        match deserialize::<Entry>(data)
        {
            Ok(d) => eprint!("Data : {:?}", d),
            Err(e) =>  eprint!("Error deserializing data {}", e)
        }
    }
    

    any idea what is going on?

    opened by GOVYANSONG 4
  • I cannot use systemd_journal_logger with shared memory

    I cannot use systemd_journal_logger with shared memory

    I am not able to use shared_memory lib and systemd_journal_logger lib together when I run binary file without debug symbols

    For example

    `use log::LevelFilter;
    
    fn main() {
      systemd_journal_logger::init().unwrap();
    
      log::set_max_level( LevelFilter::Debug);
    
      log::warn!("A warning.");
      log::error!("An error");
    }    `
    

    And this dependencies

    
    `[dependencies]
    serde =  { version = "1.0", features = ["derive"] }
    serde_json = "1.0"
    log = "=0.4.14"
    systemd-journal-logger = "=0.3.1"
    
    

    everything works perfectly when running ./target/release/xyz

    but if I include shared_memory It stops working

    I checked in sm source code that implements a log crate, why dont use standard log api implementation ?| thanks

    opened by vandercijr 4
  • Patern matching errors on linux

    Patern matching errors on linux

    Cargo version: 1.53.0 (also tried with 1.55.0-nightly) Rustc version: 1.53.0 (also tried with 1.55.0-nightly) Crate version: 0.11.4

    When it compile the crate it throw these errors:

    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
      --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:87:13
       |
    87 |         Err(nix::Error::Sys(Errno::EEXIST)) => return Err(ShmemError::MappingIdExists),
       |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
       |
       = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
      --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:88:13
       |
    88 |         Err(nix::Error::Sys(e)) => return Err(ShmemError::MapCreateFailed(e as u32)),
       |             ^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
       |
       = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
       --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:103:13
        |
    103 |         Err(nix::Error::Sys(e)) => return Err(ShmemError::UnknownOsError(e as u32)),
        |             ^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
        |
        = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
       --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:119:13
        |
    119 |         Err(nix::Error::Sys(e)) => return Err(ShmemError::MapCreateFailed(e as u32)),
        |             ^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
        |
        = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
       --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:135:13
        |
    135 |         Err(nix::Error::Sys(e)) => return Err(ShmemError::MapOpenFailed(e as u32)),
        |             ^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
        |
        = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
       --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:150:13
        |
    150 |         Err(nix::Error::Sys(e)) => return Err(ShmemError::MapOpenFailed(e as u32)),
        |             ^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
        |
        = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error[E0164]: expected tuple struct or tuple variant, found associated function `nix::Error::Sys`
       --> /home/zacharie/.cargo/registry/src/github.com-1ecc6299db9ec823/shared_memory-0.11.4/src/unix.rs:166:13
        |
    166 |         Err(nix::Error::Sys(e)) => return Err(ShmemError::MapOpenFailed(e as u32)),
        |             ^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
        |
        = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
    
    error: aborting due to 7 previous errors
    
    opened by Rayzeq 4
  • Emulate POSIX shared memory behavior on Windows

    Emulate POSIX shared memory behavior on Windows

    Shmem currently behaves differently on Windows than Unix. Specifically, Shmem::set_owner has no effect on the underlying memory object on Windows, as the standard Windows shared file mapping doesn't allow persistence. This means that dropping a unique Shmem will destroy the shared memory even when Shmem::is_owner returns false. This clashes with POSIX behaviour, which persists the memory unless shm_unlink() is called and allows reopening even when all handles have previously been closed.

    This PR unifies shared memory behaviour on Windows and Unix and adds a test to check for compliance. It follows the C++ Boost implementation of creating a file to back the shared memory which is renamed and marked for deletion when an owning Shmem drops, but persists otherwise. Shmem::set_owner stops being a no-op on Windows and now behaves as expected.

    opened by defiori 4
  • unresolved imports `winapi::shared::winerror`, `winapi::um::handleapi`, `winapi::um::winbase`

    unresolved imports `winapi::shared::winerror`, `winapi::um::handleapi`, `winapi::um::winbase`

    when trying to compile shared_memory 0.11.1 on Windows 10 I get this error.

    error[E0432]: unresolved imports `winapi::shared::winerror`, `winapi::um::handleapi`, `winapi::um::winbase`
      --> C:\Users\domen\.cargo\registry\src\github.com-1ecc6299db9ec823\shared_memory-0.11.1\src\windows.rs:4:9
       |
    4  |         winerror::ERROR_ALREADY_EXISTS,
       |         ^^^^^^^^ could not find `winerror` in `shared`
    ...
    8  |         handleapi::{CloseHandle, INVALID_HANDLE_VALUE},
       |         ^^^^^^^^^ could not find `handleapi` in `um`
    9  |         memoryapi::{MapViewOfFile, UnmapViewOfFile, VirtualQuery, FILE_MAP_READ, FILE_MAP_WRITE},
    10 |         winbase::{CreateFileMappingA, OpenFileMappingA},
       |         ^^^^^^^ could not find `winbase` in `um`
    

    Other information: windows 10 (build 17763) rustup 1.21.1 (7832b2ebe 2019-12-20) cargo 1.45.0-nightly (cb06cb269 2020-05-08) rustc 1.45.0-nightly (a74d1862d 2020-05-14)

    opened by Dmajster 4
  • Allow dynamic creation of locks/events

    Allow dynamic creation of locks/events

    At the moment, the number and kinds of locks and events is fixed when creating the shared memory. There are APIs (like channels) where it would be useful to be able to create these dynamically, allocating them into the regular shared memory rather than the metadata. Is this doable?

    opened by asajeffrey 4
  • Add Travis CI support

    Add Travis CI support

    As suggested by @llogiq , mem_file would probably benefit from the features provided by https://travis-ci.org/

    I will have to set up compilation on the supported targets at a minimum and maybe try to see how testing could be implemented.

    Testing might prove to be a bit tricky since mem_file is a library aimed for multi-process environments and it sounds like a headache to do automated testing for that. Issues that come to mind:

    • Granted that you can launch multiple separate processes in a single cargo test, how do you validate: -Memory is actually shared -Locking mechanism work properly (the two process cant both hold a mutex for example) -Things are getting cleaned up/closed properly after a non-crashing/non-frozen run

    • In case of error for any of these testcases, your testing framework might have to deal with crashes processes, frozen processes waiting forever on locks, etc.. on a per-OS basis.

    enhancement 
    opened by elast0ny 4
  • Update nix requirement from 0.23 to 0.26

    Update nix requirement from 0.23 to 0.26

    Updates the requirements on nix to permit the latest version.

    Changelog

    Sourced from nix's changelog.

    [0.26.1] - 2022-11-29

    Fixed

    • Fix UB with sys::socket::sockopt::SockType using SOCK_PACKET. (#1821)

    [0.26.0] - 2022-11-29

    Added

    • Added SockaddrStorage::{as_unix_addr, as_unix_addr_mut} (#1871)
    • Added MntFlags and unmount on all of the BSDs.
    • Added any() and all() to poll::PollFd. (#1877)
    • Add MntFlags and unmount on all of the BSDs. (#1849)
    • Added a Statfs::flags method. (#1849)
    • Added NSFS_MAGIC FsType on Linux and Android. (#1829)
    • Added sched_getcpu on platforms that support it. (#1825)
    • Added sched_getaffinity and sched_setaffinity on FreeBSD. (#1804)
    • Added line_discipline field to Termios on Linux, Android and Haiku (#1805)
    • Expose the memfd module on FreeBSD (memfd was added in FreeBSD 13) (#1808)
    • Added domainname field of UtsName on Android and Linux (#1817)
    • Re-export RLIM_INFINITY from libc (#1831)
    • Added syncfs(2) on Linux (#1833)
    • Added faccessat(2) on illumos (#1841)
    • Added eaccess() on FreeBSD, DragonFly and Linux (glibc and musl). (#1842)
    • Added IP_TOS SO_PRIORITY and IPV6_TCLASS sockopts for Linux (#1853)
    • Added new_unnamed and is_unnamed for UnixAddr on Linux and Android. (#1857)
    • Added SockProtocol::Raw for raw sockets (#1848)
    • added IP_MTU (IpMtu) IPPROTO_IP sockopt on Linux and Android. (#1865)

    Changed

    • The MSRV is now 1.56.1 (#1792)

    ... (truncated)

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 0
  • Update clap requirement from 3 to 4

    Update clap requirement from 3 to 4

    Updates the requirements on clap to permit the latest version.

    Release notes

    Sourced from clap's releases.

    v4.0.2

    [4.0.2] - 2022-09-28

    Fixes

    • (parser) SetFalse should conflict with itself like SetTrue and Set
    • (parser) Allow one-off overrides
    Changelog

    Sourced from clap's changelog.

    [4.0.2] - 2022-09-28

    Fixes

    • (parser) SetFalse should conflict with itself like SetTrue and Set
    • (parser) Allow one-off overrides

    [4.0.1] - 2022-09-28

    Fixes

    • (derive) Ensure #[clap(...)] attribute still works

    [4.0.0] - 2022-09-28

    Highlights

    Arg::num_args(range)

    Clap has had several ways for controlling how many values will be captured without always being clear on how they interacted, including

    • Arg::multiple_values(true)
    • Arg::number_of_values(4)
    • Arg::min_values(2)
    • Arg::max_values(20)
    • Arg::takes_value(true)

    These have now all been collapsed into Arg::num_args which accepts both single values and ranges of values. num_args controls how many raw arguments on the command line will be captured as values per occurrence and independent of value delimiters.

    See Issue 2688 for more background.

    Polishing Help

    Clap strives to give a polished CLI experience out of the box with little ceremony. With some feedback that has accumulated over time, we took this release as an opportunity to re-evaluate our --help output to make sure it is meeting that goal.

    In doing this evaluation, we wanted to keep in mind:

    • Whether other CLIs had ideas that make sense to apply
    • Providing an experience that fits within the rest of applications and works across all shells

    Before:

    git
    A fictional versioning CLI
    

    USAGE: </tr></table>

    ... (truncated)

    Commits
    • 4524127 chore: Release
    • d279f7f docs: Update changelog
    • 929c87c Merge pull request #4281 from epage/override
    • 3683e2c fix(parser): Allow one-off self-overrides
    • 2d78749 fix(parser): SetFalse should also not allow self-override
    • bf42ff0 chore: Release
    • 824f658 docs: Update changelog
    • 7b886d2 Merge pull request #4278 from intgr/zsh-completion-fix-multiple-args-handling
    • 89cae3a fix(complete): Fix handling of multiple arguments
    • f6602c5 chore: Release
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 0
Owner
elast0ny
elast0ny
Use Git installed in Bash on Windows/Windows Subsystem for Linux (WSL) from Windows and Visual Studio Code (VSCode)

WSLGit This project provides a small executable that forwards all arguments to git running inside Bash on Windows/Windows Subsystem for Linux (WSL). T

A. R. S. 1.1k Jan 3, 2023
A safe and idiomatic wrapper over shared memory APIs in rust with proper cleanups.

shmem-bind A safe and idiomatic wrapper over shared memory APIs in rust with proper cleanups. Quick start: check the message-passing example for bette

ArshiA Akhavan 3 Apr 6, 2024
Check if the process is running inside Windows Subsystem for Linux (Bash on Windows)

is-wsl Check if the process is running inside Windows Subsystem for Linux (Bash on Windows) Inspired by sindresorhus/is-wsl and made for Rust lang. Ca

Sean Larkin 6 Jan 31, 2023
Wrapper around atspi-code to provide higher-level at-spi Rust bindings

atspi Wrapper around atspi-codegen to provide higher-level at-spi Rust bindings. Contributions Take a look at our atspi-codegen crate, and try inpleme

Odilia 3 Feb 7, 2022
Python wrapper around reth db. Written in Rust.

reth-db-py Bare-bones Python package allowing you to interact with the Reth DB via Python. Written with Rust and Pyo3. This python wrapper can access

gibz 44 Jul 3, 2023
A wrapper around the code action dump from https://mcdiamondfire.com.

DiamondFire Action Dump for Rust A wrapper around the code action dump from https://mcdiamondfire.com. This currently only provides schema types for u

null 3 Sep 17, 2022
A simple made in Rust crack, automatic for Winrar, activated from shared virtual memory, for studies.

Simple Winrar Crack in Rust What does it do ? A simple project that allows you to modify the license check used by WinRaR, "RegKey" from virtual memor

João Vitor 7 Jan 2, 2023
Use Thunk to build your Rust program that runs on old Windows platforms, support Windows XP and more!

Use Thunk to build your Rust program that runs on old platforms. Thunk uses VC-LTL5 and YY-Thunks to build programs that support old platforms. So, ho

null 6 May 21, 2023
Maccha is an extremely extensible and themable power menu for Windows, macOS, and Linux.

Maccha I hate coffee. Maccha is an extremely extensible and themable power menu for Windows, macOS, and Linux. Plugins Plugins are written in Rust (ot

Kyza 9 May 13, 2023
Simple template to use csr and ssr leptos with tauri for ios/android/windows/macos/linux and web dev

Tailwind-Leptos-Tauri Template Simple template to use csr and ssr leptos with tauri for ios/android/windows/macos/linux and web dev Just clone the rep

Victor Batarse 11 Mar 10, 2024
Windows-rs - Rust for Windows

Rust for Windows The windows crate lets you call any Windows API past, present, and future using code generated on the fly directly from the metadata

Microsoft 7.7k Dec 30, 2022
Switch windows of same app with alt + ` on windows pc.

Windows Switcher Switch windows of same app with alt + ` on windows pc. 250k single file executable downloaded from Github Release. No installation re

null 172 Dec 10, 2022
Windows Capture Simple Screen Capture for Windows 🔥

Windows Capture   Windows Capture is a highly efficient Rust library that enables you to effortlessly capture the screen using the Graphics Capture AP

null 3 Sep 24, 2023
A library to capture the Screen on Linux, MacOS and Windows.

Captis - A library for capturing the screen on Linux, MacOS and Windows It's a fairly simple library that performs good enough, the OS level APIs that

CrewNew.com 17 Dec 23, 2022
A todo list from terminal. Compatible with Linux and Windows, not tested on macOS

todocli A todo list from terminal. Compatible with Linux and Windows, not tested on macOS (not planing on support tho). Note: Currently being rewritte

Patommmmm 3 Dec 12, 2022
Toggleable cron reminders app for Mac, Linux and Windows

Remind Me Again Remind Me Again Toggleable reminders app for Mac, Linux and Windows Download for Mac, Windows or Linux Dev instructions Get started In

Kasper 42 Apr 22, 2023
An implementation of a Windows Event Collector server running on GNU/Linux.

OpenWEC OpenWEC is a free and open source (GPLv3) implementation of a Windows Event Collector server running on GNU/Linux and written in Rust. OpenWEC

CEA IT Security 15 Jun 15, 2023
Cross-platform casting SDK, support Android, Windows, Linux

mirror Cross-platform casting SDK, support Android, Windows, Linux Low-latency transport protocols use [SRT](https://github.com/Haivision/srt) Video:

Lazy Panda 10 Feb 29, 2024
A library that allows for the arbitrary inspection and manipulation of the memory and code of a process on a Linux system.

raminspect raminspect is a crate that allows for the inspection and manipulation of the memory and code of a running process on a Linux system. It pro

Liam Germain 24 Sep 26, 2023