elast0ny / shared_memory

A Rust wrapper around native shared memory for Linux and Windows
382 stars 51 forks source link

Unique ID generation code is not portable on *nix #18

Closed Gekkio closed 5 years ago

Gekkio commented 5 years ago

If a unique ID is not defined in SharedMemConf, a random one is generated using this code:

let unique_id: String = match self.wanted_os_path {
    Some(ref s) => s.clone(),
    None => {
        format!("shmem_rs_{:16X}", rand::thread_rng().gen::<u64>())
    },
};

However, it looks like the generated name doesn't work on all supported platforms. I've got a simple program that uses this library, and it works on Linux but fails on FreeBSD with the following error:

shm_open() failed with :\nErr(Sys(EINVAL))

After looking at shm_open man pages, I noticed that FreeBSD has an extra restriction: the name parameter must begin with a slash. The man page on my local Linux system also suggests that a slash is required for portability.

FreeBSD:

The following errors are defined for shm_open(): [EINVAL] The path does not begin with a slash (`/') character.

Linux:

For portable use, a shared memory object should be identified by a name of the form /somename; that is, a null-terminated string of up to NAME_MAX (i.e., 255) characters consisting of an initial slash, followed by one or more characters, none of which are slashes.

And POSIX:

The name argument conforms to the construction rules for a pathname, except that the interpretation of characters other than the leading character in name is implementation-defined, and that the length limits for the name argument are implementation-defined and need not be the same as the pathname limits {PATH_MAX} and {NAME_MAX}. If name begins with the character, then processes calling shm_open() with the same value of name refer to the same shared memory object, as long as that name has not been removed. If name does not begin with the character, the effect is implementation-defined.